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

timekeeping: Introduce fast accessor to clock tai

Introduce fast/NMI safe accessor to clock tai for tracing. The Linux kernel
tracing infrastructure has support for using different clocks to generate
timestamps for trace events. Especially in TSN networks it's useful to have TAI
as trace clock, because the application scheduling is done in accordance to the
network time, which is based on TAI. With a tai trace_clock in place, it becomes
very convenient to correlate network activity with Linux kernel application
traces.

Use the same implementation as ktime_get_boot_fast_ns() does by reading the
monotonic time and adding the TAI offset. The same limitations as for the fast
boot implementation apply. The TAI offset may change at run time e.g., by
setting the time or using adjtimex() with an offset. However, these kind of
offset changes are rare events. Nevertheless, the user has to be aware and deal
with it in post processing.

An alternative approach would be to use the same implementation as
ktime_get_real_fast_ns() does. However, this requires to add an additional u64
member to the tk_read_base struct. This struct together with a seqcount is
designed to fit into a single cache line on 64 bit architectures. Adding a new
member would violate this constraint.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: https://lore.kernel.org/r/20220414091805.89667-2-kurt@linutronix.de

authored by

Kurt Kanzenbach and committed by
Thomas Gleixner
3dc6ffae ce522ba9

+19
+1
Documentation/core-api/timekeeping.rst
··· 132 132 .. c:function:: u64 ktime_get_mono_fast_ns( void ) 133 133 u64 ktime_get_raw_fast_ns( void ) 134 134 u64 ktime_get_boot_fast_ns( void ) 135 + u64 ktime_get_tai_fast_ns( void ) 135 136 u64 ktime_get_real_fast_ns( void ) 136 137 137 138 These variants are safe to call from any context, including from
+1
include/linux/timekeeping.h
··· 177 177 extern u64 ktime_get_mono_fast_ns(void); 178 178 extern u64 ktime_get_raw_fast_ns(void); 179 179 extern u64 ktime_get_boot_fast_ns(void); 180 + extern u64 ktime_get_tai_fast_ns(void); 180 181 extern u64 ktime_get_real_fast_ns(void); 181 182 182 183 /*
+17
kernel/time/timekeeping.c
··· 532 532 } 533 533 EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns); 534 534 535 + /** 536 + * ktime_get_tai_fast_ns - NMI safe and fast access to tai clock. 537 + * 538 + * The same limitations as described for ktime_get_boot_fast_ns() apply. The 539 + * mono time and the TAI offset are not read atomically which may yield wrong 540 + * readouts. However, an update of the TAI offset is an rare event e.g., caused 541 + * by settime or adjtimex with an offset. The user of this function has to deal 542 + * with the possibility of wrong timestamps in post processing. 543 + */ 544 + u64 notrace ktime_get_tai_fast_ns(void) 545 + { 546 + struct timekeeper *tk = &tk_core.timekeeper; 547 + 548 + return (ktime_get_mono_fast_ns() + ktime_to_ns(data_race(tk->offs_tai))); 549 + } 550 + EXPORT_SYMBOL_GPL(ktime_get_tai_fast_ns); 551 + 535 552 static __always_inline u64 __ktime_get_real_fast(struct tk_fast *tkf, u64 *mono) 536 553 { 537 554 struct tk_read_base *tkr;