@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/smp.h>
+#include <linux/cpu.h>
#include "tick-internal.h"
@@ -431,6 +432,7 @@ void clockevents_notify(unsigned long reason, void *arg)
unsigned long flags;
int cpu;
+ get_online_cpus_atomic();
raw_spin_lock_irqsave(&clockevents_lock, flags);
clockevents_do_notify(reason, arg);
@@ -459,6 +461,7 @@ void clockevents_notify(unsigned long reason, void *arg)
break;
}
raw_spin_unlock_irqrestore(&clockevents_lock, flags);
+ put_online_cpus_atomic();
}
EXPORT_SYMBOL_GPL(clockevents_notify);
#endif
The cpu idle code invokes clockevents_notify() during idle state transitions and the cpu offline code invokes it during the CPU_DYING phase. There seems to be a race-condition between the two, where the clockevents_lock never gets released, ending in a lockup. This can be fixed by synchronizing clockevents_notify() with CPU offline, by wrapping its contents within get/put_online_cpus_atomic(). Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> --- kernel/time/clockevents.c | 3 +++ 1 file changed, 3 insertions(+)