debug: softlockup looping fix

Rafael J. Wysocki reported weird, multi-seconds delays during
suspend/resume and bisected it back to:

commit 82a1fcb90287052aabfa235e7ffc693ea003fe69
Author: Ingo Molnar <mingo@elte.hu>
Date: Fri Jan 25 21:08:02 2008 +0100

softlockup: automatically detect hung TASK_UNINTERRUPTIBLE tasks

fix it:

- restore the old wakeup mechanism
- fix break usage in do_each_thread() { } while_each_thread().
- fix the hotplug switch stmt, a fall-through case was broken.

Bisected-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Tested-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Peter Zijlstra and committed by Linus Torvalds ed50d6cb aa629992

+20 -10
+20 -10
kernel/softlockup.c
··· 101 101 102 102 now = get_timestamp(this_cpu); 103 103 104 + /* Wake up the high-prio watchdog task every second: */ 105 + if (now > (touch_timestamp + 1)) 106 + wake_up_process(per_cpu(watchdog_task, this_cpu)); 107 + 104 108 /* Warn about unreasonable delays: */ 105 109 if (now <= (touch_timestamp + softlockup_thresh)) 106 110 return; ··· 195 191 read_lock(&tasklist_lock); 196 192 do_each_thread(g, t) { 197 193 if (!--max_count) 198 - break; 194 + goto unlock; 199 195 if (t->state & TASK_UNINTERRUPTIBLE) 200 196 check_hung_task(t, now); 201 197 } while_each_thread(g, t); 202 - 198 + unlock: 203 199 read_unlock(&tasklist_lock); 204 200 } 205 201 ··· 222 218 * debug-printout triggers in softlockup_tick(). 223 219 */ 224 220 while (!kthread_should_stop()) { 221 + set_current_state(TASK_INTERRUPTIBLE); 225 222 touch_softlockup_watchdog(); 226 - msleep_interruptible(10000); 223 + schedule(); 224 + 225 + if (kthread_should_stop()) 226 + break; 227 227 228 228 if (this_cpu != check_cpu) 229 229 continue; 230 230 231 231 if (sysctl_hung_task_timeout_secs) 232 232 check_hung_uninterruptible_tasks(this_cpu); 233 + 233 234 } 234 235 235 236 return 0; ··· 268 259 wake_up_process(per_cpu(watchdog_task, hotcpu)); 269 260 break; 270 261 #ifdef CONFIG_HOTPLUG_CPU 271 - case CPU_UP_CANCELED: 272 - case CPU_UP_CANCELED_FROZEN: 273 - if (!per_cpu(watchdog_task, hotcpu)) 274 - break; 275 - /* Unbind so it can run. Fall thru. */ 276 - kthread_bind(per_cpu(watchdog_task, hotcpu), 277 - any_online_cpu(cpu_online_map)); 278 262 case CPU_DOWN_PREPARE: 279 263 case CPU_DOWN_PREPARE_FROZEN: 280 264 if (hotcpu == check_cpu) { ··· 277 275 check_cpu = any_online_cpu(temp_cpu_online_map); 278 276 } 279 277 break; 278 + 279 + case CPU_UP_CANCELED: 280 + case CPU_UP_CANCELED_FROZEN: 281 + if (!per_cpu(watchdog_task, hotcpu)) 282 + break; 283 + /* Unbind so it can run. Fall thru. */ 284 + kthread_bind(per_cpu(watchdog_task, hotcpu), 285 + any_online_cpu(cpu_online_map)); 280 286 case CPU_DEAD: 281 287 case CPU_DEAD_FROZEN: 282 288 p = per_cpu(watchdog_task, hotcpu);