aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2006-06-15 00:11:22 -0400
committerPaul Mackerras <paulus@samba.org>2006-06-21 01:01:33 -0400
commit1e92a550e80fef01ebcc0bcd0896109cdb986c72 (patch)
tree6cdb7bc6c6ad51644f9b899b2604d26fe7cd540b /include
parentddf5f75a16b3e7460ffee881795aa168dffcd0cf (diff)
[POWERPC] Fix mdelay badness on shared processor partitions
On partitioned PPC64 systems where a partition is given 1/10 of a processor, we have seen mdelay() delaying for 10 times longer than it should. The reason is that the generic mdelay(n) does n delays of 1 millisecond each. However, with 1/10 of a processor, we only get a one-millisecond timeslice every 10ms. Thus each 1 millisecond delay loop ends up taking 10ms elapsed time. The solution is just to use the PPC64 udelay function, which uses the timebase to ensure that the delay is based on elapsed time rather than how much processing time the partition has been given. (Yes, the generic mdelay uses the PPC64 udelay, but the problem is that the start time gets reset every millisecond, and each time it gets reset we lose another 9ms.) Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Paul Mackerras <paulus@samba.org> Acked-by: Andrew Morton <akpm@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-powerpc/delay.h13
-rw-r--r--include/linux/delay.h5
2 files changed, 14 insertions, 4 deletions
diff --git a/include/asm-powerpc/delay.h b/include/asm-powerpc/delay.h
index 057a60955474..f9200a65c632 100644
--- a/include/asm-powerpc/delay.h
+++ b/include/asm-powerpc/delay.h
@@ -17,5 +17,18 @@
17extern void __delay(unsigned long loops); 17extern void __delay(unsigned long loops);
18extern void udelay(unsigned long usecs); 18extern void udelay(unsigned long usecs);
19 19
20/*
21 * On shared processor machines the generic implementation of mdelay can
22 * result in large errors. While each iteration of the loop inside mdelay
23 * is supposed to take 1ms, the hypervisor could sleep our partition for
24 * longer (eg 10ms). With the right timing these errors can add up.
25 *
26 * Since there is no 32bit overflow issue on 64bit kernels, just call
27 * udelay directly.
28 */
29#ifdef CONFIG_PPC64
30#define mdelay(n) udelay((n) * 1000)
31#endif
32
20#endif /* __KERNEL__ */ 33#endif /* __KERNEL__ */
21#endif /* _ASM_POWERPC_DELAY_H */ 34#endif /* _ASM_POWERPC_DELAY_H */
diff --git a/include/linux/delay.h b/include/linux/delay.h
index acb74865b973..17ddb55430ae 100644
--- a/include/linux/delay.h
+++ b/include/linux/delay.h
@@ -25,10 +25,7 @@ extern unsigned long loops_per_jiffy;
25#define MAX_UDELAY_MS 5 25#define MAX_UDELAY_MS 5
26#endif 26#endif
27 27
28#ifdef notdef 28#ifndef mdelay
29#define mdelay(n) (\
30 {unsigned long __ms=(n); while (__ms--) udelay(1000);})
31#else
32#define mdelay(n) (\ 29#define mdelay(n) (\
33 (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \ 30 (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
34 ({unsigned long __ms=(n); while (__ms--) udelay(1000);})) 31 ({unsigned long __ms=(n); while (__ms--) udelay(1000);}))