diff --git a/include/linux/sched.h b/include/linux/sched.h index d464bd0d6578..6312521df2c1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -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 diff --git a/kernel/sched.c b/kernel/sched.c index 0227f1625a75..5530ed211f72 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -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: diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 5ea631742dbc..8fa7040247ad 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -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);