Messages in this thread | | | Date | Sun, 19 Mar 2000 02:06:44 +1100 | From | "Andrew Morton" <> | Subject | Re: bogo-bogomips |
| |
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/
| |