possible overflow in __udelay

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Current __udelay implementation will cause internal overflow on the
first multiplication.

Basically, the multiplication is:

X = usecs * 2**64 / (100000 / HZ)

And maximum input usecs value is 5000 (MAX_UDELAY_MS * 1000).

If usecs == 5000 and HZ == 1000, X is 5 * 2**64.  Of course this can
not be held in 64bit variable.

How should we avoid the overflow?


1. Use smaller HZ.

HZ < 200 should be OK.


2. Use smaller MAX_UDELAY_MS.

The arch specific delay.h can provide its own MAX_UDELAY_MS.
MAX_UDELAY_MS == 1 should be OK.


3. Use smaller multiplier.

This example should be OK (but lose some precision on larger HZ)

#if HZ < (1000 / MAX_UDELAY_MS)
	usecs *= (0x8000000000000000UL / (500000 / HZ));
#elif HZ < ((1000 / MAX_UDELAY_MS) << 1)
	usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 1;
	lpj <<= 1
#elif HZ < ((1000 / MAX_UDELAY_MS) << 2)
	usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 2;
	lpj <<= 2
#else
	usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 3;
	lpj <<= 3
#endif


Any idea?

---
Atsushi Nemoto


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux