add touch_all_softlockup_watchdogs()
authorJeremy Fitzhardinge <jeremy@goop.org>
Tue, 8 May 2007 07:28:05 +0000 (00:28 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 8 May 2007 18:15:06 +0000 (11:15 -0700)
Add touch_all_softlockup_watchdogs() to allow the softlockup watchdog
timers on all cpus to be updated.  This is used to prevent sysrq-t from
generating a spurious watchdog message when generating lots of output.

Softlockup watchdogs use sched_clock() as its timebase, which is inherently
per-cpu (at least, when it is measuring unstolen time).  Because of this,
it isn't possible for one CPU to directly update the other CPU's timers,
but it is possible to tell the other CPUs to do update themselves
appropriately.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Acked-by: Chris Lalancette <clalance@redhat.com>
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: Rick Lindsley <ricklind@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/sched.h
kernel/sched.c
kernel/softlockup.c

index d464bd0d657892ecc703627a36a5433f00764521..6312521df2c145d96ca6a847f1004078fadc6f59 100644 (file)
@@ -226,6 +226,7 @@ extern void scheduler_tick(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 void softlockup_tick(void)
 {
@@ -236,6 +237,9 @@ static inline void spawn_softlockup_task(void)
 static inline void touch_softlockup_watchdog(void)
 {
 }
+static inline void touch_all_softlockup_watchdogs(void)
+{
+}
 #endif
 
 
index 0227f1625a75d9cf0831138856ba7250b895d04d..5530ed211f72f9ef1ceed453cf6fdcca07da27d3 100644 (file)
@@ -4750,6 +4750,8 @@ void show_state_filter(unsigned long state_filter)
                        show_task(p);
        } while_each_thread(g, p);
 
+       touch_all_softlockup_watchdogs();
+
        read_unlock(&tasklist_lock);
        /*
         * Only show locks if all tasks are dumped:
index 5ea631742dbcf246e7dbd772e33c798c74ee6625..8fa7040247ad1971125916e3fe903581ecbc56c4 100644 (file)
@@ -50,6 +50,16 @@ void touch_softlockup_watchdog(void)
 }
 EXPORT_SYMBOL(touch_softlockup_watchdog);
 
+void touch_all_softlockup_watchdogs(void)
+{
+       int cpu;
+
+       /* Cause each CPU to re-update its timestamp rather than complain */
+       for_each_online_cpu(cpu)
+               per_cpu(touch_timestamp, cpu) = 0;
+}
+EXPORT_SYMBOL(touch_all_softlockup_watchdogs);
+
 /*
  * This callback runs from the timer interrupt, and checks
  * whether the watchdog thread has hung or not:
@@ -61,9 +71,10 @@ void softlockup_tick(void)
        unsigned long print_timestamp;
        unsigned long now;
 
-       /* watchdog task hasn't updated timestamp yet */
-       if (touch_timestamp == 0)
+       if (touch_timestamp == 0) {
+               touch_softlockup_watchdog();
                return;
+       }
 
        print_timestamp = per_cpu(print_timestamp, this_cpu);