]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
posix-timers: Expand timer_[re]arm() callbacks with a boolean return value
authorThomas Gleixner <tglx@kernel.org>
Wed, 8 Apr 2026 11:53:56 +0000 (13:53 +0200)
committerThomas Gleixner <tglx@kernel.org>
Fri, 1 May 2026 19:36:11 +0000 (21:36 +0200)
In order to catch expiry times which are already in the past the
timer_arm() and timer_rearm() callbacks need to be able to report back to
the caller whether the timer has been queued or not.

Change the function signature and let all implementations return true for
now. While at it simplify posix_cpu_timer_rearm().

No functional change intended.

Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: John Stultz <jstultz@google.com>
Link: https://patch.msgid.link/20260408114952.130222296@kernel.org
kernel/time/alarmtimer.c
kernel/time/posix-cpu-timers.c
kernel/time/posix-timers.c
kernel/time/posix-timers.h

index 6e173d70d82592ff2d3208698e3073846debd670..e10021be190fd3941370a226a8a7a2372cae4c33 100644 (file)
@@ -527,12 +527,13 @@ static void alarm_handle_timer(struct alarm *alarm, ktime_t now)
  * alarm_timer_rearm - Posix timer callback for rearming timer
  * @timr:      Pointer to the posixtimer data struct
  */
-static void alarm_timer_rearm(struct k_itimer *timr)
+static bool alarm_timer_rearm(struct k_itimer *timr)
 {
        struct alarm *alarm = &timr->it.alarm.alarmtimer;
 
        timr->it_overrun += alarm_forward_now(alarm, timr->it_interval);
        alarm_start(alarm, alarm->node.expires);
+       return true;
 }
 
 /**
@@ -588,7 +589,7 @@ static void alarm_timer_wait_running(struct k_itimer *timr)
  * @absolute:  Expiry value is absolute time
  * @sigev_none:        Posix timer does not deliver signals
  */
-static void alarm_timer_arm(struct k_itimer *timr, ktime_t expires,
+static bool alarm_timer_arm(struct k_itimer *timr, ktime_t expires,
                            bool absolute, bool sigev_none)
 {
        struct alarm *alarm = &timr->it.alarm.alarmtimer;
@@ -600,6 +601,7 @@ static void alarm_timer_arm(struct k_itimer *timr, ktime_t expires,
                alarm->node.expires = expires;
        else
                alarm_start(&timr->it.alarm.alarmtimer, expires);
+       return true;
 }
 
 /**
index 0de2bb7cbec01c423fc98e78c5a0aeb5c910381d..395e297093f89e1bf0d88b3b3fa1979f0d5f31ad 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "posix-timers.h"
 
-static void posix_cpu_timer_rearm(struct k_itimer *timer);
+static bool posix_cpu_timer_rearm(struct k_itimer *timer);
 
 void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit)
 {
@@ -1011,24 +1011,27 @@ static void check_process_timers(struct task_struct *tsk,
 /*
  * This is called from the signal code (via posixtimer_rearm)
  * when the last timer signal was delivered and we have to reload the timer.
+ *
+ * Return true unconditionally so the core code assumes the timer to be
+ * armed. Otherwise it would requeue the signal.
  */
-static void posix_cpu_timer_rearm(struct k_itimer *timer)
+static bool posix_cpu_timer_rearm(struct k_itimer *timer)
 {
        clockid_t clkid = CPUCLOCK_WHICH(timer->it_clock);
-       struct task_struct *p;
        struct sighand_struct *sighand;
+       struct task_struct *p;
        unsigned long flags;
        u64 now;
 
-       rcu_read_lock();
+       guard(rcu)();
        p = cpu_timer_task_rcu(timer);
        if (!p)
-               goto out;
+               return true;
 
        /* Protect timer list r/w in arm_timer() */
        sighand = lock_task_sighand(p, &flags);
        if (unlikely(sighand == NULL))
-               goto out;
+               return true;
 
        /*
         * Fetch the current sample and update the timer's expiry time.
@@ -1045,8 +1048,7 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer)
         */
        arm_timer(timer, p);
        unlock_task_sighand(p, &flags);
-out:
-       rcu_read_unlock();
+       return true;
 }
 
 /**
index 9331e1614124693dda2332f51ab7458310e1d226..da04ed42bf82452346566e152b8b51a51e2b2cd5 100644 (file)
@@ -288,12 +288,13 @@ static inline int timer_overrun_to_int(struct k_itimer *timr)
        return (int)timr->it_overrun_last;
 }
 
-static void common_hrtimer_rearm(struct k_itimer *timr)
+static bool common_hrtimer_rearm(struct k_itimer *timr)
 {
        struct hrtimer *timer = &timr->it.real.timer;
 
        timr->it_overrun += hrtimer_forward_now(timer, timr->it_interval);
        hrtimer_restart(timer);
+       return true;
 }
 
 static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struct k_itimer *timr)
@@ -795,7 +796,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
                return timer_overrun_to_int(scoped_timer);
 }
 
-static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires,
+static bool common_hrtimer_arm(struct k_itimer *timr, ktime_t expires,
                               bool absolute, bool sigev_none)
 {
        struct hrtimer *timer = &timr->it.real.timer;
@@ -822,6 +823,7 @@ static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires,
 
        if (!sigev_none)
                hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
+       return true;
 }
 
 static int common_hrtimer_try_to_cancel(struct k_itimer *timr)
index 7f259e845d240c139a3ae507fd388eeff9e857e1..4ea9611dd7165c5fce83cc3f87c58d9b9eb5edc0 100644 (file)
@@ -27,11 +27,11 @@ struct k_clock {
        int     (*timer_del)(struct k_itimer *timr);
        void    (*timer_get)(struct k_itimer *timr,
                             struct itimerspec64 *cur_setting);
-       void    (*timer_rearm)(struct k_itimer *timr);
+       bool    (*timer_rearm)(struct k_itimer *timr);
        s64     (*timer_forward)(struct k_itimer *timr, ktime_t now);
        ktime_t (*timer_remaining)(struct k_itimer *timr, ktime_t now);
        int     (*timer_try_to_cancel)(struct k_itimer *timr);
-       void    (*timer_arm)(struct k_itimer *timr, ktime_t expires,
+       bool    (*timer_arm)(struct k_itimer *timr, ktime_t expires,
                             bool absolute, bool sigev_none);
        void    (*timer_wait_running)(struct k_itimer *timr);
 };