diff options
Diffstat (limited to 'kernel/watchdog.c')
-rw-r--r-- | kernel/watchdog.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 14bc092fb12c..df30ee08bdd4 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * to those contributors as well. | 9 | * to those contributors as well. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #define pr_fmt(fmt) "NMI watchdog: " fmt | ||
13 | |||
12 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
13 | #include <linux/cpu.h> | 15 | #include <linux/cpu.h> |
14 | #include <linux/nmi.h> | 16 | #include <linux/nmi.h> |
@@ -319,11 +321,9 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) | |||
319 | */ | 321 | */ |
320 | static int watchdog(void *unused) | 322 | static int watchdog(void *unused) |
321 | { | 323 | { |
322 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | 324 | struct sched_param param = { .sched_priority = 0 }; |
323 | struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); | 325 | struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); |
324 | 326 | ||
325 | sched_setscheduler(current, SCHED_FIFO, ¶m); | ||
326 | |||
327 | /* initialize timestamp */ | 327 | /* initialize timestamp */ |
328 | __touch_watchdog(); | 328 | __touch_watchdog(); |
329 | 329 | ||
@@ -349,8 +349,11 @@ static int watchdog(void *unused) | |||
349 | 349 | ||
350 | set_current_state(TASK_INTERRUPTIBLE); | 350 | set_current_state(TASK_INTERRUPTIBLE); |
351 | } | 351 | } |
352 | /* | ||
353 | * Drop the policy/priority elevation during thread exit to avoid a | ||
354 | * scheduling latency spike. | ||
355 | */ | ||
352 | __set_current_state(TASK_RUNNING); | 356 | __set_current_state(TASK_RUNNING); |
353 | param.sched_priority = 0; | ||
354 | sched_setscheduler(current, SCHED_NORMAL, ¶m); | 357 | sched_setscheduler(current, SCHED_NORMAL, ¶m); |
355 | return 0; | 358 | return 0; |
356 | } | 359 | } |
@@ -376,18 +379,20 @@ static int watchdog_nmi_enable(int cpu) | |||
376 | /* Try to register using hardware perf events */ | 379 | /* Try to register using hardware perf events */ |
377 | event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); | 380 | event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); |
378 | if (!IS_ERR(event)) { | 381 | if (!IS_ERR(event)) { |
379 | printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n"); | 382 | pr_info("enabled, takes one hw-pmu counter.\n"); |
380 | goto out_save; | 383 | goto out_save; |
381 | } | 384 | } |
382 | 385 | ||
383 | 386 | ||
384 | /* vary the KERN level based on the returned errno */ | 387 | /* vary the KERN level based on the returned errno */ |
385 | if (PTR_ERR(event) == -EOPNOTSUPP) | 388 | if (PTR_ERR(event) == -EOPNOTSUPP) |
386 | printk(KERN_INFO "NMI watchdog disabled (cpu%i): not supported (no LAPIC?)\n", cpu); | 389 | pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu); |
387 | else if (PTR_ERR(event) == -ENOENT) | 390 | else if (PTR_ERR(event) == -ENOENT) |
388 | printk(KERN_WARNING "NMI watchdog disabled (cpu%i): hardware events not enabled\n", cpu); | 391 | pr_warning("disabled (cpu%i): hardware events not enabled\n", |
392 | cpu); | ||
389 | else | 393 | else |
390 | printk(KERN_ERR "NMI watchdog disabled (cpu%i): unable to create perf event: %ld\n", cpu, PTR_ERR(event)); | 394 | pr_err("disabled (cpu%i): unable to create perf event: %ld\n", |
395 | cpu, PTR_ERR(event)); | ||
391 | return PTR_ERR(event); | 396 | return PTR_ERR(event); |
392 | 397 | ||
393 | /* success path */ | 398 | /* success path */ |
@@ -439,9 +444,10 @@ static int watchdog_enable(int cpu) | |||
439 | 444 | ||
440 | /* create the watchdog thread */ | 445 | /* create the watchdog thread */ |
441 | if (!p) { | 446 | if (!p) { |
447 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | ||
442 | p = kthread_create_on_node(watchdog, NULL, cpu_to_node(cpu), "watchdog/%d", cpu); | 448 | p = kthread_create_on_node(watchdog, NULL, cpu_to_node(cpu), "watchdog/%d", cpu); |
443 | if (IS_ERR(p)) { | 449 | if (IS_ERR(p)) { |
444 | printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); | 450 | pr_err("softlockup watchdog for %i failed\n", cpu); |
445 | if (!err) { | 451 | if (!err) { |
446 | /* if hardlockup hasn't already set this */ | 452 | /* if hardlockup hasn't already set this */ |
447 | err = PTR_ERR(p); | 453 | err = PTR_ERR(p); |
@@ -450,6 +456,7 @@ static int watchdog_enable(int cpu) | |||
450 | } | 456 | } |
451 | goto out; | 457 | goto out; |
452 | } | 458 | } |
459 | sched_setscheduler(p, SCHED_FIFO, ¶m); | ||
453 | kthread_bind(p, cpu); | 460 | kthread_bind(p, cpu); |
454 | per_cpu(watchdog_touch_ts, cpu) = 0; | 461 | per_cpu(watchdog_touch_ts, cpu) = 0; |
455 | per_cpu(softlockup_watchdog, cpu) = p; | 462 | per_cpu(softlockup_watchdog, cpu) = p; |
@@ -496,7 +503,7 @@ static void watchdog_enable_all_cpus(void) | |||
496 | watchdog_enabled = 1; | 503 | watchdog_enabled = 1; |
497 | 504 | ||
498 | if (!watchdog_enabled) | 505 | if (!watchdog_enabled) |
499 | printk(KERN_ERR "watchdog: failed to be enabled on some cpus\n"); | 506 | pr_err("failed to be enabled on some cpus\n"); |
500 | 507 | ||
501 | } | 508 | } |
502 | 509 | ||