diff options
Diffstat (limited to 'kernel/watchdog.c')
-rw-r--r-- | kernel/watchdog.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index c8c21be11ab4..997c6a16ec22 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -31,6 +31,7 @@ | |||
31 | int watchdog_enabled = 1; | 31 | int watchdog_enabled = 1; |
32 | int __read_mostly watchdog_thresh = 10; | 32 | int __read_mostly watchdog_thresh = 10; |
33 | static int __read_mostly watchdog_disabled; | 33 | static int __read_mostly watchdog_disabled; |
34 | static u64 __read_mostly sample_period; | ||
34 | 35 | ||
35 | static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); | 36 | static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); |
36 | static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog); | 37 | static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog); |
@@ -116,7 +117,7 @@ static unsigned long get_timestamp(int this_cpu) | |||
116 | return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ | 117 | return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ |
117 | } | 118 | } |
118 | 119 | ||
119 | static u64 get_sample_period(void) | 120 | static void set_sample_period(void) |
120 | { | 121 | { |
121 | /* | 122 | /* |
122 | * convert watchdog_thresh from seconds to ns | 123 | * convert watchdog_thresh from seconds to ns |
@@ -125,7 +126,7 @@ static u64 get_sample_period(void) | |||
125 | * and hard thresholds) to increment before the | 126 | * and hard thresholds) to increment before the |
126 | * hardlockup detector generates a warning | 127 | * hardlockup detector generates a warning |
127 | */ | 128 | */ |
128 | return get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5); | 129 | sample_period = get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5); |
129 | } | 130 | } |
130 | 131 | ||
131 | /* Commands for resetting the watchdog */ | 132 | /* Commands for resetting the watchdog */ |
@@ -275,7 +276,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) | |||
275 | wake_up_process(__this_cpu_read(softlockup_watchdog)); | 276 | wake_up_process(__this_cpu_read(softlockup_watchdog)); |
276 | 277 | ||
277 | /* .. and repeat */ | 278 | /* .. and repeat */ |
278 | hrtimer_forward_now(hrtimer, ns_to_ktime(get_sample_period())); | 279 | hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period)); |
279 | 280 | ||
280 | if (touch_ts == 0) { | 281 | if (touch_ts == 0) { |
281 | if (unlikely(__this_cpu_read(softlockup_touch_sync))) { | 282 | if (unlikely(__this_cpu_read(softlockup_touch_sync))) { |
@@ -356,7 +357,7 @@ static void watchdog_enable(unsigned int cpu) | |||
356 | hrtimer->function = watchdog_timer_fn; | 357 | hrtimer->function = watchdog_timer_fn; |
357 | 358 | ||
358 | /* done here because hrtimer_start can only pin to smp_processor_id() */ | 359 | /* done here because hrtimer_start can only pin to smp_processor_id() */ |
359 | hrtimer_start(hrtimer, ns_to_ktime(get_sample_period()), | 360 | hrtimer_start(hrtimer, ns_to_ktime(sample_period), |
360 | HRTIMER_MODE_REL_PINNED); | 361 | HRTIMER_MODE_REL_PINNED); |
361 | 362 | ||
362 | /* initialize timestamp */ | 363 | /* initialize timestamp */ |
@@ -386,7 +387,7 @@ static int watchdog_should_run(unsigned int cpu) | |||
386 | /* | 387 | /* |
387 | * The watchdog thread function - touches the timestamp. | 388 | * The watchdog thread function - touches the timestamp. |
388 | * | 389 | * |
389 | * It only runs once every get_sample_period() seconds (4 seconds by | 390 | * It only runs once every sample_period seconds (4 seconds by |
390 | * default) to reset the softlockup timestamp. If this gets delayed | 391 | * default) to reset the softlockup timestamp. If this gets delayed |
391 | * for more than 2*watchdog_thresh seconds then the debug-printout | 392 | * for more than 2*watchdog_thresh seconds then the debug-printout |
392 | * triggers in watchdog_timer_fn(). | 393 | * triggers in watchdog_timer_fn(). |
@@ -519,6 +520,7 @@ int proc_dowatchdog(struct ctl_table *table, int write, | |||
519 | if (ret || !write) | 520 | if (ret || !write) |
520 | return ret; | 521 | return ret; |
521 | 522 | ||
523 | set_sample_period(); | ||
522 | if (watchdog_enabled && watchdog_thresh) | 524 | if (watchdog_enabled && watchdog_thresh) |
523 | watchdog_enable_all_cpus(); | 525 | watchdog_enable_all_cpus(); |
524 | else | 526 | else |
@@ -540,6 +542,7 @@ static struct smp_hotplug_thread watchdog_threads = { | |||
540 | 542 | ||
541 | void __init lockup_detector_init(void) | 543 | void __init lockup_detector_init(void) |
542 | { | 544 | { |
545 | set_sample_period(); | ||
543 | if (smpboot_register_percpu_thread(&watchdog_threads)) { | 546 | if (smpboot_register_percpu_thread(&watchdog_threads)) { |
544 | pr_err("Failed to create watchdog threads, disabled\n"); | 547 | pr_err("Failed to create watchdog threads, disabled\n"); |
545 | watchdog_disabled = -ENODEV; | 548 | watchdog_disabled = -ENODEV; |