[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250308155623.892762130@linutronix.de>
Date: Sat, 8 Mar 2025 17:48:28 +0100 (CET)
From: Thomas Gleixner <tglx@...utronix.de>
To: LKML <linux-kernel@...r.kernel.org>
Cc: Anna-Maria Behnsen <anna-maria@...utronix.de>,
Frederic Weisbecker <frederic@...nel.org>,
Benjamin Segall <bsegall@...gle.com>,
Eric Dumazet <edumazet@...gle.com>,
Andrey Vagin <avagin@...nvz.org>,
Pavel Tikhomirov <ptikhomirov@...tuozzo.com>,
Peter Zijlstra <peterz@...radead.org>,
Cyrill Gorcunov <gorcunov@...il.com>
Subject: [patch V3 07/18] posix-timers: Use guards in a few places
Switch locking and RCU to guards where applicable.
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
Reviewed-by: Frederic Weisbecker <frederic@...nel.org>
---
V2: New patch
---
kernel/time/posix-timers.c | 68 +++++++++++++++++++--------------------------
1 file changed, 30 insertions(+), 38 deletions(-)
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -397,9 +397,8 @@ void posixtimer_free_timer(struct k_itim
static void posix_timer_unhash_and_free(struct k_itimer *tmr)
{
- spin_lock(&hash_lock);
- hlist_del_rcu(&tmr->t_hash);
- spin_unlock(&hash_lock);
+ scoped_guard (spinlock, &hash_lock)
+ hlist_del_rcu(&tmr->t_hash);
posixtimer_putref(tmr);
}
@@ -443,9 +442,8 @@ static int do_timer_create(clockid_t whi
new_timer->it_overrun = -1LL;
if (event) {
- rcu_read_lock();
- new_timer->it_pid = get_pid(good_sigevent(event));
- rcu_read_unlock();
+ scoped_guard (rcu)
+ new_timer->it_pid = get_pid(good_sigevent(event));
if (!new_timer->it_pid) {
error = -EINVAL;
goto out;
@@ -579,7 +577,7 @@ static struct k_itimer *__lock_timer(tim
* can't change, but timr::it_signal becomes NULL during
* destruction.
*/
- rcu_read_lock();
+ guard(rcu)();
timr = posix_timer_by_id(timer_id);
if (timr) {
spin_lock_irqsave(&timr->it_lock, *flags);
@@ -587,14 +585,10 @@ static struct k_itimer *__lock_timer(tim
* Validate under timr::it_lock that timr::it_signal is
* still valid. Pairs with #1 above.
*/
- if (timr->it_signal == current->signal) {
- rcu_read_unlock();
+ if (timr->it_signal == current->signal)
return timr;
- }
spin_unlock_irqrestore(&timr->it_lock, *flags);
}
- rcu_read_unlock();
-
return NULL;
}
@@ -825,16 +819,15 @@ static struct k_itimer *timer_wait_runni
timer_t timer_id = READ_ONCE(timer->it_id);
/* Prevent kfree(timer) after dropping the lock */
- rcu_read_lock();
- unlock_timer(timer, *flags);
-
- /*
- * kc->timer_wait_running() might drop RCU lock. So @timer
- * cannot be touched anymore after the function returns!
- */
- timer->kclock->timer_wait_running(timer);
+ scoped_guard (rcu) {
+ unlock_timer(timer, *flags);
+ /*
+ * kc->timer_wait_running() might drop RCU lock. So @timer
+ * cannot be touched anymore after the function returns!
+ */
+ timer->kclock->timer_wait_running(timer);
+ }
- rcu_read_unlock();
/* Relock the timer. It might be not longer hashed. */
return lock_timer(timer_id, flags);
}
@@ -1020,20 +1013,20 @@ SYSCALL_DEFINE1(timer_delete, timer_t, t
goto retry_delete;
}
- spin_lock(¤t->sighand->siglock);
- hlist_del(&timer->list);
- posix_timer_cleanup_ignored(timer);
- /*
- * A concurrent lookup could check timer::it_signal lockless. It
- * will reevaluate with timer::it_lock held and observe the NULL.
- *
- * It must be written with siglock held so that the signal code
- * observes timer->it_signal == NULL in do_sigaction(SIG_IGN),
- * which prevents it from moving a pending signal of a deleted
- * timer to the ignore list.
- */
- WRITE_ONCE(timer->it_signal, NULL);
- spin_unlock(¤t->sighand->siglock);
+ scoped_guard (spinlock, ¤t->sighand->siglock) {
+ hlist_del(&timer->list);
+ posix_timer_cleanup_ignored(timer);
+ /*
+ * A concurrent lookup could check timer::it_signal lockless. It
+ * will reevaluate with timer::it_lock held and observe the NULL.
+ *
+ * It must be written with siglock held so that the signal code
+ * observes timer->it_signal == NULL in do_sigaction(SIG_IGN),
+ * which prevents it from moving a pending signal of a deleted
+ * timer to the ignore list.
+ */
+ WRITE_ONCE(timer->it_signal, NULL);
+ }
unlock_timer(timer, flags);
posix_timer_unhash_and_free(timer);
@@ -1106,9 +1099,8 @@ void exit_itimers(struct task_struct *ts
return;
/* Protect against concurrent read via /proc/$PID/timers */
- spin_lock_irq(&tsk->sighand->siglock);
- hlist_move_list(&tsk->signal->posix_timers, &timers);
- spin_unlock_irq(&tsk->sighand->siglock);
+ scoped_guard (spinlock_irq, &tsk->sighand->siglock)
+ hlist_move_list(&tsk->signal->posix_timers, &timers);
/* The timers are not longer accessible via tsk::signal */
while (!hlist_empty(&timers)) {
Powered by blists - more mailing lists