summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2017-09-25 20:21:54 +0200
committerThomas Gleixner <tglx@linutronix.de>2017-09-25 20:21:54 +0200
commit115ef3b7e61ac64e32827611a127002672ed3725 (patch)
tree0814accfe914507045c65a7e12b38acbd03d1b81 /kernel
parentwatchdog/hardlockup: Clean up hotplug locking mess (diff)
downloadlinux-115ef3b7e61ac64e32827611a127002672ed3725.tar.xz
linux-115ef3b7e61ac64e32827611a127002672ed3725.zip
watchdog/hardlockup/perf: Cure UP damage
for_each_cpu() unintuitively reports CPU0 as set independend of the actual cpumask content on UP kernels. That leads to a NULL pointer dereference when the cleanup function is invoked and there is no event to clean up. Reported-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/watchdog_hld.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c
index b2931154b5f2..204a8cadb717 100644
--- a/kernel/watchdog_hld.c
+++ b/kernel/watchdog_hld.c
@@ -220,8 +220,13 @@ void hardlockup_detector_perf_cleanup(void)
for_each_cpu(cpu, &dead_events_mask) {
struct perf_event *event = per_cpu(watchdog_ev, cpu);
+ /*
+ * Required because for_each_cpu() reports unconditionally
+ * CPU0 as set on UP kernels. Sigh.
+ */
+ if (event)
+ perf_event_release_kernel(event);
per_cpu(watchdog_ev, cpu) = NULL;
- perf_event_release_kernel(event);
}
cpumask_clear(&dead_events_mask);
}