diff -Naur linux-2.6.13/drivers/block/ll_rw_blk.c linux-2.6.13-diskstat/drivers/block/ll_rw_blk.c --- linux-2.6.13/drivers/block/ll_rw_blk.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-diskstat/drivers/block/ll_rw_blk.c 2005-10-03 16:05:14.000000000 +0200 @@ -29,6 +29,7 @@ #include #include #include +#include /* * for max sense size @@ -2297,6 +2298,20 @@ disk_round_stats(rq->rq_disk); rq->rq_disk->in_flight++; } +#ifdef CONFIG_VSERVER_DISKSTAT + struct vx_info *current_vx_info = lookup_vx_info(rq->xid); + if (current_vx_info) { + if (rw == READ) { + cvirt_acct_add(current_vx_info, read_sectors, nr_sectors); + if (!new_io) + cvirt_acct_add(current_vx_info, read_merges, 1); + } else if (rw == WRITE) { + cvirt_acct_add(current_vx_info, write_sectors, nr_sectors); + if (!new_io) + cvirt_acct_add(current_vx_info, write_merges, 1); + } + } +#endif } /* @@ -2659,6 +2674,9 @@ req->ioprio = prio; req->rq_disk = bio->bi_bdev->bd_disk; req->start_time = jiffies; +#ifdef CONFIG_VSERVER_DISKSTAT + req->xid = bio_page(bio)->xid; +#endif spin_lock_irq(q->queue_lock); if (elv_queue_empty(q)) @@ -3175,6 +3193,23 @@ } disk_round_stats(disk); disk->in_flight--; +#ifdef CONFIG_VSERVER_DISKSTAT + if (req->xid) { + struct vx_info *current_vx_info = lookup_vx_info(req->xid); + if (current_vx_info) { + switch (rq_data_dir(req)) { + case WRITE: + cvirt_acct_add(current_vx_info, writes, 1); + cvirt_acct_add(current_vx_info, write_ticks, duration); + break; + case READ: + cvirt_acct_add(current_vx_info, reads, 1); + cvirt_acct_add(current_vx_info, read_ticks, duration); + break; + } + } + } +#endif } if (req->end_io) req->end_io(req); diff -Naur linux-2.6.13/include/linux/blkdev.h linux-2.6.13-diskstat/include/linux/blkdev.h --- linux-2.6.13/include/linux/blkdev.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-diskstat/include/linux/blkdev.h 2005-10-03 16:05:55.000000000 +0200 @@ -195,6 +195,10 @@ */ rq_end_io_fn *end_io; void *end_io_data; + +#ifdef CONFIG_VSERVER_DISKSTAT + xid_t xid; +#endif }; /* diff -Naur linux-2.6.13/include/linux/mm.h linux-2.6.13-diskstat/include/linux/mm.h --- linux-2.6.13/include/linux/mm.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-diskstat/include/linux/mm.h 2005-10-03 16:04:43.000000000 +0200 @@ -257,6 +257,9 @@ void *virtual; /* Kernel virtual address (NULL if not kmapped, ie. highmem) */ #endif /* WANT_PAGE_VIRTUAL */ +#ifdef CONFIG_VSERVER_DISKSTAT + xid_t xid; +#endif }; /* diff -Naur linux-2.6.13/include/linux/vserver/cvirt_def.h linux-2.6.13-diskstat/include/linux/vserver/cvirt_def.h --- linux-2.6.13/include/linux/vserver/cvirt_def.h 2005-10-03 15:37:32.000000000 +0200 +++ linux-2.6.13-diskstat/include/linux/vserver/cvirt_def.h 2005-10-03 16:04:43.000000000 +0200 @@ -9,6 +9,14 @@ #include +struct _vx_disk_stats { + unsigned read_sectors, write_sectors; + unsigned reads, writes; + unsigned read_merges, write_merges; + unsigned read_ticks, write_ticks; + unsigned in_flight; +}; + struct _vx_usage_stat { uint64_t user; uint64_t nice; @@ -56,6 +64,10 @@ atomic_t total_forks; /* number of forks so far */ +#ifdef CONFIG_VSERVER_DISKSTAT + struct _vx_disk_stats dkstats[NR_CPUS]; +#endif + struct _vx_usage_stat cpustat[NR_CPUS]; struct _vx_syslog syslog; diff -Naur linux-2.6.13/include/linux/vserver/cvirt_diskstat.h linux-2.6.13-diskstat/include/linux/vserver/cvirt_diskstat.h --- linux-2.6.13/include/linux/vserver/cvirt_diskstat.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.13-diskstat/include/linux/vserver/cvirt_diskstat.h 2005-10-03 16:04:43.000000000 +0200 @@ -0,0 +1,30 @@ +#ifndef __LINUX_CVIRT_DISKSTAT_H +#define __LINUX_CVIRT_DISKSTAT_H + +#ifdef CONFIG_VSERVER_DISKSTAT +#define cvirt_acct_add(VXINFO,FIELD,STEP) \ +do { \ + if (VXINFO) \ + VXINFO->cvirt.dkstats[smp_processor_id()].FIELD += STEP; \ +} while (0) + +#define cvirt_vfs_stat_read(CVIRT,field) \ +({ \ + typeof(CVIRT->dkstats[0].field) res = 0; \ + int i; \ + for (i=0; i < NR_CPUS; i++) { \ + if (!cpu_possible(i)) \ + continue; \ + res += CVIRT->dkstats[i].field; \ + } \ + res; \ +}) + +#else + +#define cvirt_acct_add(VXINFO,FIELD,STEP) +#define cvirt_vfs_stat_read(CVIRT,field) (0) + +#endif + +#endif diff -Naur linux-2.6.13/kernel/vserver/cvirt_proc.h linux-2.6.13-diskstat/kernel/vserver/cvirt_proc.h --- linux-2.6.13/kernel/vserver/cvirt_proc.h 2005-10-03 15:37:32.000000000 +0200 +++ linux-2.6.13-diskstat/kernel/vserver/cvirt_proc.h 2005-10-03 16:04:43.000000000 +0200 @@ -3,6 +3,7 @@ #include +#include #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) @@ -52,6 +53,24 @@ ,LOAD_INT(c), LOAD_FRAC(c) ,atomic_read(&cvirt->total_forks) ); +#ifdef CONFIG_VSERVER_DISKSTAT + length += sprintf(buffer + length, + "reads:\t%u\n" + "read_sectors:\t%u\n" + "read_ticks:\t%u\n" + "writes:\t%u\n" + "write_sectors:\t%u\n" + "write_ticks:\t%u\n" + "in_flight:\t%u\n" + ,cvirt_vfs_stat_read(cvirt, reads) + ,cvirt_vfs_stat_read(cvirt, read_sectors) + ,jiffies_to_msecs(cvirt_vfs_stat_read(cvirt, read_ticks)) + ,cvirt_vfs_stat_read(cvirt, writes) + ,cvirt_vfs_stat_read(cvirt, write_sectors) + ,jiffies_to_msecs(cvirt_vfs_stat_read(cvirt, write_ticks)) + ,cvirt_vfs_stat_read(cvirt, in_flight) + ); +#endif return length; } diff -Naur linux-2.6.13/kernel/vserver/Kconfig linux-2.6.13-diskstat/kernel/vserver/Kconfig --- linux-2.6.13/kernel/vserver/Kconfig 2005-10-03 15:37:32.000000000 +0200 +++ linux-2.6.13-diskstat/kernel/vserver/Kconfig 2005-10-03 16:04:43.000000000 +0200 @@ -185,5 +185,12 @@ This allows you to specify the number of entries in the per-CPU history buffer. +config VSERVER_DISKSTAT + bool "VServer Disk Usage Statistics" + default n + help + Enables per-vserver disk usage statistics in + /proc/virtual//cvirt + endmenu diff -Naur linux-2.6.13/mm/page_alloc.c linux-2.6.13-diskstat/mm/page_alloc.c --- linux-2.6.13/mm/page_alloc.c 2005-10-03 15:37:32.000000000 +0200 +++ linux-2.6.13-diskstat/mm/page_alloc.c 2005-10-03 16:04:43.000000000 +0200 @@ -965,6 +965,9 @@ return NULL; got_pg: zone_statistics(zonelist, z); +#ifdef CONFIG_VSERVER_DISKSTAT + page->xid = current->xid; +#endif return page; }