[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230425183313.143596887@linutronix.de>
Date: Tue, 25 Apr 2023 20:49:05 +0200 (CEST)
From: Thomas Gleixner <tglx@...utronix.de>
To: LKML <linux-kernel@...r.kernel.org>
Cc: Frederic Weisbecker <frederic@...nel.org>,
Anna-Maria Behnsen <anna-maria@...utronix.de>,
Peter Zijlstra <peterz@...radead.org>,
Sebastian Siewior <bigeasy@...utronix.de>,
syzbot+5c54bd3eb218bb595aa9@...kaller.appspotmail.com,
Dmitry Vyukov <dvyukov@...gle.com>,
Michael Kerrisk <mtk.manpages@...il.com>
Subject: [patch 06/20] posix-timers: Annotate concurrent access to k_itimer::it_signal
k_itimer::it_signal is read lockless in the RCU protected hash lookup, but
it can be written concurrently in the timer_create() and timer_delete()
path. Annotate these places with READ_ONCE() and WRITE_ONCE()
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
---
kernel/time/posix-timers.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -109,9 +109,9 @@ static struct k_itimer *__posix_timers_f
{
struct k_itimer *timer;
- hlist_for_each_entry_rcu(timer, head, t_hash,
- lockdep_is_held(&hash_lock)) {
- if ((timer->it_signal == sig) && (timer->it_id == id))
+ hlist_for_each_entry_rcu(timer, head, t_hash, lockdep_is_held(&hash_lock)) {
+ /* timer->it_signal can be set concurrently */
+ if ((READ_ONCE(timer->it_signal) == sig) && (timer->it_id == id))
return timer;
}
return NULL;
@@ -557,7 +557,7 @@ static int do_timer_create(clockid_t whi
spin_lock_irq(¤t->sighand->siglock);
/* This makes the timer valid in the hash table */
- new_timer->it_signal = current->signal;
+ WRITE_ONCE(new_timer->it_signal, current->signal);
list_add(&new_timer->list, ¤t->signal->posix_timers);
spin_unlock_irq(¤t->sighand->siglock);
@@ -1051,10 +1051,10 @@ SYSCALL_DEFINE1(timer_delete, timer_t, t
list_del(&timer->list);
spin_unlock(¤t->sighand->siglock);
/*
- * This keeps any tasks waiting on the spin lock from thinking
- * they got something (see the lock code above).
+ * A concurrent lookup could check timer::it_signal lockless. It
+ * will reevaluate with timer::it_lock held and observe the NULL.
*/
- timer->it_signal = NULL;
+ WRITE_ONCE(timer->it_signal, NULL);
unlock_timer(timer, flags);
release_posix_timer(timer, IT_ID_SET);
Powered by blists - more mailing lists