aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/watchdog.c
diff options
context:
space:
mode:
authorDon Zickus <dzickus@redhat.com>2011-03-22 19:34:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-22 20:44:12 -0400
commitf99a99330f85a84c346ddeb4adc72dbfad9b9e3e (patch)
tree4c72a3f2231e7c79f1afeaee5cd03ae7331d3b7a /kernel/watchdog.c
parentfef2c9bc1b54c0261324a96e948c0b849796e896 (diff)
kernel/watchdog.c: always return NOTIFY_OK during cpu up/down events
This patch addresses a couple of problems. One was the case when the hardlockup failed to start, it also failed to start the softlockup. There were valid cases when the hardlockup shouldn't start and that shouldn't block the softlockup (no lapic, bios controls perf counters). The second problem was when the hardlockup failed to start on boxes (from a no lapic or bios controlled perf counter case), it reported failure to the cpu notifier chain. This blocked the notifier from continuing to start other more critical pieces of cpu bring-up (in our case based on a 2.6.32 fork, it was the mce). As a result, during soft cpu online/offline testing, the system would panic when a cpu was offlined because the cpu notifier would succeed in processing a watchdog disable cpu event and would panic in the mce case as a result of un-initialized variables from a never executed cpu up event. I realized the hardlockup/softlockup cases are really just debugging aids and should never impede the progress of a cpu up/down event. Therefore I modified the code to always return NOTIFY_OK and instead rely on printks to inform the user of problems. Signed-off-by: Don Zickus <dzickus@redhat.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Reviewed-by: WANG Cong <xiyou.wangcong@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/watchdog.c')
-rw-r--r--kernel/watchdog.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 054a67cca9da..140dce750450 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -418,19 +418,22 @@ static int watchdog_prepare_cpu(int cpu)
418static int watchdog_enable(int cpu) 418static int watchdog_enable(int cpu)
419{ 419{
420 struct task_struct *p = per_cpu(softlockup_watchdog, cpu); 420 struct task_struct *p = per_cpu(softlockup_watchdog, cpu);
421 int err; 421 int err = 0;
422 422
423 /* enable the perf event */ 423 /* enable the perf event */
424 err = watchdog_nmi_enable(cpu); 424 err = watchdog_nmi_enable(cpu);
425 if (err) 425
426 return err; 426 /* Regardless of err above, fall through and start softlockup */
427 427
428 /* create the watchdog thread */ 428 /* create the watchdog thread */
429 if (!p) { 429 if (!p) {
430 p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu); 430 p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu);
431 if (IS_ERR(p)) { 431 if (IS_ERR(p)) {
432 printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); 432 printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu);
433 return PTR_ERR(p); 433 if (!err)
434 /* if hardlockup hasn't already set this */
435 err = PTR_ERR(p);
436 goto out;
434 } 437 }
435 kthread_bind(p, cpu); 438 kthread_bind(p, cpu);
436 per_cpu(watchdog_touch_ts, cpu) = 0; 439 per_cpu(watchdog_touch_ts, cpu) = 0;
@@ -438,7 +441,8 @@ static int watchdog_enable(int cpu)
438 wake_up_process(p); 441 wake_up_process(p);
439 } 442 }
440 443
441 return 0; 444out:
445 return err;
442} 446}
443 447
444static void watchdog_disable(int cpu) 448static void watchdog_disable(int cpu)
@@ -550,7 +554,13 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
550 break; 554 break;
551#endif /* CONFIG_HOTPLUG_CPU */ 555#endif /* CONFIG_HOTPLUG_CPU */
552 } 556 }
553 return notifier_from_errno(err); 557
558 /*
559 * hardlockup and softlockup are not important enough
560 * to block cpu bring up. Just always succeed and
561 * rely on printk output to flag problems.
562 */
563 return NOTIFY_OK;
554} 564}
555 565
556static struct notifier_block __cpuinitdata cpu_nfb = { 566static struct notifier_block __cpuinitdata cpu_nfb = {