mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2] Fix data races on hrtimer_sleeper ->task field
@ 2026-09-19  0:13 Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 01/12] hrtimer: Mark data-racy accesses to " Paul E. McKenney
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:13 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team

Hello!

In CONFIG_KCSAN_STRICT=y mode, KCSAN finds data races on the
hrtimer_sleeper structure's ->task field.  This field is used to indicate
owner of this structure, and also to signal the sleeper that the sleep
is over through use of a store of NULL.

Because access to the ->task field is open-coded across several kernel
subsystems, this series creates accessor functions creatively named
hrtimer_sleeper_task_get() and hrtimer_sleeper_task_set(), and uses
these throughout.

While in the area, also apply READ_ONCE() to lockless loads from
base->running.

A key goal of this and similar serieses is to reduce KCSAN noise in
strict mode so that new data races are more visible.

The series is as follows:

1.	Mark data-racy accesses to hrtimer_sleeper ->task field.

2.	Use accessor for hrtimer_sleeper ->task field.

3.	Use accessor for hrtimer_sleeper ->task field.

4.	Use accessor for hrtimer_sleeper ->task field.

5.	Use accessor for hrtimer_sleeper ->task field in waitwake.c.

6.	Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c.

7.	pktgen: Use accessor for hrtimer_sleeper ->task field.

8.	Use accessor for hrtimer_sleeper ->task field.

9.	Use accessor for hrtimer_sleeper ->task field in requeue.

10.	Update hrtimer_resolution only if value changes.

11.	Mark the hrtimer_sleeper structure's ->task field __private.

12.	Apply READ_ONCE() to lockless base->running loads.

						Thanx, Paul

Changes since RFC v1:

o	Add patch 10 to avoid both cache misses and KCSAN false positives
	when updating hrtimer_resolution.

o	Add patch 11 to mark the hrtimer_sleeper structure's ->task
	field __private, as suggested by Thomas Gleixner.

o	Add patch 12 for a similar KCSAN issue involving lockless
	loads from base->running.

------------------------------------------------------------------------

 b/fs/aio.c                    |    2 +-
 b/include/linux/hrtimer.h     |    8 ++++++++
 b/include/linux/wait.h        |    2 +-
 b/io_uring/rw.c               |    2 +-
 b/kernel/futex/requeue.c      |    2 +-
 b/kernel/futex/waitwake.c     |    8 ++++----
 b/kernel/locking/rtmutex.c    |    2 +-
 b/kernel/time/hrtimer.c       |   14 +++++++-------
 b/kernel/time/sleep_timeout.c |    4 ++--
 b/net/core/pktgen.c           |    4 ++--
 include/linux/hrtimer.h       |    6 +++---
 kernel/time/hrtimer.c         |    9 +++++----
 12 files changed, 36 insertions(+), 27 deletions(-)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 01/12] hrtimer: Mark data-racy accesses to hrtimer_sleeper ->task field
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 02/12] aio: Use accessor for " Paul E. McKenney
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, Dmitry Ilvokhin

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However,
that is no reason to let the compiler introduce additional confusion.

Therefore, mark data-racy accesses to the hrtimer_sleeper ->task field
using READ_ONCE() (using a new hrtimer_sleeper_task_get() access function)
and WRITE_ONCE() (using a new hrtimer_sleeper_task_set() access function).

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Dmitry Ilvokhin <d@ilvokhin.com>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 include/linux/hrtimer.h |  8 ++++++++
 kernel/time/hrtimer.c   | 14 +++++++-------
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 29072d89e5cb..d44549c0a2c1 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -320,6 +320,14 @@ extern int schedule_hrtimeout_range_clock(ktime_t *expires,
 					  const enum hrtimer_mode mode,
 					  clockid_t clock_id);
 extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
+static inline struct task_struct *hrtimer_sleeper_task_get(struct hrtimer_sleeper *sl)
+{
+	return READ_ONCE(sl->task);
+}
+static inline void hrtimer_sleeper_task_set(struct hrtimer_sleeper *sl, struct task_struct *t)
+{
+	WRITE_ONCE(sl->task, t);
+}
 
 /* Soft interrupt function to run the hrtimer queues: */
 extern void hrtimer_run_queues(void);
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 530d61257b9a..53c57d585696 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -2316,9 +2316,9 @@ void hrtimer_run_queues(void)
 static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer)
 {
 	struct hrtimer_sleeper *t = container_of(timer, struct hrtimer_sleeper, timer);
-	struct task_struct *task = t->task;
+	struct task_struct *task = hrtimer_sleeper_task_get(t);
 
-	t->task = NULL;
+	hrtimer_sleeper_task_set(t, NULL);
 	if (task)
 		wake_up_process(task);
 
@@ -2347,7 +2347,7 @@ void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl, enum hrtimer_mode
 
 	/* If already expired, clear the task pointer and set current state to running */
 	if (!hrtimer_start_expires_user(&sl->timer, mode)) {
-		sl->task = NULL;
+		hrtimer_sleeper_task_set(sl, NULL);
 		__set_current_state(TASK_RUNNING);
 	}
 }
@@ -2381,7 +2381,7 @@ static void __hrtimer_setup_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_
 	}
 
 	__hrtimer_setup(&sl->timer, hrtimer_wakeup, clock_id, mode);
-	sl->task = current;
+	hrtimer_sleeper_task_set(sl, current);
 }
 
 /**
@@ -2425,17 +2425,17 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
 		set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE);
 		hrtimer_sleeper_start_expires(t, mode);
 
-		if (likely(t->task))
+		if (likely(hrtimer_sleeper_task_get(t)))
 			schedule();
 
 		hrtimer_cancel(&t->timer);
 		mode = HRTIMER_MODE_ABS;
 
-	} while (t->task && !signal_pending(current));
+	} while (hrtimer_sleeper_task_get(t) && !signal_pending(current));
 
 	__set_current_state(TASK_RUNNING);
 
-	if (!t->task)
+	if (!hrtimer_sleeper_task_get(t))
 		return 0;
 
 	restart = &current->restart_block;
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 02/12] aio: Use accessor for hrtimer_sleeper ->task field
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 01/12] hrtimer: Mark data-racy accesses to " Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 03/12] wait: " Paul E. McKenney
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, Jan Kara,
	Christian Brauner, Benjamin LaHaise, Alexander Viro

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christian Brauner (Amutable) <brauner@kernel.org>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 fs/aio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/aio.c b/fs/aio.c
index d78acc69f487..8130d9e637ea 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1402,7 +1402,7 @@ static long read_events(struct kioctx *ctx, long min_nr, long nr,
 		w.min_nr = min_nr - ret;
 
 		ret2 = prepare_to_wait_event(&ctx->wait, &w.w, TASK_INTERRUPTIBLE);
-		if (!ret2 && !t.task)
+		if (!ret2 && !hrtimer_sleeper_task_get(&t))
 			ret2 = -ETIME;
 
 		if (aio_read_events(ctx, min_nr, nr, event, &ret) || ret2)
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 03/12] wait: Use accessor for hrtimer_sleeper ->task field
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 01/12] hrtimer: Mark data-racy accesses to " Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 02/12] aio: Use accessor for " Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 04/12] io-uring/rw: " Paul E. McKenney
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, Ingo Molnar, Juri Lelli,
	Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
	Mel Gorman, Valentin Schneider, K Prateek Nayak

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

Therefore, apply this accessor to the __wait_event_hrtimeout() macro.

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 include/linux/wait.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/wait.h b/include/linux/wait.h
index 7e215330199c..c2af98b0074d 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -556,7 +556,7 @@ do {										\
 	}									\
 										\
 	__ret = ___wait_event(wq_head, condition, state, 0, 0,			\
-		if (!__t.task) {						\
+		if (!hrtimer_sleeper_task_get(&__t)) {				\
 			__ret = -ETIME;						\
 			break;							\
 		}								\
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 04/12] io-uring/rw: Use accessor for hrtimer_sleeper ->task field
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (2 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 03/12] wait: " Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 05/12] futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c Paul E. McKenney
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, Jens Axboe

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

Therefore, apply this accessor to the io_hybrid_iopoll_delay() function.

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 io_uring/rw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/io_uring/rw.c b/io_uring/rw.c
index 95106dd1d7eb..3f4cbdb8b2be 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -1285,7 +1285,7 @@ static u64 io_hybrid_iopoll_delay(struct io_ring_ctx *ctx, struct io_kiocb *req)
 	set_current_state(TASK_INTERRUPTIBLE);
 	hrtimer_sleeper_start_expires(&timer, mode);
 
-	if (timer.task)
+	if (hrtimer_sleeper_task_get(&timer))
 		io_schedule();
 
 	hrtimer_cancel(&timer.timer);
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 05/12] futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (3 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 04/12] io-uring/rw: " Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 06/12] timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c Paul E. McKenney
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, André Almeida,
	Dmitry Ilvokhin, Ingo Molnar, Darren Hart, Davidlohr Bueso

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

Therefore, apply this accessor to kernel/futex/waitwake.c.

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Dmitry Ilvokhin <d@ilvokhin.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Darren Hart <dvhart@infradead.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: "André Almeida" <andrealmeid@igalia.com>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 kernel/futex/waitwake.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/futex/waitwake.c b/kernel/futex/waitwake.c
index d4483d15d30a..cf18309e5770 100644
--- a/kernel/futex/waitwake.c
+++ b/kernel/futex/waitwake.c
@@ -383,7 +383,7 @@ void futex_do_wait(struct futex_q *q, struct hrtimer_sleeper *timeout)
 		 * flagged for rescheduling. Only call schedule if there
 		 * is no timeout, or if it has yet to expire.
 		 */
-		if (!timeout || timeout->task)
+		if (!timeout || hrtimer_sleeper_task_get(timeout))
 			schedule();
 	}
 	__set_current_state(TASK_RUNNING);
@@ -539,7 +539,7 @@ int futex_wait_multiple_setup(struct futex_vector *vs, int count, int *woken)
 static void futex_sleep_multiple(struct futex_vector *vs, unsigned int count,
 				 struct hrtimer_sleeper *to)
 {
-	if (to && !to->task)
+	if (to && !hrtimer_sleeper_task_get(to))
 		return;
 
 	for (; count; count--, vs++) {
@@ -590,7 +590,7 @@ int futex_wait_multiple(struct futex_vector *vs, unsigned int count,
 		if (ret >= 0)
 			return ret;
 
-		if (to && !to->task)
+		if (to && !hrtimer_sleeper_task_get(to))
 			return -ETIMEDOUT;
 		else if (signal_pending(current))
 			return -ERESTARTSYS;
@@ -725,7 +725,7 @@ int __futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
 	if (!futex_unqueue(&q))
 		return 0;
 
-	if (to && !to->task)
+	if (to && !hrtimer_sleeper_task_get(to))
 		return -ETIMEDOUT;
 
 	/*
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 06/12] timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (4 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 05/12] futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 07/12] net: pktgen: Use accessor for hrtimer_sleeper ->task field Paul E. McKenney
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, Dmitry Ilvokhin

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

Therefore, apply this accessor to schedule_hrtimeout_range_clock().

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Dmitry Ilvokhin <d@ilvokhin.com>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 kernel/time/sleep_timeout.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/time/sleep_timeout.c b/kernel/time/sleep_timeout.c
index 3c90574bd904..ad8c415851ae 100644
--- a/kernel/time/sleep_timeout.c
+++ b/kernel/time/sleep_timeout.c
@@ -212,7 +212,7 @@ int __sched schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,
 	hrtimer_set_expires_range_ns(&t.timer, *expires, delta);
 	hrtimer_sleeper_start_expires(&t, mode);
 
-	if (likely(t.task))
+	if (likely(hrtimer_sleeper_task_get(&t)))
 		schedule();
 
 	hrtimer_cancel(&t.timer);
@@ -220,7 +220,7 @@ int __sched schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,
 
 	__set_current_state(TASK_RUNNING);
 
-	return !t.task ? 0 : -EINTR;
+	return !hrtimer_sleeper_task_get(&t) ? 0 : -EINTR;
 }
 EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock);
 
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 07/12] net: pktgen: Use accessor for hrtimer_sleeper ->task field
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (5 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 06/12] timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 08/12] rtmutex: " Paul E. McKenney
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

Therefore, apply this accessor to the pktgen spin() function.

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <netdev@vger.kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
---
 net/core/pktgen.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 7f81aed46672..784d8398fb7a 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2346,11 +2346,11 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 			set_current_state(TASK_INTERRUPTIBLE);
 			hrtimer_sleeper_start_expires(&t, HRTIMER_MODE_ABS);
 
-			if (likely(t.task))
+			if (likely(hrtimer_sleeper_task_get(&t)))
 				schedule();
 
 			hrtimer_cancel(&t.timer);
-		} while (t.task && pkt_dev->running && !signal_pending(current));
+		} while (hrtimer_sleeper_task_get(&t) && pkt_dev->running && !signal_pending(current));
 		__set_current_state(TASK_RUNNING);
 		end_time = ktime_get();
 	}
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 08/12] rtmutex: Use accessor for hrtimer_sleeper ->task field
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (6 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 07/12] net: pktgen: Use accessor for hrtimer_sleeper ->task field Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 09/12] futex: Use accessor for hrtimer_sleeper ->task field in requeue Paul E. McKenney
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, Dmitry Ilvokhin,
	Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

Therefore, apply this accessor to rt_mutex_slowlock_block().

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Dmitry Ilvokhin <d@ilvokhin.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Will Deacon <will@kernel.org>
Cc: Boqun Feng <boqun@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 kernel/locking/rtmutex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 4728631ae719..5a9534c715b8 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -1644,7 +1644,7 @@ static int __sched rt_mutex_slowlock_block(struct rt_mutex_base *lock,
 			break;
 		}
 
-		if (timeout && !timeout->task) {
+		if (timeout && !hrtimer_sleeper_task_get(timeout)) {
 			ret = -ETIMEDOUT;
 			break;
 		}
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 09/12] futex: Use accessor for hrtimer_sleeper ->task field in requeue
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (7 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 08/12] rtmutex: " Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 10/12] hrtimer: Update hrtimer_resolution only if value changes Paul E. McKenney
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney, André Almeida,
	Dmitry Ilvokhin, Ingo Molnar, Darren Hart, Davidlohr Bueso

The hrtimer_sleeper structure's ->task field is used as a flag to indicate
that the associated hrtimer has expired.  This means that the hrtimer
handler can be storing to this field while other code is loading from it
to check for expiry.  Note that additional races appear for hrtimers that
can be restarted, which could be argued to be a user error.  However, that
is no reason to let the compiler introduce additional confusion, and to
this end, the hrtimer_sleeper_task_get() was introduced, use of which also
has the benefit of avoiding open-code access to hrtimer_sleeper innards.

Therefore, apply this accessor to handle_early_requeue_pi_wakeup().

KCSAN located this issue.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Dmitry Ilvokhin <d@ilvokhin.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Darren Hart <dvhart@infradead.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: "André Almeida" <andrealmeid@igalia.com>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: <linux-aio@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>
Cc: <io-uring@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
 kernel/futex/requeue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c
index 79823ad13683..196d6ff148a4 100644
--- a/kernel/futex/requeue.c
+++ b/kernel/futex/requeue.c
@@ -736,7 +736,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
 
 	/* Handle spurious wakeups gracefully */
 	ret = -EWOULDBLOCK;
-	if (timeout && !timeout->task)
+	if (timeout && !hrtimer_sleeper_task_get(timeout))
 		ret = -ETIMEDOUT;
 	else if (signal_pending(current))
 		ret = -ERESTARTNOINTR;
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 10/12] hrtimer: Update hrtimer_resolution only if value changes
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (8 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 09/12] futex: Use accessor for hrtimer_sleeper ->task field in requeue Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 11/12] hrtimer: Mark the hrtimer_sleeper structure's ->task field __private Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 12/12] hrtimer: Apply READ_ONCE() to lockless base->running loads Paul E. McKenney
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney

Currently, the hrtimer_switch_to_hres() function unconditionally updates
hrtimer_resolution to HIGH_RES_NSEC.  This causes KCSAN false positives
in kernels built with CONFIG_KCSAN_STRICT=y.  It also causes unnecessary
cache-line traffic on the many code paths that load hrtimer_resolution,
which is especially regrettable because the value of hrtimer_resolution
normally changes only once during the lifetime of a given kernel.

Therefore, update the value of hrtimer_resolution to HIGH_RES_NSEC only
if it does not already have that value.

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

diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 53c57d585696..91ac2b517637 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -780,7 +780,8 @@ static void hrtimer_switch_to_hres(void)
 		return;
 	}
 	base->hres_active = true;
-	hrtimer_resolution = HIGH_RES_NSEC;
+	if (hrtimer_resolution != HIGH_RES_NSEC)
+		hrtimer_resolution = HIGH_RES_NSEC;
 
 	tick_setup_sched_timer(true);
 	/* "Retrigger" the interrupt to get things going */
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 11/12] hrtimer: Mark the hrtimer_sleeper structure's ->task field __private
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (9 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 10/12] hrtimer: Update hrtimer_resolution only if value changes Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  2026-09-19  0:14 ` [PATCH 12/12] hrtimer: Apply READ_ONCE() to lockless base->running loads Paul E. McKenney
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney

The hrtimer_sleeper structure's ->task field is now used only by the
hrtimer_sleeper_task_get() and hrtimer_sleeper_task_set() functions,
and there is no reason for it to be directly accessed anywhere else.

Therefore, mark this field __private and use ACCESS_PRIVATE() in
hrtimer_sleeper_task_get() and hrtimer_sleeper_task_set().

Suggested-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
---
 include/linux/hrtimer.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index d44549c0a2c1..cad8482337cb 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -72,7 +72,7 @@ enum hrtimer_mode {
  */
 struct hrtimer_sleeper {
 	struct hrtimer timer;
-	struct task_struct *task;
+	struct task_struct *__private task;
 };
 
 static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
@@ -322,11 +322,11 @@ extern int schedule_hrtimeout_range_clock(ktime_t *expires,
 extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
 static inline struct task_struct *hrtimer_sleeper_task_get(struct hrtimer_sleeper *sl)
 {
-	return READ_ONCE(sl->task);
+	return READ_ONCE(ACCESS_PRIVATE(sl, task));
 }
 static inline void hrtimer_sleeper_task_set(struct hrtimer_sleeper *sl, struct task_struct *t)
 {
-	WRITE_ONCE(sl->task, t);
+	WRITE_ONCE(ACCESS_PRIVATE(sl, task), t);
 }
 
 /* Soft interrupt function to run the hrtimer queues: */
-- 
2.40.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 12/12] hrtimer: Apply READ_ONCE() to lockless base->running loads
  2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
                   ` (10 preceding siblings ...)
  2026-09-19  0:14 ` [PATCH 11/12] hrtimer: Mark the hrtimer_sleeper structure's ->task field __private Paul E. McKenney
@ 2026-09-19  0:14 ` Paul E. McKenney
  11 siblings, 0 replies; 13+ messages in thread
From: Paul E. McKenney @ 2026-09-19  0:14 UTC (permalink / raw)
  To: Anna-Maria Behnsen, Frederic Weisbecker, Thomas Gleixner
  Cc: linux-kernel, Peter Zijlstra, linux-aio, linux-fsdevel, io-uring,
	netdev, kernel-team, Paul E. McKenney

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@kernel.org>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
---
 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


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-09-19  0:14 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-19  0:13 [PATCH v2] Fix data races on hrtimer_sleeper ->task field Paul E. McKenney
2026-09-19  0:14 ` [PATCH 01/12] hrtimer: Mark data-racy accesses to " Paul E. McKenney
2026-09-19  0:14 ` [PATCH 02/12] aio: Use accessor for " Paul E. McKenney
2026-09-19  0:14 ` [PATCH 03/12] wait: " Paul E. McKenney
2026-09-19  0:14 ` [PATCH 04/12] io-uring/rw: " Paul E. McKenney
2026-09-19  0:14 ` [PATCH 05/12] futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c Paul E. McKenney
2026-09-19  0:14 ` [PATCH 06/12] timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c Paul E. McKenney
2026-09-19  0:14 ` [PATCH 07/12] net: pktgen: Use accessor for hrtimer_sleeper ->task field Paul E. McKenney
2026-09-19  0:14 ` [PATCH 08/12] rtmutex: " Paul E. McKenney
2026-09-19  0:14 ` [PATCH 09/12] futex: Use accessor for hrtimer_sleeper ->task field in requeue Paul E. McKenney
2026-09-19  0:14 ` [PATCH 10/12] hrtimer: Update hrtimer_resolution only if value changes Paul E. McKenney
2026-09-19  0:14 ` [PATCH 11/12] hrtimer: Mark the hrtimer_sleeper structure's ->task field __private Paul E. McKenney
2026-09-19  0:14 ` [PATCH 12/12] hrtimer: Apply READ_ONCE() to lockless base->running loads Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®