X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fsoftlockup.c;h=01b6522fd92bc0b28f7df00eb66876a389b34908;hb=8d2bdf49481b27096e242119e73abe9348c1019b;hp=c1d76552446e592bc132d8de37073ecb589a1629;hpb=0008bf54408d4c0637c24d34642f1038c299be95;p=linux-2.6-omap-h63xx.git diff --git a/kernel/softlockup.c b/kernel/softlockup.c index c1d76552446..01b6522fd92 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -101,6 +101,10 @@ void softlockup_tick(void) now = get_timestamp(this_cpu); + /* Wake up the high-prio watchdog task every second: */ + if (now > (touch_timestamp + 1)) + wake_up_process(per_cpu(watchdog_task, this_cpu)); + /* Warn about unreasonable delays: */ if (now <= (touch_timestamp + softlockup_thresh)) return; @@ -191,11 +195,11 @@ static void check_hung_uninterruptible_tasks(int this_cpu) read_lock(&tasklist_lock); do_each_thread(g, t) { if (!--max_count) - break; + goto unlock; if (t->state & TASK_UNINTERRUPTIBLE) check_hung_task(t, now); } while_each_thread(g, t); - + unlock: read_unlock(&tasklist_lock); } @@ -212,6 +216,7 @@ static int watchdog(void *__bind_cpu) /* initialize timestamp */ touch_softlockup_watchdog(); + set_current_state(TASK_INTERRUPTIBLE); /* * Run briefly once per second to reset the softlockup timestamp. * If this gets delayed for more than 60 seconds then the @@ -219,14 +224,19 @@ static int watchdog(void *__bind_cpu) */ while (!kthread_should_stop()) { touch_softlockup_watchdog(); - msleep_interruptible(10000); + schedule(); - if (this_cpu != check_cpu) - continue; + if (kthread_should_stop()) + break; + + if (this_cpu == check_cpu) { + if (sysctl_hung_task_timeout_secs) + check_hung_uninterruptible_tasks(this_cpu); + } - if (sysctl_hung_task_timeout_secs) - check_hung_uninterruptible_tasks(this_cpu); + set_current_state(TASK_INTERRUPTIBLE); } + __set_current_state(TASK_RUNNING); return 0; } @@ -259,13 +269,6 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) wake_up_process(per_cpu(watchdog_task, hotcpu)); break; #ifdef CONFIG_HOTPLUG_CPU - case CPU_UP_CANCELED: - case CPU_UP_CANCELED_FROZEN: - if (!per_cpu(watchdog_task, hotcpu)) - break; - /* Unbind so it can run. Fall thru. */ - kthread_bind(per_cpu(watchdog_task, hotcpu), - any_online_cpu(cpu_online_map)); case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: if (hotcpu == check_cpu) { @@ -275,6 +278,14 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) check_cpu = any_online_cpu(temp_cpu_online_map); } break; + + case CPU_UP_CANCELED: + case CPU_UP_CANCELED_FROZEN: + if (!per_cpu(watchdog_task, hotcpu)) + break; + /* Unbind so it can run. Fall thru. */ + kthread_bind(per_cpu(watchdog_task, hotcpu), + any_online_cpu(cpu_online_map)); case CPU_DEAD: case CPU_DEAD_FROZEN: p = per_cpu(watchdog_task, hotcpu);