aboutsummaryrefslogtreecommitdiffstats
path: root/patches
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-02-07 02:16:56 +0000
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-02-07 02:16:56 +0000
commita38c7c1575e655ccdee168a265058a41ae13b548 (patch)
treed63845610942d76e677e4d2a6968263dc5e26c9c /patches
parent326d80a41220644cbaa82b25058437dff32c4e44 (diff)
downloadxen-a38c7c1575e655ccdee168a265058a41ae13b548.tar.gz
xen-a38c7c1575e655ccdee168a265058a41ae13b548.tar.bz2
xen-a38c7c1575e655ccdee168a265058a41ae13b548.zip
linux: Fix softlockup interaction with noidlehz.
next_timer_interrupt() must check for when timer ISR is due to wake up the softlockup thread. Signed-off-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'patches')
-rw-r--r--patches/linux-2.6.18/series1
-rw-r--r--patches/linux-2.6.18/softlockup-no-idle-hz.patch56
2 files changed, 57 insertions, 0 deletions
diff --git a/patches/linux-2.6.18/series b/patches/linux-2.6.18/series
index 62b3e0e0d7..85bbae63e4 100644
--- a/patches/linux-2.6.18/series
+++ b/patches/linux-2.6.18/series
@@ -18,3 +18,4 @@ git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch
x86-elfnote-as-preprocessor-macro.patch
fixaddr-top.patch
git-c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4.patch
+softlockup-no-idle-hz.patch
diff --git a/patches/linux-2.6.18/softlockup-no-idle-hz.patch b/patches/linux-2.6.18/softlockup-no-idle-hz.patch
new file mode 100644
index 0000000000..6799bfc4bf
--- /dev/null
+++ b/patches/linux-2.6.18/softlockup-no-idle-hz.patch
@@ -0,0 +1,56 @@
+diff -pruN ../orig-linux-2.6.18/include/linux/sched.h ./include/linux/sched.h
+--- ../orig-linux-2.6.18/include/linux/sched.h 2006-09-20 04:42:06.000000000 +0100
++++ ./include/linux/sched.h 2007-02-07 01:10:24.000000000 +0000
+@@ -211,10 +211,15 @@ extern void update_process_times(int use
+ extern void scheduler_tick(void);
+
+ #ifdef CONFIG_DETECT_SOFTLOCKUP
++extern unsigned long softlockup_get_next_event(void);
+ extern void softlockup_tick(void);
+ extern void spawn_softlockup_task(void);
+ extern void touch_softlockup_watchdog(void);
+ #else
++static inline unsigned long softlockup_get_next_event(void)
++{
++ return MAX_JIFFY_OFFSET;
++}
+ static inline void softlockup_tick(void)
+ {
+ }
+diff -pruN ../orig-linux-2.6.18/kernel/softlockup.c ./kernel/softlockup.c
+--- ../orig-linux-2.6.18/kernel/softlockup.c 2006-09-20 04:42:06.000000000 +0100
++++ ./kernel/softlockup.c 2007-02-07 01:53:22.000000000 +0000
+@@ -40,6 +40,19 @@ void touch_softlockup_watchdog(void)
+ }
+ EXPORT_SYMBOL(touch_softlockup_watchdog);
+
++unsigned long softlockup_get_next_event(void)
++{
++ int this_cpu = smp_processor_id();
++ unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
++
++ if (per_cpu(print_timestamp, this_cpu) == touch_timestamp ||
++ did_panic ||
++ !per_cpu(watchdog_task, this_cpu))
++ return MAX_JIFFY_OFFSET;
++
++ return min_t(long, 0, touch_timestamp + HZ - jiffies);
++}
++
+ /*
+ * This callback runs from the timer interrupt, and checks
+ * whether the watchdog thread has hung or not:
+diff -pruN ../orig-linux-2.6.18/kernel/timer.c ./kernel/timer.c
+--- ../orig-linux-2.6.18/kernel/timer.c 2006-09-20 04:42:06.000000000 +0100
++++ ./kernel/timer.c 2007-02-07 01:29:34.000000000 +0000
+@@ -485,7 +485,9 @@ unsigned long next_timer_interrupt(void)
+ if (hr_expires < 3)
+ return hr_expires + jiffies;
+ }
+- hr_expires += jiffies;
++ hr_expires = min_t(unsigned long,
++ softlockup_get_next_event(),
++ hr_expires) + jiffies;
+
+ base = __get_cpu_var(tvec_bases);
+ spin_lock(&base->lock);