timers: Make sure TIMER_PINNED flag is set in add_timer_on()
authorAnna-Maria Behnsen <anna-maria@linutronix.de>
Wed, 21 Feb 2024 09:05:35 +0000 (10:05 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 22 Feb 2024 16:52:31 +0000 (17:52 +0100)
When adding a timer to the timer wheel using add_timer_on(), it is an
implicitly pinned timer. With the timer pull at expiry time model in place,
the TIMER_PINNED flag is required to make sure timers end up in proper
base.

Set the TIMER_PINNED flag unconditionally when add_timer_on() is executed.

Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/r/20240221090548.36600-8-anna-maria@linutronix.de
kernel/time/timer.c

index bef8cb8e72661eb0953068eb476b17209dbb7607..121f5b99ea213f30bca7c2f732d7ac00fd56ab72 100644 (file)
@@ -1329,7 +1329,10 @@ EXPORT_SYMBOL(add_timer_global);
  * @timer:     The timer to be started
  * @cpu:       The CPU to start it on
  *
- * Same as add_timer() except that it starts the timer on the given CPU.
+ * Same as add_timer() except that it starts the timer on the given CPU and
+ * the TIMER_PINNED flag is set. When timer shouldn't be a pinned timer in
+ * the next round, add_timer_global() should be used instead as it unsets
+ * the TIMER_PINNED flag.
  *
  * See add_timer() for further details.
  */
@@ -1343,6 +1346,9 @@ void add_timer_on(struct timer_list *timer, int cpu)
        if (WARN_ON_ONCE(timer_pending(timer)))
                return;
 
+       /* Make sure timer flags have TIMER_PINNED flag set */
+       timer->flags |= TIMER_PINNED;
+
        new_base = get_timer_cpu_base(timer->flags, cpu);
 
        /*