[PATCH 12/12] hrtimer: Apply READ_ONCE() to lockless base->running loads

From: Paul E. McKenney

Date: Fri Sep 18 2026 - 20:20:43 EST


Updates to base->running are protected by the hrtimer base lock, but some
loads are lockless. Therefore, prevent compiler mischief by applying
READ_ONCE() to the lockless loads.

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
Cc: Anna-Maria Behnsen <anna-maria@xxxxxxxxxxxxx>
Cc: Frederic Weisbecker <frederic@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxx>
---
kernel/time/hrtimer.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 91ac2b517637..b3b4776c17a1 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1997,7 +1997,7 @@ bool hrtimer_active(const struct hrtimer *timer)
base = READ_ONCE(timer->base);
seq = raw_read_seqcount_begin(&base->seq);

- if (timer->is_queued || base->running == timer)
+ if (timer->is_queued || READ_ONCE(base->running) == timer)
return true;

} while (read_seqcount_retry(&base->seq, seq) || base != READ_ONCE(timer->base));
@@ -2034,7 +2034,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, struct hrtimer_cloc
lockdep_assert_held(&cpu_base->lock);

debug_hrtimer_deactivate(timer);
- base->running = timer;
+ WRITE_ONCE(base->running, timer);

/*
* Separate the ->running assignment from the ->is_queued assignment.
@@ -2093,7 +2093,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, struct hrtimer_cloc
raw_write_seqcount_barrier(&base->seq);

WARN_ON_ONCE(base->running != timer);
- base->running = NULL;
+ WRITE_ONCE(base->running, NULL);
}

static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
--
2.40.1