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 getters for auxiliary clocks

Provide interfaces similar to the ktime_get*() family which provide access
to the auxiliary clocks.

These interfaces have a boolean return value, which indicates whether the
accessed clock is valid or not.

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

+81
+5
include/linux/posix-timers.h
··· 37 37 return ~(clk >> 3); 38 38 } 39 39 40 + static inline bool clockid_aux_valid(clockid_t id) 41 + { 42 + return IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS) && id >= CLOCK_AUX && id <= CLOCK_AUX_LAST; 43 + } 44 + 40 45 #ifdef CONFIG_POSIX_TIMERS 41 46 42 47 #include <linux/signal_types.h>
+11
include/linux/timekeeping.h
··· 263 263 264 264 extern void timekeeping_inject_sleeptime64(const struct timespec64 *delta); 265 265 266 + /* 267 + * Auxiliary clock interfaces 268 + */ 269 + #ifdef CONFIG_POSIX_AUX_CLOCKS 270 + extern bool ktime_get_aux(clockid_t id, ktime_t *kt); 271 + extern bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt); 272 + #else 273 + static inline bool ktime_get_aux(clockid_t id, ktime_t *kt) { return false; } 274 + static inline bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt) { return false; } 275 + #endif 276 + 266 277 /** 267 278 * struct system_time_snapshot - simultaneous raw/real time capture with 268 279 * counter value
+65
kernel/time/timekeeping.c
··· 2664 2664 */ 2665 2665 static unsigned long aux_timekeepers; 2666 2666 2667 + static inline unsigned int clockid_to_tkid(unsigned int id) 2668 + { 2669 + return TIMEKEEPER_AUX_FIRST + id - CLOCK_AUX; 2670 + } 2671 + 2672 + static inline struct tk_data *aux_get_tk_data(clockid_t id) 2673 + { 2674 + if (!clockid_aux_valid(id)) 2675 + return NULL; 2676 + return &timekeeper_data[clockid_to_tkid(id)]; 2677 + } 2678 + 2667 2679 /* Invoked from timekeeping after a clocksource change */ 2668 2680 static void tk_aux_update_clocksource(void) 2669 2681 { ··· 2695 2683 timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL); 2696 2684 } 2697 2685 } 2686 + 2687 + /** 2688 + * ktime_get_aux - Get time for a AUX clock 2689 + * @id: ID of the clock to read (CLOCK_AUX...) 2690 + * @kt: Pointer to ktime_t to store the time stamp 2691 + * 2692 + * Returns: True if the timestamp is valid, false otherwise 2693 + */ 2694 + bool ktime_get_aux(clockid_t id, ktime_t *kt) 2695 + { 2696 + struct tk_data *aux_tkd = aux_get_tk_data(id); 2697 + struct timekeeper *aux_tk; 2698 + unsigned int seq; 2699 + ktime_t base; 2700 + u64 nsecs; 2701 + 2702 + WARN_ON(timekeeping_suspended); 2703 + 2704 + if (!aux_tkd) 2705 + return false; 2706 + 2707 + aux_tk = &aux_tkd->timekeeper; 2708 + do { 2709 + seq = read_seqcount_begin(&aux_tkd->seq); 2710 + if (!aux_tk->clock_valid) 2711 + return false; 2712 + 2713 + base = ktime_add(aux_tk->tkr_mono.base, aux_tk->offs_aux); 2714 + nsecs = timekeeping_get_ns(&aux_tk->tkr_mono); 2715 + } while (read_seqcount_retry(&aux_tkd->seq, seq)); 2716 + 2717 + *kt = ktime_add_ns(base, nsecs); 2718 + return true; 2719 + } 2720 + EXPORT_SYMBOL_GPL(ktime_get_aux); 2721 + 2722 + /** 2723 + * ktime_get_aux_ts64 - Get time for a AUX clock 2724 + * @id: ID of the clock to read (CLOCK_AUX...) 2725 + * @ts: Pointer to timespec64 to store the time stamp 2726 + * 2727 + * Returns: True if the timestamp is valid, false otherwise 2728 + */ 2729 + bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *ts) 2730 + { 2731 + ktime_t now; 2732 + 2733 + if (!ktime_get_aux(id, &now)) 2734 + return false; 2735 + *ts = ktime_to_timespec64(now); 2736 + return true; 2737 + } 2738 + EXPORT_SYMBOL_GPL(ktime_get_aux_ts64); 2698 2739 2699 2740 static __init void tk_aux_setup(void) 2700 2741 {