Re: bogo-bogomips

From: Andrew Morton (morton@nortelnetworks.com)
Date: Sat Mar 18 2000 - 10:06:44 EST


Time for a little audit.

loops_per_sec isn't actually used a lot - there's more code in the tree
to calculate and report than there is that actually uses it. Whatever.

The value of loops_per_sec is meaningless outside the context of a call
to __delay(). Unfortunately a lot of drivers either:

1: Assume a time relationship between a loop in the driver and the loop
in __delay() by doing something like:

        for (i = 0; i < loops_per_sec / something; i++)
                driver_stuff();

or
2: Assume that the implementation of __delay() will never change and
that all CPUs run at the same speed by calling:

        __delay(MAGIC_CONSTANT);

drivers/block/acsi.c is fragile:

                long tries = loops_per_sec / HZ / 8 * timeout;
                while( --tries >= 0 )
                        if (!(mfp.par_dt_reg & 0x20)) return( 1 );

Assumes that there's an 8:1 ratio between this loop and the __delay()
loop. This is for Atari - should be OK.

drivers/net/appletalk/ltpc.c:

        for(i=0;i<20000;i++) {
                if ( c != inb_p(dev->base_addr+6) ) return 0;
                for(timeout=loops_per_sec/1000; timeout > 0; timeout--)
;

Not sure what arch this is for, but it's fragile and dependent upon CPU
speed.

drivers/scsi/eata_dma.c:

    while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY)
        if (--loop == 0) {
            printk("eata_reset: exit, timeout error.\n");
            restore_flags(flags);
            DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
            return (SCSI_RESET_ERROR);
        }

This will now take twice as long to time out. Dependent upon CPU speed.

drivers/sound/wavfront.c:

        for (i = 0; i < short_loop_cnt; i++) {
                if (wavefront_status() & mask) {
                        return 1;
                }
        }

The only one which caters for differently clocked SMP CPUs. Doubled in
2.3.99. Dependent upon CPU speed.

arch/alpha/kernel/time.c:

    __delay(1000000);
 
Presumably safe for now, but should use loops_per_sec. Dependent on CPU
speed.

arch/ppc/xmon/xmon.c

        __delay(200);

Ditto.

drivers/video/atyfb.c:

        __delay(2000);

Halved. Dependent upon CPU speed.

drivers/video/platinumfb.c:

        __delay(5000);
        __delay(2000);

Halved. Dependent...

drivers/video/valkyriefb.c:

    __delay(20000);

Halved. Dependent...

I suggest the way to restore determinism to all of this is to unexport
loops_per_sec and __delay(), then to reimplement everything with
udelay() (and, perhaps, ndelay()).

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:24 EST