aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2017-09-12 15:37:21 -0400
committerIngo Molnar <mingo@kernel.org>2017-09-14 05:41:08 -0400
commit146c9d0e9dfdb62ed6afd43cc263efafbbfd1dcf (patch)
tree6fdf1af693979b68fdc9f610d73aaf769080af05
parent2a1b8ee4f5665b4291e43e4a25d964c3eb2f4c32 (diff)
watchdog/hardlockup/perf: Use new perf CPU enable mechanism
Get rid of the hodgepodge which tries to be smart about perf being unavailable and error printout rate limiting. That's all not required simply because this is never invoked when the perf NMI watchdog is not functional. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Don Zickus <dzickus@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Sebastian Siewior <bigeasy@linutronix.de> Cc: Ulrich Obergfell <uobergfe@redhat.com> Link: http://lkml.kernel.org/r/20170912194148.259651788@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--kernel/watchdog.c4
-rw-r--r--kernel/watchdog_hld.c88
2 files changed, 8 insertions, 84 deletions
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index fd8a998eb197..5eb11960e4a2 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -107,6 +107,7 @@ __setup("hardlockup_all_cpu_backtrace=", hardlockup_all_cpu_backtrace_setup);
107 */ 107 */
108int __weak watchdog_nmi_enable(unsigned int cpu) 108int __weak watchdog_nmi_enable(unsigned int cpu)
109{ 109{
110 hardlockup_detector_perf_enable();
110 return 0; 111 return 0;
111} 112}
112 113
@@ -465,7 +466,8 @@ static void watchdog_enable(unsigned int cpu)
465 /* Initialize timestamp */ 466 /* Initialize timestamp */
466 __touch_watchdog(); 467 __touch_watchdog();
467 /* Enable the perf event */ 468 /* Enable the perf event */
468 watchdog_nmi_enable(cpu); 469 if (watchdog_enabled & NMI_WATCHDOG_ENABLED)
470 watchdog_nmi_enable(cpu);
469 471
470 watchdog_set_prio(SCHED_FIFO, MAX_RT_PRIO - 1); 472 watchdog_set_prio(SCHED_FIFO, MAX_RT_PRIO - 1);
471} 473}
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c
index 99a3f22e48cc..509bb6b59c41 100644
--- a/kernel/watchdog_hld.c
+++ b/kernel/watchdog_hld.c
@@ -25,7 +25,7 @@ static DEFINE_PER_CPU(struct perf_event *, dead_event);
25static struct cpumask dead_events_mask; 25static struct cpumask dead_events_mask;
26 26
27static unsigned long hardlockup_allcpu_dumped; 27static unsigned long hardlockup_allcpu_dumped;
28static bool hardlockup_detector_disabled; 28static unsigned int watchdog_cpus;
29 29
30void arch_touch_nmi_watchdog(void) 30void arch_touch_nmi_watchdog(void)
31{ 31{
@@ -160,84 +160,6 @@ static void watchdog_overflow_callback(struct perf_event *event,
160 return; 160 return;
161} 161}
162 162
163/*
164 * People like the simple clean cpu node info on boot.
165 * Reduce the watchdog noise by only printing messages
166 * that are different from what cpu0 displayed.
167 */
168static unsigned long firstcpu_err;
169static atomic_t watchdog_cpus;
170
171int watchdog_nmi_enable(unsigned int cpu)
172{
173 struct perf_event_attr *wd_attr;
174 struct perf_event *event = per_cpu(watchdog_ev, cpu);
175 int firstcpu = 0;
176
177 /* nothing to do if the hard lockup detector is disabled */
178 if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
179 goto out;
180
181 /* A failure disabled the hardlockup detector permanently */
182 if (hardlockup_detector_disabled)
183 return -ENODEV;
184
185 /* is it already setup and enabled? */
186 if (event && event->state > PERF_EVENT_STATE_OFF)
187 goto out;
188
189 /* it is setup but not enabled */
190 if (event != NULL)
191 goto out_enable;
192
193 if (atomic_inc_return(&watchdog_cpus) == 1)
194 firstcpu = 1;
195
196 wd_attr = &wd_hw_attr;
197 wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
198
199 /* Try to register using hardware perf events */
200 event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL);
201
202 /* save the first cpu's error for future comparision */
203 if (firstcpu && IS_ERR(event))
204 firstcpu_err = PTR_ERR(event);
205
206 if (!IS_ERR(event)) {
207 /* only print for the first cpu initialized */
208 if (firstcpu || firstcpu_err)
209 pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n");
210 goto out_save;
211 }
212
213 /* skip displaying the same error again */
214 if (!firstcpu && (PTR_ERR(event) == firstcpu_err))
215 return PTR_ERR(event);
216
217 /* vary the KERN level based on the returned errno */
218 if (PTR_ERR(event) == -EOPNOTSUPP)
219 pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu);
220 else if (PTR_ERR(event) == -ENOENT)
221 pr_warn("disabled (cpu%i): hardware events not enabled\n",
222 cpu);
223 else
224 pr_err("disabled (cpu%i): unable to create perf event: %ld\n",
225 cpu, PTR_ERR(event));
226
227 pr_info("Disabling hard lockup detector permanently\n");
228 hardlockup_detector_disabled = true;
229
230 return PTR_ERR(event);
231
232 /* success path */
233out_save:
234 per_cpu(watchdog_ev, cpu) = event;
235out_enable:
236 perf_event_enable(per_cpu(watchdog_ev, cpu));
237out:
238 return 0;
239}
240
241static int hardlockup_detector_event_create(void) 163static int hardlockup_detector_event_create(void)
242{ 164{
243 unsigned int cpu = smp_processor_id(); 165 unsigned int cpu = smp_processor_id();
@@ -267,6 +189,9 @@ void hardlockup_detector_perf_enable(void)
267 if (hardlockup_detector_event_create()) 189 if (hardlockup_detector_event_create())
268 return; 190 return;
269 191
192 if (!watchdog_cpus++)
193 pr_info("Enabled. Permanently consumes one hw-PMU counter.\n");
194
270 perf_event_enable(this_cpu_read(watchdog_ev)); 195 perf_event_enable(this_cpu_read(watchdog_ev));
271} 196}
272 197
@@ -282,10 +207,7 @@ void hardlockup_detector_perf_disable(void)
282 this_cpu_write(watchdog_ev, NULL); 207 this_cpu_write(watchdog_ev, NULL);
283 this_cpu_write(dead_event, event); 208 this_cpu_write(dead_event, event);
284 cpumask_set_cpu(smp_processor_id(), &dead_events_mask); 209 cpumask_set_cpu(smp_processor_id(), &dead_events_mask);
285 210 watchdog_cpus--;
286 /* watchdog_nmi_enable() expects this to be zero initially. */
287 if (atomic_dec_and_test(&watchdog_cpus))
288 firstcpu_err = 0;
289 } 211 }
290} 212}
291 213