On Thursday 26 October 2006 16:12, Julian Bradfield wrote:
> A few years ago, I reported a problem with mdelay (that it basically
> didn't work) - see
>
> http://marc.theaimsgroup.com/?l=user-mode-linux-devel&m=103774842828993&w=2
>
> and preceding messages.
>
> I see the problem is still there in 2.6.18 (I find it because I insert an
> mdelay(1000) into one of the ubd routines to simulate the effect of
> busy-waiting on i/o in one of my practical exercises).
>
> Here's the patch I currently use to fix it. I can't remember now how I
> produced this patch four years ago, but it should make sense in
> conjunction with the above referenced message.
I've not yet looked at that messages, however:
Direct invocations of __const_udelay (see include/asm-i386/delay.h) are still
broken with the below patch IMHO, since you do not multiply the value passed
there by that magic constant - look also at arch/i386/lib/delay.c. Please try
if the attached patch works for you. Also, a number of other users complained
about the same bug (hangs on shutdown result for device-mapper users in some
particular conditions, for instance).
> --- arch/um/sys-i386/delay.c.dist 2006-10-26 14:50:38.069023000 +0100
> +++ arch/um/sys-i386/delay.c 2006-10-26 14:50:42.527846000 +0100
> @@ -3,7 +3,7 @@
> #include <linux/delay.h>
> #include <asm/param.h>
>
> -void __delay(unsigned long time)
> +static void __loop_delay(unsigned long loops)
> {
> /* Stolen from the i386 __loop_delay */
> int d0;
> @@ -14,27 +14,28 @@
> ".align 16\n"
> "2:\tdecl %0\n\tjns 2b"
>
> :"=&a" (d0)
>
> - :"0" (time));
> + :"0" (loops));
> }
>
> -void __udelay(unsigned long usecs)
> +void __delay(unsigned long loops)
> {
> - int i, n;
> -
> - n = (loops_per_jiffy * HZ * usecs) / MILLION;
> - for(i=0;i<n;i++)
> - cpu_relax();
> + __loop_delay(loops);
> }
>
> -EXPORT_SYMBOL(__udelay);
> -
> -void __const_udelay(unsigned long usecs)
> +inline void __const_udelay(unsigned long xloops)
> {
> - int i, n;
> + int d0;
> + __asm__("mull %0"
> + :"=d" (xloops), "=&a" (d0)
> + :"1" (xloops),"0" (loops_per_jiffy));
> + __delay(xloops * HZ);
> +}
>
> - n = (loops_per_jiffy * HZ * usecs) / MILLION;
> - for(i=0;i<n;i++)
> - cpu_relax();
> +void __udelay(unsigned long usecs)
> +{
> + __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
> }
>
> +EXPORT_SYMBOL(__udelay);
> +
> EXPORT_SYMBOL(__const_udelay);
--
Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
Paolo Giarrusso, aka Blaisorblade
http://www.user-mode-linux.org/~blaisorblade
Index: linux-2.6.git/arch/um/sys-i386/delay.c
===================================================================
--- linux-2.6.git.orig/arch/um/sys-i386/delay.c
+++ linux-2.6.git/arch/um/sys-i386/delay.c
@@ -27,14 +27,3 @@ void __udelay(unsigned long usecs)
}
EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
- int i, n;
-
- n = (loops_per_jiffy * HZ * usecs) / MILLION;
- for(i=0;i<n;i++)
- cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
Index: linux-2.6.git/arch/um/sys-x86_64/delay.c
===================================================================
--- linux-2.6.git.orig/arch/um/sys-x86_64/delay.c
+++ linux-2.6.git/arch/um/sys-x86_64/delay.c
@@ -28,14 +28,3 @@ void __udelay(unsigned long usecs)
}
EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
- unsigned long i, n;
-
- n = (loops_per_jiffy * HZ * usecs) / MILLION;
- for(i=0;i<n;i++)
- cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
Index: linux-2.6.git/include/asm-um/delay.h
===================================================================
--- linux-2.6.git.orig/include/asm-um/delay.h
+++ linux-2.6.git/include/asm-um/delay.h
@@ -1,9 +1,20 @@
#ifndef __UM_DELAY_H
#define __UM_DELAY_H
-#include "asm/arch/delay.h"
-#include "asm/archparam.h"
-
#define MILLION 1000000
+/* Undefined on purpose */
+extern void __bad_udelay(void);
+extern void __bad_ndelay(void);
+
+extern void __udelay(unsigned long usecs);
+extern void __const_udelay(unsigned long usecs);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
+ __bad_udelay() : __udelay(n))
+
+/* It appears that ndelay is not used at all for UML. */
+#define ndelay(n) __bad_ndelay()
+
#endif
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel