Subject: possible overflow in __udelay

From: Atsushi Nemoto <[email-masked]>
Date: Thu, 01 Jul 2004 21:14:56 +0900 (JST)

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

---

From: Atsushi Nemoto <[email-masked]>
Date: Wed, 07 Jul 2004 23:57:23 +0900 (JST)

>>>>> On Thu, 01 Jul 2004 21:14:56 +0900 (JST), Atsushi Nemoto <[email-masked]> said:

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

anemo> Basically, the multiplication is:

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

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

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

anemo> How should we avoid the overflow?

anemo> ....

Don't you really have any comments?

I believe, for example, mdelay(10) does not work properly on most MIPS
ports (except for DECSTATION and JAZZ which have smaller HZ value).

---
Atsushi Nemoto

---

From: Atsushi Nemoto <[email-masked]>
Date: Thu, 08 Jul 2004 00:12:07 +0900 (JST)

>>>>> On Wed, 07 Jul 2004 23:57:23 +0900 (JST), Atsushi Nemoto <[email-masked]> said:

anemo> I believe, for example, mdelay(10) does not work properly on
anemo> most MIPS ports (except for DECSTATION and JAZZ which have
anemo> smaller HZ value).

Oops, mdelay(10) should work.  But mdelay(5) (mdelay(MAX_UDELAY_MS))
does not work.

---
Atsushi Nemoto