All of lore.kernel.org
 help / color / mirror / Atom feed
* timers: Move clearing of base::timer_running under base::lock
@ 2020-12-06 21:40 Thomas Gleixner
  2020-12-07  1:10 ` Frederic Weisbecker
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Thomas Gleixner @ 2020-12-06 21:40 UTC (permalink / raw)
  To: LKML
  Cc: Marco Elver, kasan-dev, Peter Zijlstra, Paul E. McKenney,
	Anna-Maria Behnsen, Sebastian Andrzej Siewior

syzbot reported KCSAN data races vs. timer_base::timer_running being set to
NULL without holding base::lock in expire_timers().

This looks innocent and most reads are clearly not problematic but for a
non-RT kernel it's completely irrelevant whether the store happens before
or after taking the lock. For an RT kernel moving the store under the lock
requires an extra unlock/lock pair in the case that there is a waiter for
the timer. But that's not the end of the world and definitely not worth the
trouble of adding boatloads of comments and annotations to the code. Famous
last words...

Reported-by: syzbot+aa7c2385d46c5eba0b89@syzkaller.appspotmail.com
Reported-by: syzbot+abea4558531bae1ba9fe@syzkaller.appspotmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/timer.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1263,8 +1263,10 @@ static inline void timer_base_unlock_exp
 static void timer_sync_wait_running(struct timer_base *base)
 {
 	if (atomic_read(&base->timer_waiters)) {
+		raw_spin_unlock_irq(&base->lock);
 		spin_unlock(&base->expiry_lock);
 		spin_lock(&base->expiry_lock);
+		raw_spin_lock_irq(&base->lock);
 	}
 }
 
@@ -1448,14 +1450,14 @@ static void expire_timers(struct timer_b
 		if (timer->flags & TIMER_IRQSAFE) {
 			raw_spin_unlock(&base->lock);
 			call_timer_fn(timer, fn, baseclk);
-			base->running_timer = NULL;
 			raw_spin_lock(&base->lock);
+			base->running_timer = NULL;
 		} else {
 			raw_spin_unlock_irq(&base->lock);
 			call_timer_fn(timer, fn, baseclk);
+			raw_spin_lock_irq(&base->lock);
 			base->running_timer = NULL;
 			timer_sync_wait_running(base);
-			raw_spin_lock_irq(&base->lock);
 		}
 	}
 }

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

end of thread, other threads:[~2021-07-27 19:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-06 21:40 timers: Move clearing of base::timer_running under base::lock Thomas Gleixner
2020-12-07  1:10 ` Frederic Weisbecker
2020-12-07 12:25   ` Peter Zijlstra
2020-12-07 12:49     ` Frederic Weisbecker
2020-12-07 13:07 ` Sebastian Andrzej Siewior
2020-12-07 14:29   ` Thomas Gleixner
2020-12-07 15:25     ` Sebastian Andrzej Siewior
2020-12-07 16:06       ` Paul E. McKenney
2020-12-08  8:50         ` Sebastian Andrzej Siewior
2020-12-08 15:04           ` Paul E. McKenney
2020-12-11 14:36           ` Thomas Gleixner
2020-12-11 15:04             ` Sebastian Andrzej Siewior
2021-07-27 19:00 ` [tip: timers/urgent] timers: Move clearing of base::timer_running under base:: Lock tip-bot2 for Thomas Gleixner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.