diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2017-09-25 20:21:54 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-09-25 20:21:54 +0200 |
commit | 115ef3b7e61ac64e32827611a127002672ed3725 (patch) | |
tree | 0814accfe914507045c65a7e12b38acbd03d1b81 /kernel/watchdog_hld.c | |
parent | ab5fe3ff38ff9653490910cc71dbbedc95a86e41 (diff) |
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/watchdog_hld.c')
-rw-r--r-- | kernel/watchdog_hld.c | 7 |
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); } |