Skip to contentSkip to conversation

disable preemption in udelay()

PATCH New [email protected] 1 participant 1 message Dec 14, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 disable preemption in udelay()

The udelay() inline for ia64 uses the ITC. If CONFIG_PREEMPT is enabled and the platform has unsynchronized ITCs and the calling task migrates to another CPU while doing the udelay loop, then the effective delay may be too short or very, very long.

The most simple fix is to disable preemption around the udelay looping. The downside is that inhibits realtime preemption for cases of long udelays. I am reluctant to propose a much more complicated patch (that disables preemption only for "short" delays, and uses the global RTC as the time base for longer, preemptible delays) unless there are valid objections to this more simple fix.

Index: linux/include/asm-ia64/delay.h
=================================--- linux.orig/include/asm-ia64/delay.h 2005-10-27 17:02:08.000000000 -0700
+++ linux/include/asm-ia64/delay.h 2005-12-14 10:30:55.000000000 -0800
@@ -87,11 +87,17 @@
static __inline__ void
udelay (unsigned long usecs)
{
- unsigned long start = ia64_get_itc();
- unsigned long cycles = usecs*local_cpu_data->cyc_per_usec;
+ unsigned long start;
+ unsigned long cycles;
+
+ preempt_disable();
+ cycles = usecs*local_cpu_data->cyc_per_usec;
+ start = ia64_get_itc();

while (ia64_get_itc() - start < cycles)
cpu_relax();
+
+ preempt_enable();
}

#endif /* _ASM_IA64_DELAY_H */