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: Provide time setter for auxiliary clocks

Add clock_settime(2) support for auxiliary clocks. The function affects the
AUX offset which is added to the "monotonic" clock readout of these clocks.

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

+44
+44
kernel/time/timekeeping.c
··· 2765 2765 return ktime_get_aux_ts64(id, tp) ? 0 : -ENODEV; 2766 2766 } 2767 2767 2768 + static int aux_clock_set(const clockid_t id, const struct timespec64 *tnew) 2769 + { 2770 + struct tk_data *aux_tkd = aux_get_tk_data(id); 2771 + struct timekeeper *aux_tks; 2772 + ktime_t tnow, nsecs; 2773 + 2774 + if (!timespec64_valid_settod(tnew)) 2775 + return -EINVAL; 2776 + if (!aux_tkd) 2777 + return -ENODEV; 2778 + 2779 + aux_tks = &aux_tkd->shadow_timekeeper; 2780 + 2781 + guard(raw_spinlock_irq)(&aux_tkd->lock); 2782 + if (!aux_tks->clock_valid) 2783 + return -ENODEV; 2784 + 2785 + /* Forward the timekeeper base time */ 2786 + timekeeping_forward_now(aux_tks); 2787 + /* 2788 + * Get the updated base time. tkr_mono.base has not been 2789 + * updated yet, so do that first. That makes the update 2790 + * in timekeeping_update_from_shadow() redundant, but 2791 + * that's harmless. After that @tnow can be calculated 2792 + * by using tkr_mono::cycle_last, which has been set 2793 + * by timekeeping_forward_now(). 2794 + */ 2795 + tk_update_ktime_data(aux_tks); 2796 + nsecs = timekeeping_cycles_to_ns(&aux_tks->tkr_mono, aux_tks->tkr_mono.cycle_last); 2797 + tnow = ktime_add(aux_tks->tkr_mono.base, nsecs); 2798 + 2799 + /* 2800 + * Calculate the new AUX offset as delta to @tnow ("monotonic"). 2801 + * That avoids all the tk::xtime back and forth conversions as 2802 + * xtime ("realtime") is not applicable for auxiliary clocks and 2803 + * kept in sync with "monotonic". 2804 + */ 2805 + aux_tks->offs_aux = ktime_sub(timespec64_to_ktime(*tnew), tnow); 2806 + 2807 + timekeeping_update_from_shadow(aux_tkd, TK_UPDATE_ALL); 2808 + return 0; 2809 + } 2810 + 2768 2811 const struct k_clock clock_aux = { 2769 2812 .clock_getres = aux_get_res, 2770 2813 .clock_get_timespec = aux_get_timespec, 2814 + .clock_set = aux_clock_set, 2771 2815 }; 2772 2816 2773 2817 static __init void tk_aux_setup(void)