ia64/xen-unstable

changeset 13862:1a411820230b

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>
author kfraser@localhost.localdomain
date Wed Feb 07 02:16:56 2007 +0000 (2007-02-07)
parents f28b144fb5cd
children 67faf6c59bfa
files patches/linux-2.6.18/series patches/linux-2.6.18/softlockup-no-idle-hz.patch
line diff
     1.1 --- a/patches/linux-2.6.18/series	Wed Feb 07 00:51:26 2007 +0000
     1.2 +++ b/patches/linux-2.6.18/series	Wed Feb 07 02:16:56 2007 +0000
     1.3 @@ -18,3 +18,4 @@ git-dbaab49f92ff6ae6255762a948375e4036cb
     1.4  x86-elfnote-as-preprocessor-macro.patch
     1.5  fixaddr-top.patch
     1.6  git-c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4.patch
     1.7 +softlockup-no-idle-hz.patch
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/patches/linux-2.6.18/softlockup-no-idle-hz.patch	Wed Feb 07 02:16:56 2007 +0000
     2.3 @@ -0,0 +1,56 @@
     2.4 +diff -pruN ../orig-linux-2.6.18/include/linux/sched.h ./include/linux/sched.h
     2.5 +--- ../orig-linux-2.6.18/include/linux/sched.h	2006-09-20 04:42:06.000000000 +0100
     2.6 ++++ ./include/linux/sched.h	2007-02-07 01:10:24.000000000 +0000
     2.7 +@@ -211,10 +211,15 @@ extern void update_process_times(int use
     2.8 + extern void scheduler_tick(void);
     2.9 + 
    2.10 + #ifdef CONFIG_DETECT_SOFTLOCKUP
    2.11 ++extern unsigned long softlockup_get_next_event(void);
    2.12 + extern void softlockup_tick(void);
    2.13 + extern void spawn_softlockup_task(void);
    2.14 + extern void touch_softlockup_watchdog(void);
    2.15 + #else
    2.16 ++static inline unsigned long softlockup_get_next_event(void)
    2.17 ++{
    2.18 ++	return MAX_JIFFY_OFFSET;
    2.19 ++}
    2.20 + static inline void softlockup_tick(void)
    2.21 + {
    2.22 + }
    2.23 +diff -pruN ../orig-linux-2.6.18/kernel/softlockup.c ./kernel/softlockup.c
    2.24 +--- ../orig-linux-2.6.18/kernel/softlockup.c	2006-09-20 04:42:06.000000000 +0100
    2.25 ++++ ./kernel/softlockup.c	2007-02-07 01:53:22.000000000 +0000
    2.26 +@@ -40,6 +40,19 @@ void touch_softlockup_watchdog(void)
    2.27 + }
    2.28 + EXPORT_SYMBOL(touch_softlockup_watchdog);
    2.29 + 
    2.30 ++unsigned long softlockup_get_next_event(void)
    2.31 ++{
    2.32 ++	int this_cpu = smp_processor_id();
    2.33 ++	unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
    2.34 ++
    2.35 ++	if (per_cpu(print_timestamp, this_cpu) == touch_timestamp ||
    2.36 ++		did_panic ||
    2.37 ++			!per_cpu(watchdog_task, this_cpu))
    2.38 ++		return MAX_JIFFY_OFFSET;
    2.39 ++
    2.40 ++	return min_t(long, 0, touch_timestamp + HZ - jiffies);
    2.41 ++}
    2.42 ++
    2.43 + /*
    2.44 +  * This callback runs from the timer interrupt, and checks
    2.45 +  * whether the watchdog thread has hung or not:
    2.46 +diff -pruN ../orig-linux-2.6.18/kernel/timer.c ./kernel/timer.c
    2.47 +--- ../orig-linux-2.6.18/kernel/timer.c	2006-09-20 04:42:06.000000000 +0100
    2.48 ++++ ./kernel/timer.c	2007-02-07 01:29:34.000000000 +0000
    2.49 +@@ -485,7 +485,9 @@ unsigned long next_timer_interrupt(void)
    2.50 + 		if (hr_expires < 3)
    2.51 + 			return hr_expires + jiffies;
    2.52 + 	}
    2.53 +-	hr_expires += jiffies;
    2.54 ++	hr_expires = min_t(unsigned long,
    2.55 ++			   softlockup_get_next_event(),
    2.56 ++			   hr_expires) + jiffies;
    2.57 + 
    2.58 + 	base = __get_cpu_var(tvec_bases);
    2.59 + 	spin_lock(&base->lock);