From: "tip-bot2 for Thomas Gleixner" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: syzbot+aa7c2385d46c5eba0b89@syzkaller.appspotmail.com,
syzbot+abea4558531bae1ba9fe@syzkaller.appspotmail.com,
Thomas Gleixner <tglx@linutronix.de>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
stable@vger.kernel.org, x86@kernel.org,
linux-kernel@vger.kernel.org
Subject: [tip: timers/urgent] timers: Move clearing of base::timer_running under base:: Lock
Date: Tue, 27 Jul 2021 19:00:29 -0000 [thread overview]
Message-ID: <162741242945.395.1178547166318427399.tip-bot2@tip-bot2> (raw)
In-Reply-To: <87lfea7gw8.fsf@nanos.tec.linutronix.de>
The following commit has been merged into the timers/urgent branch of tip:
Commit-ID: bb7262b295472eb6858b5c49893954794027cd84
Gitweb: https://git.kernel.org/tip/bb7262b295472eb6858b5c49893954794027cd84
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 06 Dec 2020 22:40:07 +01:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Tue, 27 Jul 2021 20:57:44 +02:00
timers: Move clearing of base::timer_running under base:: Lock
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
Frederic identified an issue which is:
int data = 0;
void timer_func(struct timer_list *t)
{
data = 1;
}
CPU 0 CPU 1
------------------------------ --------------------------
base = lock_timer_base(timer, &flags); raw_spin_unlock(&base->lock);
if (base->running_timer != timer) call_timer_fn(timer, fn, baseclk);
ret = detach_if_pending(timer, base, true); base->running_timer = NULL;
raw_spin_unlock_irqrestore(&base->lock, flags); raw_spin_lock(&base->lock);
x = data;
If the timer has previously executed on CPU 1 and then CPU 0 can observe
base->running_timer == NULL and returns, assuming the timer has completed,
but it's not guaranteed on all architectures. The comment for
del_timer_sync() makes that guarantee. Moving the assignment under
base->lock prevents this.
For non-RT kernel it's performance wise 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.
Reported-by: syzbot+aa7c2385d46c5eba0b89@syzkaller.appspotmail.com
Reported-by: syzbot+abea4558531bae1ba9fe@syzkaller.appspotmail.com
Fixes: 030dcdd197d7 ("timers: Prepare support for PREEMPT_RT")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/87lfea7gw8.fsf@nanos.tec.linutronix.de
Cc: stable@vger.kernel.org
---
kernel/time/timer.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 9eb11c2..e3d2c23 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1265,8 +1265,10 @@ static inline void timer_base_unlock_expiry(struct timer_base *base)
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);
}
}
@@ -1457,14 +1459,14 @@ static void expire_timers(struct timer_base *base, struct hlist_head *head)
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);
}
}
}
prev parent reply other threads:[~2021-07-27 19:00 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
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-bot2 for Thomas Gleixner [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=162741242945.395.1178547166318427399.tip-bot2@tip-bot2 \
--to=tip-bot2@linutronix.de \
--cc=bigeasy@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=syzbot+aa7c2385d46c5eba0b89@syzkaller.appspotmail.com \
--cc=syzbot+abea4558531bae1ba9fe@syzkaller.appspotmail.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.