lkml.org 
[lkml]   [2017]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[RFC patch 4/7] timekeeping: Add NMI safe accessor to mono/boot/real clocks
Clock MONOTONIC timestamps are not allowing reliable correlation to other
timestamps (clock REALTIME/BOOTTIME). For post mortem analysis and other
purposes its helpful to store all of these time stamps in the printk ring
buffer entries.

Rework __ktime_get_real_fast() so it captures both MONOTONIC and REALTIME
atomically and provide an accessor which stores these plus BOOTTIME in a
new system_timestamp data structure.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/timekeeping.h | 17 ++++++++++++++++-
kernel/time/timekeeping.c | 36 +++++++++++++++++++++++++-----------
2 files changed, 41 insertions(+), 12 deletions(-)

--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -146,7 +146,19 @@ extern void timekeeping_inject_sleeptime
* PPS accessor
*/
extern void ktime_get_raw_and_real_ts64(struct timespec64 *ts_raw,
- struct timespec64 *ts_real);
+ struct timespec64 *ts_real);
+
+/*
+ * struct system_timestamps - Simultaneous mono/boot/real timestamps
+ * @mono: Monotonic timestamp
+ * @boot: Boottime timestamp
+ * @real: Realtime timestamp
+ */
+struct system_timestamps {
+ u64 mono;
+ u64 boot;
+ u64 real;
+};

/*
* struct system_time_snapshot - simultaneous raw/real time capture with
@@ -206,6 +218,9 @@ extern int get_device_system_crosststamp
*/
extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot);

+/* NMI safe mono/boot/realtime timestamps */
+extern void ktime_get_fast_timestamps(struct system_timestamps *ts);
+
/*
* Persistent clock related interfaces
*/
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -496,29 +496,29 @@ u64 notrace ktime_get_boot_fast_ns(void)
}
EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns);

-
/*
* See comment for __ktime_get_fast_ns() vs. timestamp ordering
*/
-static __always_inline u64 __ktime_get_real_fast_ns(struct tk_fast *tkf)
+static notrace u64 __ktime_get_real_fast(struct tk_fast *tkf, u64 *mono)
{
struct tk_read_base *tkr;
+ u64 basem, baser, delta;
unsigned int seq;
- u64 now;

do {
seq = raw_read_seqcount_latch(&tkf->seq);
tkr = tkf->base + (seq & 0x01);
- now = ktime_to_ns(tkr->base_real);
+ basem = ktime_to_ns(tkr->base);
+ baser = ktime_to_ns(tkr->base_real);

- now += timekeeping_delta_to_ns(tkr,
- clocksource_delta(
- tk_clock_read(tkr),
- tkr->cycle_last,
- tkr->mask));
+ delta = timekeeping_delta_to_ns(tkr,
+ clocksource_delta(tk_clock_read(tkr),
+ tkr->cycle_last, tkr->mask));
} while (read_seqcount_retry(&tkf->seq, seq));

- return now;
+ if (mono)
+ *mono = basem + delta;
+ return baser + delta;
}

/**
@@ -526,11 +526,25 @@ static __always_inline u64 __ktime_get_r
*/
u64 ktime_get_real_fast_ns(void)
{
- return __ktime_get_real_fast_ns(&tk_fast_mono);
+ return __ktime_get_real_fast(&tk_fast_mono, NULL);
}
EXPORT_SYMBOL_GPL(ktime_get_real_fast_ns);

/**
+ * ktime_get_fast_timestamps: - NMI safe timestamps
+ * @ts: Pointer to timestamp storage
+ *
+ * Stores clock monotonic, boottime and realtime time stamps
+ */
+void ktime_get_fast_timestamps(struct system_timestamps *ts)
+{
+ struct timekeeper *tk = &tk_core.timekeeper;
+
+ ts->real = __ktime_get_real_fast(&tk_fast_mono, &ts->mono);
+ ts->boot = ts->mono + ktime_to_ns(tk->offs_boot);
+}
+
+/**
* halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource.
* @tk: Timekeeper to snapshot.
*

\
 
 \ /
  Last update: 2017-11-15 19:30    [W:0.177 / U:0.532 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site