Skip to contentSkip to conversation

Disk IO statisitics gathering for all disks

PATCH In review Mingming cao 2 participants 3 messages Nov 8, 2001 – Nov 9, 2001

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

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
diff -urN -X dontdiff linux-2.4.13/drivers/block/ll_rw_blk.c /home/ming/linux-13-dk/drivers/block/ll_rw_blk.c
@@ -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
diff -urN -X dontdiff linux-2.4.13/drivers/md/md.c /home/ming/linux-13-dk/drivers/md/md.c
@@ -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
diff -urN -X dontdiff linux-2.4.13/fs/proc/proc_misc.c /home/ming/linux-13-dk/fs/proc/proc_misc.c
@@ -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
diff -urN -X dontdiff linux-2.4.13/include/linux/genhd.h /home/ming/linux-13-dk/include/linux/genhd.h
@@ -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
diff -urN -X dontdiff linux-2.4.13/include/linux/kernel_stat.h /home/ming/linux-13-dk/include/linux/kernel_stat.h
@@ -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)
#1 lore raw
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.
#2 lore raw
In reply to Mingming cao
Quoted 4 lines · Christoph Hellwig

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.

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