summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/2.6.22/20010_softlockup-no-idle-hz.patch1')
-rw-r--r--trunk/2.6.22/20010_softlockup-no-idle-hz.patch175
1 files changed, 75 insertions, 0 deletions
diff --git a/trunk/2.6.22/20010_softlockup-no-idle-hz.patch1 b/trunk/2.6.22/20010_softlockup-no-idle-hz.patch1
new file mode 100644
index 0000000..e67c89c
--- /dev/null
+++ b/trunk/2.6.22/20010_softlockup-no-idle-hz.patch1
@@ -0,0 +1,75 @@
+Subject: xen3 softlockup - no-idle-hz interaction fix
+From: http://xenbits.xensource.com/xen-3.1-testing.hg (tip 15042)
+Acked-by: jbeulich@novell.com
+
+Index: head-2007-09-25/include/linux/sched.h
+===================================================================
+--- head-2007-09-25.orig/include/linux/sched.h 2007-09-25 14:22:37.000000000 +0200
++++ head-2007-09-25/include/linux/sched.h 2007-09-25 14:32:18.000000000 +0200
+@@ -236,11 +236,16 @@ 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);
+ extern void touch_all_softlockup_watchdogs(void);
+ #else
++static inline unsigned long softlockup_get_next_event(void)
++{
++ return MAX_JIFFY_OFFSET;
++}
+ static inline void softlockup_tick(void)
+ {
+ }
+Index: head-2007-09-25/kernel/softlockup.c
+===================================================================
+--- head-2007-09-25.orig/kernel/softlockup.c 2007-09-25 14:22:37.000000000 +0200
++++ head-2007-09-25/kernel/softlockup.c 2007-09-25 14:32:18.000000000 +0200
+@@ -60,6 +60,19 @@ void touch_all_softlockup_watchdogs(void
+ }
+ EXPORT_SYMBOL(touch_all_softlockup_watchdogs);
+
++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 max_t(long, 0, touch_timestamp + HZ - jiffies);
++}
++
+ /*
+ * This callback runs from the timer interrupt, and checks
+ * whether the watchdog thread has hung or not:
+Index: head-2007-09-25/kernel/timer.c
+===================================================================
+--- head-2007-09-25.orig/kernel/timer.c 2007-09-25 14:22:37.000000000 +0200
++++ head-2007-09-25/kernel/timer.c 2007-09-25 14:32:18.000000000 +0200
+@@ -781,7 +781,7 @@ static unsigned long cmp_next_hrtimer_ev
+ unsigned long get_next_timer_interrupt(unsigned long now)
+ {
+ tvec_base_t *base = __get_cpu_var(tvec_bases);
+- unsigned long expires;
++ unsigned long expires, sl_next;
+
+ spin_lock(&base->lock);
+ expires = __next_timer_interrupt(base);
+@@ -790,7 +790,11 @@ unsigned long get_next_timer_interrupt(u
+ if (time_before_eq(expires, now))
+ return now;
+
+- return cmp_next_hrtimer_event(now, expires);
++ expires = cmp_next_hrtimer_event(now, expires);
++ sl_next = softlockup_get_next_event();
++
++ return expires <= now || expires - now < sl_next
++ ? expires : now + sl_next;
+ }
+
+ #ifdef CONFIG_NO_IDLE_HZ