]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
timekeeping: Abort clocksource change in case of failure
authorThomas Gleixner <tglx@linutronix.de>
Wed, 9 Oct 2024 08:28:57 +0000 (10:28 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 25 Oct 2024 17:49:13 +0000 (19:49 +0200)
There is no point to go through a full timekeeping update when acquiring a
module reference or enabling the new clocksource fails.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: John Stultz <jstultz@google.com>
Link: https://lore.kernel.org/all/20241009-devel-anna-maria-b4-timers-ptp-timekeeping-v2-4-554456a44a15@linutronix.de
kernel/time/timekeeping.c

index 14aaa44104ebd5a172bfc5d1ebdba38621b91a94..a9550f6a7f12ca32b04ca076db6ee279c6910ffd 100644 (file)
@@ -1608,33 +1608,29 @@ static void __timekeeping_set_tai_offset(struct timekeeper *tk, s32 tai_offset)
 static int change_clocksource(void *data)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
-       struct clocksource *new, *old = NULL;
+       struct clocksource *new = data, *old = NULL;
        unsigned long flags;
-       bool change = false;
-
-       new = (struct clocksource *) data;
 
        /*
-        * If the cs is in module, get a module reference. Succeeds
-        * for built-in code (owner == NULL) as well.
+        * If the clocksource is in a module, get a module reference.
+        * Succeeds for built-in code (owner == NULL) as well. Abort if the
+        * reference can't be acquired.
         */
-       if (try_module_get(new->owner)) {
-               if (!new->enable || new->enable(new) == 0)
-                       change = true;
-               else
-                       module_put(new->owner);
+       if (!try_module_get(new->owner))
+               return 0;
+
+       /* Abort if the device can't be enabled */
+       if (new->enable && new->enable(new) != 0) {
+               module_put(new->owner);
+               return 0;
        }
 
        raw_spin_lock_irqsave(&timekeeper_lock, flags);
        write_seqcount_begin(&tk_core.seq);
 
        timekeeping_forward_now(tk);
-
-       if (change) {
-               old = tk->tkr_mono.clock;
-               tk_setup_internals(tk, new);
-       }
-
+       old = tk->tkr_mono.clock;
+       tk_setup_internals(tk, new);
        timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
 
        write_seqcount_end(&tk_core.seq);
@@ -1643,7 +1639,6 @@ static int change_clocksource(void *data)
        if (old) {
                if (old->disable)
                        old->disable(old);
-
                module_put(old->owner);
        }