Disk IO statisitics gathering for all disks
Subsystems (4)
PATCH 1/1 Disk IO statisitics gathering for all disks
Hello,
Attached is a patch to dynamically allocate the data buffers for the disk statistics, and to extend the gathering of disk statistics to include major numbers greater than 15.
A disk statistics structure is allocated when a new block device is registered. A global array (kstat.dkdrive_info[]) is used to hold the address of the statistics structures for all block devices. The disk statistics lookup is the same as before: indexed by the major number and the disk number. Note that this patch includes the changes
of function disk_index() in genhd.h from linux-2.4.10-ac kernel, in order to make the disk index lookup work for more disks.
This patch is against 2.4.14 kernel and has been tested. I greatly appreciate any feedback from you. Please take a look and cc you comments to me.
Have a good day.
Signature · 5 lines
Mingming Cao IBM Linux Technology Center 503-578-5024 IBM T/L: 775-5024 [email protected] http://www.ibm.com/linux/ltc
home/ming/linux-13-dk/drivers/block/ll_rw_blk.c renamed from drivers/block/ll_rw_blk.c +14 -8
@@ -501,20 +501,26 @@ {unsigned int major =MAJOR (dev);unsigned int index; +dk_stat_t * ds; + ds = kstat.dk_drive_info[major]; +if (ds ==NULL ) +return ; + index =disk_index (dev); -if ((index >=DK_MAX_DISK ) || (major >=DK_MAX_MAJOR )) +if (index >=DK_MAX_DISK )return ; - - kstat.dk_drive[major][index] += new_io; + + ds += index;if (rw ==READ ) { - kstat.dk_drive_rio[major][index] += new_io; - kstat.dk_drive_rblk[major][index] += nr_sectors; + ds->dk_drive_rio += new_io; + ds->dk_drive_rblk += nr_sectors; }else if (rw ==WRITE ) { - kstat.dk_drive_wio[major][index] += new_io; - kstat.dk_drive_wblk[major][index] += nr_sectors; - }else + ds->dk_drive_wio += new_io; + ds->dk_drive_wblk += nr_sectors; + }else {printk (KERN_ERR "drive_stat_acct: cmd not R/W?\n" ); + } }/*
home/ming/linux-13-dk/drivers/md/md.c renamed from drivers/md/md.c +5 -2
@@ -3301,12 +3301,15 @@ ITERATE_RDEV(mddev,rdev,tmp) {int major =MAJOR (rdev->dev);int idx =disk_index (rdev->dev); +dk_stat_t * ds;if ((idx >=DK_MAX_DISK ) || (major >=DK_MAX_MAJOR ))continue ; - curr_events = kstat.dk_drive_rblk[major][idx] + - kstat.dk_drive_wblk[major][idx] ; +if ((ds = kstat.dk_drive_info[major]) ==NULL ) +continue ; + ds += idx; + curr_events = ds->dk_drive_rblk + ds->dk_drive_wblk; curr_events -= sync_io[major][idx];if ((curr_events - rdev->last_events) >32 ) { rdev->last_events = curr_events;
home/ming/linux-13-dk/fs/block_dev.c renamed from fs/block_dev.c +50 -0
81 lines not on this page · raw message
home/ming/linux-13-dk/fs/proc/proc_misc.c renamed from fs/proc/proc_misc.c +15 -10
@@ -309,21 +309,26 @@ len +=sprintf (page + len,"\ndisk_io: " ); -for (major =0 ; major <DK_MAX_MAJOR ; major++) { +for (major =0 ; major <MAX_BLKDEV ; major++) { +if ( kstat.dk_drive_info[major] ==NULL ) +continue ;for (disk =0 ; disk <DK_MAX_DISK ; disk++) { -int active = kstat.dk_drive[major][disk] + - kstat.dk_drive_rblk[major][disk] + - kstat.dk_drive_wblk[major][disk]; +dk_stat_t * ds; +int active; + + ds = kstat.dk_drive_info[major] + disk; + active = ds->dk_drive_rio + ds->dk_drive_wio + + ds->dk_drive_rblk + ds->dk_drive_wblk;if (active) len +=sprintf (page + len,"(%u,%u):(%u,%u,%u,%u,%u) " , major, disk, - kstat.dk_drive[major][disk], - kstat.dk_drive_rio[major][disk], - kstat.dk_drive_rblk[major][disk], - kstat.dk_drive_wio[major][disk], - kstat.dk_drive_wblk[major][disk] - ); + ds->dk_drive_rio + ds->dk_drive_wio, + ds->dk_drive_rio, + ds->dk_drive_rblk, + ds->dk_drive_wio, + ds->dk_drive_wblk + ); } }
home/ming/linux-13-dk/include/linux/genhd.h renamed from include/linux/genhd.h +15 -6
@@ -256,21 +256,30 @@unsigned int index;switch (major) { -case DAC960_MAJOR +0 : - index = (minor &0x00f8 ) >>3 ; -break ;case SCSI_DISK0_MAJOR : index = (minor &0x00f0 ) >>4 ;break ;case IDE0_MAJOR :/* same as HD_MAJOR */ case XT_DISK_MAJOR : +case IDE1_MAJOR : +case IDE2_MAJOR : +case IDE3_MAJOR : +case IDE4_MAJOR : +case IDE5_MAJOR : index = (minor &0x0040 ) >>6 ;break ; -case IDE1_MAJOR : - index = ((minor &0x0040 ) >>6 ) +2 ; +case SCSI_CDROM_MAJOR : + index = minor &0x000f ;break ;default : -return 0 ; +if (major >=SCSI_DISK1_MAJOR && major <=SCSI_DISK7_MAJOR ) + index = (minor &0x00f0 ) >>4 ; +else if (major >=DAC960_MAJOR && major <=DAC960_MAJOR +7 ) + index = (minor &0x00f8 ) >>3 ; +else if (major >=IDE6_MAJOR && major <=IDE9_MAJOR ) + index = (minor &0x0040 ) >>6 ; +else +return 0 ; }return index; }
home/ming/linux-13-dk/include/linux/kernel_stat.h renamed from include/linux/kernel_stat.h +9 -5
@@ -15,15 +15,19 @@#define DK_MAX_MAJOR 16#define DK_MAX_DISK 16 +struct dk_stat { +unsigned int dk_drive_rio; +unsigned int dk_drive_wio; +unsigned int dk_drive_rblk; +unsigned int dk_drive_wblk; +}; + +typedef struct dk_stat dk_stat_t ;struct kernel_stat {unsigned int per_cpu_user[NR_CPUS ], per_cpu_nice[NR_CPUS ], per_cpu_system[NR_CPUS ]; -unsigned int dk_drive[DK_MAX_MAJOR ][DK_MAX_DISK ]; -unsigned int dk_drive_rio[DK_MAX_MAJOR ][DK_MAX_DISK ]; -unsigned int dk_drive_wio[DK_MAX_MAJOR ][DK_MAX_DISK ]; -unsigned int dk_drive_rblk[DK_MAX_MAJOR ][DK_MAX_DISK ]; -unsigned int dk_drive_wblk[DK_MAX_MAJOR ][DK_MAX_DISK ]; +dk_stat_t *dk_drive_info[MAX_BLKDEV ];unsigned int pgpgin, pgpgout;unsigned int pswpin, pswpout;#if !defined(CONFIG_ARCH_S390 )
Quoted 11 lines · Mingming cao
Hello,
Attached is a patch to dynamically allocate the data buffers for the disk statistics, and to extend the gathering of disk statistics to include major numbers greater than 15.
A disk statistics structure is allocated when a new block device is registered. A global array (kstat.dkdrive_info[]) is used to hold the address of the statistics structures for all block devices. The disk statistics lookup is the same as before: indexed by the major number and the disk number.
A very minor nitpick: please use struct dk_stat (or disk_stat) instead of dk_stat_t - it is by no means an opaque type.
Christoph
Signature · 1 line
Of course it doesn't work. We've performed a software upgrade.
Quoted 4 lines · Christoph Hellwig
A very minor nitpick: please use struct
dk_stat(ordisk_stat) instead ofdk_stat_t- it is by no means an opaque type.
You are right. Thank you for pointing it out.
Signature · 5 lines
Mingming Cao IBM Linux Technology Center 503-578-5024 IBM T/L: 775-5024 [email protected] http://www.ibm.com/linux/ltc