aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher S. Hall <christopher.s.hall@intel.com>2016-02-22 06:15:20 -0500
committerJohn Stultz <john.stultz@linaro.org>2016-03-02 20:12:50 -0500
commit9da0f49c8767cc0ef6101cb21156cf4380ed50dd (patch)
tree7dd2fd5c04980c3ffa520161975ee94169a3ee9e
parent6bd58f09e1d8cc6c50a824c00bf0d617919986a1 (diff)
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>
-rw-r--r--include/linux/timekeeping.h18
-rw-r--r--kernel/time/timekeeping.c30
2 files changed, 48 insertions, 0 deletions
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index ec89d846324c..7817591af46f 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -267,6 +267,24 @@ extern void ktime_get_raw_and_real_ts64(struct timespec64 *ts_raw,
267 struct timespec64 *ts_real); 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 */
276struct 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 */
285extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot);
286
287/*
270 * Persistent clock related interfaces 288 * Persistent clock related interfaces
271 */ 289 */
272extern int persistent_clock_is_local; 290extern int persistent_clock_is_local;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 4243d28177ac..89b4695bd083 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -874,6 +874,36 @@ time64_t __ktime_get_real_seconds(void)
874 return tk->xtime_sec; 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 */
881void 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}
906EXPORT_SYMBOL_GPL(ktime_get_snapshot);
877 907
878#ifdef CONFIG_NTP_PPS 908#ifdef CONFIG_NTP_PPS
879 909