Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] uml: fix unreasonably long udelay

Currently we have a confused udelay implementation.

* __const_udelay does not accept usecs but xloops in i386 and x86_64
* our implementation requires usecs as arg
* it gets a xloops count when called by asm/arch/delay.h

Bugs related to this (extremely long shutdown times) where reported by some
x86_64 users, especially using Device Mapper.

To hit this bug, a compile-time constant time parameter must be passed -
that's why UML seems to work most times. Fix this with a simple udelay
implementation.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Acked-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Paolo 'Blaisorblade' Giarrusso and committed by
Linus Torvalds
10fa1155 05565b65

+14 -25
-11
arch/um/sys-i386/delay.c
··· 27 27 } 28 28 29 29 EXPORT_SYMBOL(__udelay); 30 - 31 - void __const_udelay(unsigned long usecs) 32 - { 33 - int i, n; 34 - 35 - n = (loops_per_jiffy * HZ * usecs) / MILLION; 36 - for(i=0;i<n;i++) 37 - cpu_relax(); 38 - } 39 - 40 - EXPORT_SYMBOL(__const_udelay);
-11
arch/um/sys-x86_64/delay.c
··· 28 28 } 29 29 30 30 EXPORT_SYMBOL(__udelay); 31 - 32 - void __const_udelay(unsigned long usecs) 33 - { 34 - unsigned long i, n; 35 - 36 - n = (loops_per_jiffy * HZ * usecs) / MILLION; 37 - for(i=0;i<n;i++) 38 - cpu_relax(); 39 - } 40 - 41 - EXPORT_SYMBOL(__const_udelay);
+14 -3
include/asm-um/delay.h
··· 1 1 #ifndef __UM_DELAY_H 2 2 #define __UM_DELAY_H 3 3 4 - #include "asm/arch/delay.h" 5 - #include "asm/archparam.h" 6 - 7 4 #define MILLION 1000000 5 + 6 + /* Undefined on purpose */ 7 + extern void __bad_udelay(void); 8 + 9 + extern void __udelay(unsigned long usecs); 10 + extern void __delay(unsigned long loops); 11 + 12 + #define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \ 13 + __bad_udelay() : __udelay(n)) 14 + 15 + /* It appears that ndelay is not used at all for UML, and has never been 16 + * implemented. */ 17 + extern void __unimplemented_ndelay(void); 18 + #define ndelay(n) __unimplemented_ndelay() 8 19 9 20 #endif