watchdog/hardlockup/perf: Cure UP damage
authorThomas Gleixner <tglx@linutronix.de>
Mon, 25 Sep 2017 18:21:54 +0000 (20:21 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 25 Sep 2017 18:21:54 +0000 (20:21 +0200)
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>
kernel/watchdog_hld.c

index b2931154b5f2809993a5c91bf8f76a6136e134ba..204a8cadb7170882182f9dea94370829653d00c2 100644 (file)
@@ -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);
 }