[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>
This commit is contained in:
Paolo 'Blaisorblade' Giarrusso 2007-04-01 23:49:37 -07:00 committed by Linus Torvalds
parent 05565b65a5
commit 10fa1155a2
3 changed files with 14 additions and 25 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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 __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, and has never been
* implemented. */
extern void __unimplemented_ndelay(void);
#define ndelay(n) __unimplemented_ndelay()
#endif