Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

timekeeping: Update auxiliary timekeepers on clocksource change

Propagate a system clocksource change to the auxiliary timekeepers so that
they can pick up the new clocksource.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: John Stultz <jstultz@google.com>
Link: https://lore.kernel.org/all/20250625183757.803890875@linutronix.de

+33
+33
kernel/time/timekeeping.c
··· 119 119 120 120 #ifdef CONFIG_POSIX_AUX_CLOCKS 121 121 static __init void tk_aux_setup(void); 122 + static void tk_aux_update_clocksource(void); 122 123 #else 123 124 static inline void tk_aux_setup(void) { } 125 + static inline void tk_aux_update_clocksource(void) { } 124 126 #endif 125 127 126 128 unsigned long timekeeper_lock_irqsave(void) ··· 1550 1548 timekeeping_update_from_shadow(&tk_core, TK_UPDATE_ALL); 1551 1549 } 1552 1550 1551 + tk_aux_update_clocksource(); 1552 + 1553 1553 if (old) { 1554 1554 if (old->disable) 1555 1555 old->disable(old); ··· 2655 2651 #endif /* CONFIG_NTP_PPS */ 2656 2652 2657 2653 #ifdef CONFIG_POSIX_AUX_CLOCKS 2654 + 2655 + /* 2656 + * Bitmap for the activated auxiliary timekeepers to allow lockless quick 2657 + * checks in the hot paths without touching extra cache lines. If set, then 2658 + * the state of the corresponding timekeeper has to be re-checked under 2659 + * timekeeper::lock. 2660 + */ 2661 + static unsigned long aux_timekeepers; 2662 + 2663 + /* Invoked from timekeeping after a clocksource change */ 2664 + static void tk_aux_update_clocksource(void) 2665 + { 2666 + unsigned long active = READ_ONCE(aux_timekeepers); 2667 + unsigned int id; 2668 + 2669 + for_each_set_bit(id, &active, BITS_PER_LONG) { 2670 + struct tk_data *tkd = &timekeeper_data[id + TIMEKEEPER_AUX_FIRST]; 2671 + struct timekeeper *tks = &tkd->shadow_timekeeper; 2672 + 2673 + guard(raw_spinlock_irqsave)(&tkd->lock); 2674 + if (!tks->clock_valid) 2675 + continue; 2676 + 2677 + timekeeping_forward_now(tks); 2678 + tk_setup_internals(tks, tk_core.timekeeper.tkr_mono.clock); 2679 + timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL); 2680 + } 2681 + } 2682 + 2658 2683 static __init void tk_aux_setup(void) 2659 2684 { 2660 2685 for (int i = TIMEKEEPER_AUX_FIRST; i <= TIMEKEEPER_AUX_LAST; i++)