Skip to content

Commit 1b849c8

Browse files
Michael Bohangregtwallace
authored andcommitted
hrtimer: Prevent enqueue of hrtimer on dead CPU
Date Wed, 10 Apr 2013 14:07:48 -0700 When switching the hrtimer cpu_base, we briefly allow for preemption to become enabled by unlocking the cpu_base lock. During this time, the CPU corresponding to the new cpu_base that was selected may in fact go offline. In this scenario, the hrtimer is enqueued to a CPU that's not online, and therefore it never fires. As an example, consider this example: CPU #0 CPU lg-devs#1 ---- ---- ... hrtimer_start() lock_hrtimer_base() switch_hrtimer_base() cpu = hrtimer_get_target() -> 1 spin_unlock(&cpu_base->lock) <migrate thread to CPU #0> <offline> spin_lock(&new_base->lock) this_cpu = 0 cpu != this_cpu enqueue_hrtimer(cpu_base lg-devs#1) To prevent this scenario, verify that the CPU corresponding to the new cpu_base is indeed online before selecting it in hrtimer_switch_base(). If it's not online, fallback to using the base of the current CPU. Signed-off-by: Michael Bohan <[email protected]>
1 parent 89e170f commit 1b849c8

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

kernel/hrtimer.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
226226

227227
this_cpu = smp_processor_id();
228228

229-
if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) {
229+
if (cpu != this_cpu && (hrtimer_check_target(timer, new_base)
230+
|| !cpu_online(cpu))) {
230231
raw_spin_unlock(&new_base->cpu_base->lock);
231232
raw_spin_lock(&base->cpu_base->lock);
232233
cpu = smp_processor_id();

0 commit comments

Comments
 (0)