Sorry for the delay.  Had to run some errands...

> 2. Shouldn't affect /proc/stats. It has stats on what's actually used.
> On my peecee the floppy gets a mention sometimes.

Actually, it can.  Here's the routine from ll_rw_blk.c that does the
updating of the disk stats:

inline void drive_stat_acct (kdev_t dev, int rw,
                unsigned long nr_sectors, int new_io)
{
    unsigned int major = MAJOR(dev);
    unsigned int index;

    index = disk_index(dev);
    if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
        return;

    kstat.dk_drive[major][index] += new_io;
    if (rw == READ) {
        kstat.dk_drive_rio[major][index] += new_io;
        kstat.dk_drive_rblk[major][index] += nr_sectors;
    } else if (rw == WRITE) {
        kstat.dk_drive_wio[major][index] += new_io;
        kstat.dk_drive_wblk[major][index] += nr_sectors;
    } else
        printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
}

You'll notice the first thing it does is ensures that the device passed to
it is within a couple of limits since it maintains the stats in a two
dimensional array.  The DK_MAX_DISK is the second level limit and the
DK_MAX_MAJOR is the first level limit.  If either of these limits are
exceeded then stats for this call will not be collected.  No big deal right?

Well, here's a snippet from the routine that spits out the stuff when you
look at /proc/stat:

    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)
                proc_sprintf(page, &off, &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]
            );
        }
    }

You'll notice that it sums the dk_drive, dk_drive_rblk, and dk_drive_wblk
values to create a new variable called active.  Active is then used to
determine if stats should be printed or not.  If active is zero they won't
be printed.  So, if no stats are collected because one of the tests in
drive_stat_acct exceeds the table limits, then nothing will be printed.

What are the limits?  The defaults are 16 for both.  When I asked if there
were more than 16 disks involved, I didn't look far enough.

The problem is the DK_MAX_MAJOR test.  Does everyone know the major number
of their DASD devices?  It would be 94, which of course is greather than 16.
This causes the test to fail and no stats to be collected.

So, the solution is simply to change the value of DK_MAX_MAJOR in
linux/include/linux/kernel_stat.h to at least 95 and recompile your kernel.

The reason it works under SuSE is that it got (inadvertently) upped to 99
when they put on the user-mode-linux patch.

Leland

Reply via email to