This is a note to let you know that I've just added the patch titled
clocksource: Make watchdog robust vs. interruption
to the 2.6.32-longterm tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/longterm/longterm-queue-2.6.32.git;a=summary
The filename of the patch is:
clocksource-make-watchdog-robust-vs.-interruption.patch
and it can be found in the queue-2.6.32 subdirectory.
If you, or anyone else, feels it should not be added to the 2.6.32 longterm
tree,
please let <[email protected]> know about it.
>From b5199515c25cca622495eb9c6a8a1d275e775088 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <[email protected]>
Date: Thu, 16 Jun 2011 16:22:08 +0200
Subject: clocksource: Make watchdog robust vs. interruption
From: Thomas Gleixner <[email protected]>
commit b5199515c25cca622495eb9c6a8a1d275e775088 upstream.
The clocksource watchdog code is interruptible and it has been
observed that this can trigger false positives which disable the TSC.
The reason is that an interrupt storm or a long running interrupt
handler between the read of the watchdog source and the read of the
TSC brings the two far enough apart that the delta is larger than the
unstable treshold. Move both reads into a short interrupt disabled
region to avoid that.
Reported-and-tested-by: Vernon Mauery <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/clocksource.h | 1 +
kernel/time/clocksource.c | 24 +++++++++++++-----------
2 files changed, 14 insertions(+), 11 deletions(-)
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -190,6 +190,7 @@ struct clocksource {
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
/* Watchdog related data, used by the framework */
struct list_head wd_list;
+ cycle_t cs_last;
cycle_t wd_last;
#endif
};
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -131,7 +131,6 @@ static struct clocksource *watchdog;
static struct timer_list watchdog_timer;
static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);
static DEFINE_SPINLOCK(watchdog_lock);
-static cycle_t watchdog_last;
static int watchdog_running;
static int clocksource_watchdog_kthread(void *data);
@@ -200,11 +199,6 @@ static void clocksource_watchdog(unsigne
if (!watchdog_running)
goto out;
- wdnow = watchdog->read(watchdog);
- wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask,
- watchdog->mult, watchdog->shift);
- watchdog_last = wdnow;
-
list_for_each_entry(cs, &watchdog_list, wd_list) {
/* Clocksource already marked unstable? */
@@ -214,19 +208,28 @@ static void clocksource_watchdog(unsigne
continue;
}
+ local_irq_disable();
csnow = cs->read(cs);
+ wdnow = watchdog->read(watchdog);
+ local_irq_enable();
/* Clocksource initialized ? */
if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) {
cs->flags |= CLOCK_SOURCE_WATCHDOG;
- cs->wd_last = csnow;
+ cs->wd_last = wdnow;
+ cs->cs_last = csnow;
continue;
}
- /* Check the deviation from the watchdog clocksource. */
- cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) &
+ wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) &
watchdog->mask,
+ watchdog->mult, watchdog->shift);
+
+ cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) &
cs->mask, cs->mult, cs->shift);
- cs->wd_last = csnow;
+ cs->cs_last = csnow;
+ cs->wd_last = wdnow;
+
+ /* Check the deviation from the watchdog clocksource. */
if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) {
clocksource_unstable(cs, cs_nsec - wd_nsec);
continue;
@@ -264,7 +267,6 @@ static inline void clocksource_start_wat
return;
init_timer(&watchdog_timer);
watchdog_timer.function = clocksource_watchdog;
- watchdog_last = watchdog->read(watchdog);
watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask));
watchdog_running = 1;
Patches currently in longterm-queue-2.6.32 which might be from
[email protected] are
/home/gregkh/linux/longterm/longterm-queue-2.6.32/queue-2.6.32/clocksource-make-watchdog-robust-vs.-interruption.patch
_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable