From: Arjan van de Ven <arjanv@redhat.com>

Calling mdelay() from hardirq handlers is a very very nasty thing to do;
for one it destroys our irq latency story but it also potentially does foul
things to timekeeping now that HZ=1000.  Patch below makes mdelay() warn
(once per caller) if it's called from irq context.  It removes the
"optimisation" for constant mdelay but I don't think anyone cares about
saving 2 cpu cycles in calling mdelay really.


---

 25-akpm/include/linux/delay.h |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff -puN include/linux/delay.h~warn-on-mdelay-in-irq-handlers include/linux/delay.h
--- 25/include/linux/delay.h~warn-on-mdelay-in-irq-handlers	Wed Mar 24 14:03:01 2004
+++ 25-akpm/include/linux/delay.h	Wed Mar 24 14:03:01 2004
@@ -10,7 +10,7 @@
 extern unsigned long loops_per_jiffy;
 
 #include <asm/delay.h>
-
+#include <asm/hardirq.h>
 /*
  * Using udelay() for intervals greater than a few milliseconds can
  * risk overflow for high loops_per_jiffy (high bogomips) machines. The
@@ -25,14 +25,13 @@ extern unsigned long loops_per_jiffy;
 #define MAX_UDELAY_MS	5
 #endif
 
-#ifdef notdef
-#define mdelay(n) (\
-	{unsigned long __ms=(n); while (__ms--) udelay(1000);})
-#else
-#define mdelay(n) (\
-	(__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
-	({unsigned long __ms=(n); while (__ms--) udelay(1000);}))
-#endif
+#define mdelay(n) (					\
+	{						\
+		static int warned=0; 			\
+		unsigned long __ms=(n); 		\
+		WARN_ON(in_irq() && !(warned++)); 	\
+		while (__ms--) udelay(1000);		\
+	})
 
 #ifndef ndelay
 #define ndelay(x)	udelay(((x)+999)/1000)

_