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

time: Add timekeeping snapshot code capturing system time and counter

In the current timekeeping code there isn't any interface to
atomically capture the current relationship between the system counter
and system time. ktime_get_snapshot() returns this triple (counter,
monotonic raw, realtime) in the system_time_snapshot struct.

Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: kevin.b.stanton@intel.com
Cc: kevin.j.clarke@intel.com
Cc: hpa@zytor.com
Cc: jeffrey.t.kirsher@intel.com
Cc: netdev@vger.kernel.org
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Christopher S. Hall <christopher.s.hall@intel.com>
[jstultz: Moved structure definitions around to clean things up,
fixed cycles_t/cycle_t confusion.]
Signed-off-by: John Stultz <john.stultz@linaro.org>

authored by

Christopher S. Hall and committed by
John Stultz
9da0f49c 6bd58f09

+48
+18
include/linux/timekeeping.h
··· 267 267 struct timespec64 *ts_real); 268 268 269 269 /* 270 + * struct system_time_snapshot - simultaneous raw/real time capture with 271 + * counter value 272 + * @cycles: Clocksource counter value to produce the system times 273 + * @real: Realtime system time 274 + * @raw: Monotonic raw system time 275 + */ 276 + struct system_time_snapshot { 277 + cycle_t cycles; 278 + ktime_t real; 279 + ktime_t raw; 280 + }; 281 + 282 + /* 283 + * Simultaneously snapshot realtime and monotonic raw clocks 284 + */ 285 + extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot); 286 + 287 + /* 270 288 * Persistent clock related interfaces 271 289 */ 272 290 extern int persistent_clock_is_local;
+30
kernel/time/timekeeping.c
··· 874 874 return tk->xtime_sec; 875 875 } 876 876 877 + /** 878 + * ktime_get_snapshot - snapshots the realtime/monotonic raw clocks with counter 879 + * @systime_snapshot: pointer to struct receiving the system time snapshot 880 + */ 881 + void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot) 882 + { 883 + struct timekeeper *tk = &tk_core.timekeeper; 884 + unsigned long seq; 885 + ktime_t base_raw; 886 + ktime_t base_real; 887 + s64 nsec_raw; 888 + s64 nsec_real; 889 + cycle_t now; 890 + 891 + do { 892 + seq = read_seqcount_begin(&tk_core.seq); 893 + 894 + now = tk->tkr_mono.read(tk->tkr_mono.clock); 895 + base_real = ktime_add(tk->tkr_mono.base, 896 + tk_core.timekeeper.offs_real); 897 + base_raw = tk->tkr_raw.base; 898 + nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono, now); 899 + nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw, now); 900 + } while (read_seqcount_retry(&tk_core.seq, seq)); 901 + 902 + systime_snapshot->cycles = now; 903 + systime_snapshot->real = ktime_add_ns(base_real, nsec_real); 904 + systime_snapshot->raw = ktime_add_ns(base_raw, nsec_raw); 905 + } 906 + EXPORT_SYMBOL_GPL(ktime_get_snapshot); 877 907 878 908 #ifdef CONFIG_NTP_PPS 879 909