Skip to content

Commit 68b2c8c

Browse files
Julien GrallKAGA-KOKO
authored andcommitted
hrtimer: Don't take expiry_lock when timer is currently migrated
migration_base is used as a placeholder when an hrtimer is migrated to a different CPU. In the case that hrtimer_cancel_wait_running() hits a timer which is currently migrated it would pointlessly acquire the expiry lock of the migration base, which is even not initialized. Surely it could be initialized, but there is absolutely no point in acquiring this lock because the timer is guaranteed not to run it's callback for which the caller waits to finish on that base. So it would just do the inc/lock/dec/unlock dance for nothing. As the base switch is short and non-preemptible, there is no issue when the wait function returns immediately. The timer base and base->cpu_base cannot be NULL in the code path which is invoking that, so just replace those checks with a check whether base is migration base. [ tglx: Updated from RT patch. Massaged changelog. Added comment. ] Signed-off-by: Julien Grall <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent dd2261e commit 68b2c8c

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

kernel/time/hrtimer.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,11 @@ void hrtimer_cancel_wait_running(const struct hrtimer *timer)
12171217
/* Lockless read. Prevent the compiler from reloading it below */
12181218
struct hrtimer_clock_base *base = READ_ONCE(timer->base);
12191219

1220-
if (!timer->is_soft || !base || !base->cpu_base) {
1220+
/*
1221+
* Just relax if the timer expires in hard interrupt context or if
1222+
* it is currently on the migration base.
1223+
*/
1224+
if (!timer->is_soft || base == &migration_base)
12211225
cpu_relax();
12221226
return;
12231227
}

0 commit comments

Comments
 (0)