diff options
Diffstat (limited to 'kernel/watchdog.c')
-rw-r--r-- | kernel/watchdog.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 18bb15776c57..140dce750450 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -48,12 +48,15 @@ static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); | |||
48 | * Should we panic when a soft-lockup or hard-lockup occurs: | 48 | * Should we panic when a soft-lockup or hard-lockup occurs: |
49 | */ | 49 | */ |
50 | #ifdef CONFIG_HARDLOCKUP_DETECTOR | 50 | #ifdef CONFIG_HARDLOCKUP_DETECTOR |
51 | static int hardlockup_panic; | 51 | static int hardlockup_panic = |
52 | CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; | ||
52 | 53 | ||
53 | static int __init hardlockup_panic_setup(char *str) | 54 | static int __init hardlockup_panic_setup(char *str) |
54 | { | 55 | { |
55 | if (!strncmp(str, "panic", 5)) | 56 | if (!strncmp(str, "panic", 5)) |
56 | hardlockup_panic = 1; | 57 | hardlockup_panic = 1; |
58 | else if (!strncmp(str, "nopanic", 7)) | ||
59 | hardlockup_panic = 0; | ||
57 | else if (!strncmp(str, "0", 1)) | 60 | else if (!strncmp(str, "0", 1)) |
58 | watchdog_enabled = 0; | 61 | watchdog_enabled = 0; |
59 | return 1; | 62 | return 1; |
@@ -415,19 +418,22 @@ static int watchdog_prepare_cpu(int cpu) | |||
415 | static int watchdog_enable(int cpu) | 418 | static int watchdog_enable(int cpu) |
416 | { | 419 | { |
417 | struct task_struct *p = per_cpu(softlockup_watchdog, cpu); | 420 | struct task_struct *p = per_cpu(softlockup_watchdog, cpu); |
418 | int err; | 421 | int err = 0; |
419 | 422 | ||
420 | /* enable the perf event */ | 423 | /* enable the perf event */ |
421 | err = watchdog_nmi_enable(cpu); | 424 | err = watchdog_nmi_enable(cpu); |
422 | if (err) | 425 | |
423 | return err; | 426 | /* Regardless of err above, fall through and start softlockup */ |
424 | 427 | ||
425 | /* create the watchdog thread */ | 428 | /* create the watchdog thread */ |
426 | if (!p) { | 429 | if (!p) { |
427 | p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu); | 430 | p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu); |
428 | if (IS_ERR(p)) { | 431 | if (IS_ERR(p)) { |
429 | printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); | 432 | printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); |
430 | return PTR_ERR(p); | 433 | if (!err) |
434 | /* if hardlockup hasn't already set this */ | ||
435 | err = PTR_ERR(p); | ||
436 | goto out; | ||
431 | } | 437 | } |
432 | kthread_bind(p, cpu); | 438 | kthread_bind(p, cpu); |
433 | per_cpu(watchdog_touch_ts, cpu) = 0; | 439 | per_cpu(watchdog_touch_ts, cpu) = 0; |
@@ -435,7 +441,8 @@ static int watchdog_enable(int cpu) | |||
435 | wake_up_process(p); | 441 | wake_up_process(p); |
436 | } | 442 | } |
437 | 443 | ||
438 | return 0; | 444 | out: |
445 | return err; | ||
439 | } | 446 | } |
440 | 447 | ||
441 | static void watchdog_disable(int cpu) | 448 | static void watchdog_disable(int cpu) |
@@ -547,7 +554,13 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
547 | break; | 554 | break; |
548 | #endif /* CONFIG_HOTPLUG_CPU */ | 555 | #endif /* CONFIG_HOTPLUG_CPU */ |
549 | } | 556 | } |
550 | 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; | ||
551 | } | 564 | } |
552 | 565 | ||
553 | static struct notifier_block __cpuinitdata cpu_nfb = { | 566 | static struct notifier_block __cpuinitdata cpu_nfb = { |