public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Rework of /proc/stat
@ 2002-03-06 17:16 Jean-Eric Cuendet
  2002-03-06 17:25 ` Russell King
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Jean-Eric Cuendet @ 2002-03-06 17:16 UTC (permalink / raw)
  To: Jean-Eric Cuendet, linux-kernel


Hi,
I've made a new version of IO statistics in kstat that remove the
previous limitations of MAX_MAJOR
I've made tests on my machine.
Could someone test it, please?
Feedback welcome.
Bye
-jec

--- /tmp/linux-2.4.18-vanilla/include/linux/kernel_stat.h	Thu Nov 22 20:46:19 2001
+++ /toc/linux-2.4.18-reempt/include/linux/kernel_stat.h	Wed Mar  6 18:02:57 2002
@@ -12,18 +12,37 @@
   * used by rstatd/perfmeter
   */

-#define DK_MAX_MAJOR 16
-#define DK_MAX_DISK 16
+#define DK_MAX_DEVICES 64
+#define DK_BUCKETS 256
+
+
+struct _kstat_block_io
+{
+    struct _kstat_block_io* next;
+
+ 
unsigned int major;
+    unsigned int minor;
+
+ 
unsigned int io;
+    unsigned int rio;
+    unsigned int wio;
+    unsigned int rblk;
+    unsigned int wblk;
+};
+typedef struct _kstat_block_io kstat_block_io;
+
+
+/* static array of IO stats */
+extern unsigned int kstat_devices_current_index;
+extern kstat_block_io kstat_devices_array[DK_MAX_DEVICES];
+
+

  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];
+    kstat_block_io* io_stat_tbl[DK_BUCKETS];
  	unsigned int pgpgin, pgpgout;
  	unsigned int pswpin, pswpout;
  #if !defined(CONFIG_ARCH_S390)
@@ -37,6 +56,103 @@

  extern struct kernel_stat kstat;

+
+
+/* Size of the table */
+extern const unsigned int kstat_block_io_tbl_size;
+
+/* hash function */
+static inline unsigned kstat_block_io_hash(unsigned int major, unsigned 
int minor)
+{
+       return major * 1999 ^ minor;
+}
+
+
+/* add an IO stat */
+static inline kstat_block_io* kstat_block_io_add(unsigned int major, 
unsigned int minor)
+{
+    unsigned int i;
+ 
kstat_block_io* p;
+    kstat_block_io* pstat;
+
+ 
if (kstat_devices_current_index >= DK_MAX_DEVICES)
+ 
{
+ 
     printk("ERROR: kstat: No more slot for device IO stats. Try 
extending DK_MAX_DEVICES\n");
+ 
     return 0;
+ 
}
+
+    pstat = &kstat_devices_array[kstat_devices_current_index];
+ 
kstat_devices_current_index++;
+    pstat->next = 0;
+    pstat->major = major;
+    pstat->minor = minor;
+    pstat->io = 0;
+    pstat->rio = 0;
+    pstat->wio = 0;
+    pstat->rblk = 0;
+    pstat->wblk = 0;
+
+    i = kstat_block_io_hash(major, minor) % kstat_block_io_tbl_size;
+    p = kstat.io_stat_tbl[i];
+ 
if (p == 0)
+ 
{
+ 
     kstat.io_stat_tbl[i] = pstat;
+ 
}
+ 
else
+ 
{
+ 
     printk("WARNING: kstat: Collision found in IO stat accounting table 
(add). Try extending DK_BUCKETS\n");
+        while (p->next != 0)
+ 
	{
+            p = p->next;
+ 
	}
+ 
     p->next = pstat;
+ 
}
+ 
return pstat;
+}
+
+/* lookup an IO stat */
+static inline kstat_block_io* kstat_block_io_lookup(unsigned major, 
unsigned minor)
+{
+ 
unsigned int i = kstat_block_io_hash(major, minor) % 
kstat_block_io_tbl_size;
+ 
kstat_block_io* p = kstat.io_stat_tbl[i];
+ 
while (p && p->major != major && p->minor != minor)
+ 
{
+ 
     printk("WARNING: kstat: Collision found in IO stat accounting table 
(lookup). Try extending DK_BUCKETS\n");
+ 
	p = p->next;
+ 
}
+ 
if (p == 0)
+ 
{
+ 
     p = kstat_block_io_add(major, minor);
+ 
	if (p == 0)
+ 
	{
+ 
	    return 0;
+ 
	}
+ 
}
+ 
return p;
+}
+
+/* This is used by MD to see if IDLE */
+static inline unsigned long kstat_get_rwblk(unsigned int major, 
unsigned int minor)
+{
+    kstat_block_io* stat = kstat_block_io_lookup(major, minor);
+    if (stat == 0)
+ 
{
+ 
     printk("ERROR: kstat: No IO stat found for (%d/%d)\n", major, minor);
+        return 0;
+ 
}
+    return stat->rblk + stat->wblk;
+}
+
+
+
+
+
+
+
+
+
+
+
  #if !defined(CONFIG_ARCH_S390)
  /*
   * Number of interrupts per specific IRQ source, since bootup
--- /tmp/linux-2.4.18-vanilla/drivers/md/md.c	Mon Feb 25 20:37:58 2002
+++ /toc/linux-2.4.18-reempt/drivers/md/md.c	Wed Mar  6 16:46:56 2002
@@ -3284,6 +3284,9 @@
  	return NULL;
  }

+/* MD devices are major=9 and minor=1-31 */
+#define DK_MAX_MAJOR 16
+#define DK_MAX_DISK 32
  static unsigned int sync_io[DK_MAX_MAJOR][DK_MAX_DISK];
  void md_sync_acct(kdev_t dev, unsigned long nr_sectors)
  {
@@ -3305,15 +3308,12 @@
  	unsigned long curr_events;

  	idle = 1;
- 
ITERATE_RDEV(mddev,rdev,tmp) {
+ 
ITERATE_RDEV(mddev,rdev,tmp)
+ 
{
  		int major = MAJOR(rdev->dev);
  		int idx = disk_index(rdev->dev);

- 
	if ((idx >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
- 
		continue;
-
- 
	curr_events = kstat.dk_drive_rblk[major][idx] +
- 
					kstat.dk_drive_wblk[major][idx] ;
+        curr_events = kstat_get_rwblk(major, idx);
  		curr_events -= sync_io[major][idx];
  		if ((curr_events - rdev->last_events) > 32) {
  	 
	rdev->last_events = curr_events;
--- /tmp/linux-2.4.18-vanilla/drivers/block/ll_rw_blk.c	Mon Feb 25 20:37:57 2002
+++ /toc/linux-2.4.18-reempt/drivers/block/ll_rw_blk.c	Wed Mar  6 18:12:03 2002
@@ -501,19 +501,22 @@
  	 
		unsigned long nr_sectors, int new_io)
  {
  	unsigned int major = MAJOR(dev);
- 
unsigned int index;
+ 
unsigned int minor = MINOR(dev);
+    kstat_block_io* stat = kstat_block_io_lookup(major, minor);

- 
index = disk_index(dev);
- 
if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
- 
	return;
+    if (stat == 0)
+    {
+ 
     printk("ERROR: kstat: Haven't found an IO stat struct for major=%d 
/ minor=%d\n", major, minor);
+        return;
+ 
}

- 
kstat.dk_drive[major][index] += new_io;
+ 
stat->io += new_io;
  	if (rw == READ) {
- 
	kstat.dk_drive_rio[major][index] += new_io;
- 
	kstat.dk_drive_rblk[major][index] += nr_sectors;
+ 
	stat->rio += new_io;
+ 
	stat->rblk += nr_sectors;
  	} else if (rw == WRITE) {
- 
	kstat.dk_drive_wio[major][index] += new_io;
- 
	kstat.dk_drive_wblk[major][index] += nr_sectors;
+ 
	stat->wio += new_io;
+ 
	stat->wblk += nr_sectors;
  	} else
  		printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
  }
--- /tmp/linux-2.4.18-vanilla/fs/proc/proc_misc.c	Wed Nov 21 06:29:09 2001
+++ /toc/linux-2.4.18-reempt/fs/proc/proc_misc.c	Wed Mar  6 17:41:28 2002
@@ -282,25 +282,19 @@
  		len += sprintf(page + len, " %u", kstat_irqs(i));
  #endif

- 
len += sprintf(page + len, "\ndisk_io: ");
+    len += sprintf(page + len, "\ndisk_io: ");

- 
for (major = 0; major < DK_MAX_MAJOR; major++) {
- 
	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];
- 
		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]
- 
		);
- 
	}
- 
}
+    for (i = 0; i < kstat_devices_current_index; i++)
+    {
+        kstat_block_io* stat = &kstat_devices_array[i];
+        len += sprintf( page + len, "(%u,%u):(%u,%u,%u,%u,%u) ",
+                        stat->major, stat->minor,
+                        stat->io,
+                        stat->rio,
+                        stat->wio,
+                        stat->rblk,
+                        stat->wblk );
+    }

  	len += sprintf(page + len,

  		"\nctxt %u\n"




^ permalink raw reply	[flat|nested] 20+ messages in thread
* [PATCH] Rework of /proc/stat
@ 2002-03-06 17:43 Jean-Eric Cuendet
  2002-03-06 20:08 ` James Stevenson
  2002-03-06 22:42 ` Alan Cox
  0 siblings, 2 replies; 20+ messages in thread
From: Jean-Eric Cuendet @ 2002-03-06 17:43 UTC (permalink / raw)
  To: Jean-Eric Cuendet, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 220 bytes --]


Hi,
I've made a new version of IO statistics in kstat that remove the
previous limitations of MAX_MAJOR. I've made tests on my machine only, so could someone test it, please?
Feedback welcome.
Bye
-jec

Patch attached.

[-- Attachment #2: proc_stat.patch --]
[-- Type: text/plain, Size: 7074 bytes --]

--- /tmp/linux-2.4.18-vanilla/include/linux/kernel_stat.h	Thu Nov 22 20:46:19 2001
+++ /toc/linux-2.4.18-reempt/include/linux/kernel_stat.h	Wed Mar  6 18:02:57 2002
@@ -12,18 +12,37 @@
  * used by rstatd/perfmeter
  */
 
-#define DK_MAX_MAJOR 16
-#define DK_MAX_DISK 16
+#define DK_MAX_DEVICES 64
+#define DK_BUCKETS 256
+
+
+struct _kstat_block_io
+{
+    struct _kstat_block_io* next;
+
+	unsigned int major;
+    unsigned int minor;
+
+	unsigned int io;
+    unsigned int rio;
+    unsigned int wio;
+    unsigned int rblk;
+    unsigned int wblk;
+};
+typedef struct _kstat_block_io kstat_block_io;
+
+
+/* static array of IO stats */
+extern unsigned int kstat_devices_current_index;
+extern kstat_block_io kstat_devices_array[DK_MAX_DEVICES];
+
+
 
 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];
+    kstat_block_io* io_stat_tbl[DK_BUCKETS];
 	unsigned int pgpgin, pgpgout;
 	unsigned int pswpin, pswpout;
 #if !defined(CONFIG_ARCH_S390)
@@ -37,6 +56,103 @@
 
 extern struct kernel_stat kstat;
 
+
+
+/* Size of the table */
+extern const unsigned int kstat_block_io_tbl_size;
+
+/* hash function */
+static inline unsigned kstat_block_io_hash(unsigned int major, unsigned int minor)
+{
+       return major * 1999 ^ minor;
+}
+
+
+/* add an IO stat */
+static inline kstat_block_io* kstat_block_io_add(unsigned int major, unsigned int minor)
+{
+    unsigned int i;
+	kstat_block_io* p;
+    kstat_block_io* pstat;
+
+	if (kstat_devices_current_index >= DK_MAX_DEVICES)
+	{
+	    printk("ERROR: kstat: No more slot for device IO stats. Try extending DK_MAX_DEVICES\n");
+	    return 0;
+	}
+
+    pstat = &kstat_devices_array[kstat_devices_current_index];
+	kstat_devices_current_index++;
+    pstat->next = 0;
+    pstat->major = major;
+    pstat->minor = minor;
+    pstat->io = 0;
+    pstat->rio = 0;
+    pstat->wio = 0;
+    pstat->rblk = 0;
+    pstat->wblk = 0;
+
+    i = kstat_block_io_hash(major, minor) % kstat_block_io_tbl_size;
+    p = kstat.io_stat_tbl[i];
+	if (p == 0)
+	{
+	    kstat.io_stat_tbl[i] = pstat;
+	}
+	else
+	{
+	    printk("WARNING: kstat: Collision found in IO stat accounting table (add). Try extending DK_BUCKETS\n");
+        while (p->next != 0)
+		{
+            p = p->next;
+		}
+	    p->next = pstat;
+	}
+	return pstat;
+}
+
+/* lookup an IO stat */
+static inline kstat_block_io* kstat_block_io_lookup(unsigned major, unsigned minor)
+{
+	unsigned int i = kstat_block_io_hash(major, minor) % kstat_block_io_tbl_size;
+	kstat_block_io* p = kstat.io_stat_tbl[i];
+	while (p && p->major != major && p->minor != minor)
+	{
+	    printk("WARNING: kstat: Collision found in IO stat accounting table (lookup). Try extending DK_BUCKETS\n");
+		p = p->next;
+	}
+	if (p == 0)
+	{
+	    p = kstat_block_io_add(major, minor);
+		if (p == 0)
+		{
+		    return 0;
+		}
+	}
+	return p;
+}
+
+/* This is used by MD to see if IDLE */
+static inline unsigned long kstat_get_rwblk(unsigned int major, unsigned int minor)
+{
+    kstat_block_io* stat = kstat_block_io_lookup(major, minor);
+    if (stat == 0)
+	{
+	    printk("ERROR: kstat: No IO stat found for (%d/%d)\n", major, minor);
+        return 0;
+	}
+    return stat->rblk + stat->wblk;
+}
+
+
+
+
+
+
+
+
+
+
+
 #if !defined(CONFIG_ARCH_S390)
 /*
  * Number of interrupts per specific IRQ source, since bootup
--- /tmp/linux-2.4.18-vanilla/drivers/md/md.c	Mon Feb 25 20:37:58 2002
+++ /toc/linux-2.4.18-reempt/drivers/md/md.c	Wed Mar  6 16:46:56 2002
@@ -3284,6 +3284,9 @@
 	return NULL;
 }
 
+/* MD devices are major=9 and minor=1-31 */
+#define DK_MAX_MAJOR 16
+#define DK_MAX_DISK 32
 static unsigned int sync_io[DK_MAX_MAJOR][DK_MAX_DISK];
 void md_sync_acct(kdev_t dev, unsigned long nr_sectors)
 {
@@ -3305,15 +3308,12 @@
 	unsigned long curr_events;
 
 	idle = 1;
-	ITERATE_RDEV(mddev,rdev,tmp) {
+	ITERATE_RDEV(mddev,rdev,tmp)
+	{
 		int major = MAJOR(rdev->dev);
 		int idx = disk_index(rdev->dev);
 
-		if ((idx >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
-			continue;
-
-		curr_events = kstat.dk_drive_rblk[major][idx] +
-						kstat.dk_drive_wblk[major][idx] ;
+        curr_events = kstat_get_rwblk(major, idx);
 		curr_events -= sync_io[major][idx];
 		if ((curr_events - rdev->last_events) > 32) {
 			rdev->last_events = curr_events;
--- /tmp/linux-2.4.18-vanilla/drivers/block/ll_rw_blk.c	Mon Feb 25 20:37:57 2002
+++ /toc/linux-2.4.18-reempt/drivers/block/ll_rw_blk.c	Wed Mar  6 18:12:03 2002
@@ -501,19 +501,22 @@
 				unsigned long nr_sectors, int new_io)
 {
 	unsigned int major = MAJOR(dev);
-	unsigned int index;
+	unsigned int minor = MINOR(dev);
+    kstat_block_io* stat = kstat_block_io_lookup(major, minor);
 
-	index = disk_index(dev);
-	if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
-		return;
+    if (stat == 0)
+    {
+	    printk("ERROR: kstat: Haven't found an IO stat struct for major=%d / minor=%d\n", major, minor);
+        return;
+	}
 
-	kstat.dk_drive[major][index] += new_io;
+	stat->io += new_io;
 	if (rw == READ) {
-		kstat.dk_drive_rio[major][index] += new_io;
-		kstat.dk_drive_rblk[major][index] += nr_sectors;
+		stat->rio += new_io;
+		stat->rblk += nr_sectors;
 	} else if (rw == WRITE) {
-		kstat.dk_drive_wio[major][index] += new_io;
-		kstat.dk_drive_wblk[major][index] += nr_sectors;
+		stat->wio += new_io;
+		stat->wblk += nr_sectors;
 	} else
 		printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
 }
--- /tmp/linux-2.4.18-vanilla/fs/proc/proc_misc.c	Wed Nov 21 06:29:09 2001
+++ /toc/linux-2.4.18-reempt/fs/proc/proc_misc.c	Wed Mar  6 17:41:28 2002
@@ -282,25 +282,19 @@
 		len += sprintf(page + len, " %u", kstat_irqs(i));
 #endif
 
-	len += sprintf(page + len, "\ndisk_io: ");
+    len += sprintf(page + len, "\ndisk_io: ");
 
-	for (major = 0; major < DK_MAX_MAJOR; major++) {
-		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];
-			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]
-			);
-		}
-	}
+    for (i = 0; i < kstat_devices_current_index; i++)
+    {
+        kstat_block_io* stat = &kstat_devices_array[i];
+        len += sprintf( page + len, "(%u,%u):(%u,%u,%u,%u,%u) ",
+                        stat->major, stat->minor,
+                        stat->io,
+                        stat->rio,
+                        stat->wio,
+                        stat->rblk,
+                        stat->wblk );
+    }
 
 	len += sprintf(page + len,
 		"\nctxt %u\n"

^ permalink raw reply	[flat|nested] 20+ messages in thread
[parent not found: <E16lBe4-0006ly-00@the-village.bc.nu>]

end of thread, other threads:[~2002-03-13 16:41 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-03-06 17:16 [PATCH] Rework of /proc/stat Jean-Eric Cuendet
2002-03-06 17:25 ` Russell King
2002-03-06 19:48 ` Dominik Kubla
2002-03-07 11:12   ` Jean-Eric Cuendet
2002-03-07  1:07 ` mingming cao
  -- strict thread matches above, loose matches on Subject: below --
2002-03-06 17:43 Jean-Eric Cuendet
2002-03-06 20:08 ` James Stevenson
2002-03-06 22:42 ` Alan Cox
2002-03-07  1:13   ` mingming cao
2002-03-07 11:16     ` Jean-Eric Cuendet
2002-03-07 11:48     ` Christoph Hellwig
2002-03-07 13:50     ` Alan Cox
2002-03-07 13:53       ` Jean-Eric Cuendet
2002-03-07 14:17         ` Alan Cox
2002-03-07 11:11   ` Jean-Eric Cuendet
2002-03-07 11:48     ` Arjan van de Ven
2002-03-07 12:48     ` Alan Cox
2002-03-07 11:40   ` Jean-Eric Cuendet
2002-03-07 12:51     ` Alan Cox
     [not found] <E16lBe4-0006ly-00@the-village.bc.nu>
2002-03-13 16:41 ` Jean-Eric Cuendet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox