For demonstration purposes only. Add a disgusting hack to work around the fact that high resolution clock MONOTONIC accessors are not available during early boot and return stale time stamps accross suspend/resume when the current clocksource is not flagged with CLOCK_SOURCE_SUSPEND_ACCESS_OK. Use local_clock() to provide timestamps in early boot and when the clocksource is not accessible after timekeeping_suspend(). In the suspend/resume case this might cause non monotonic timestamps. Not-Signed-off-by: Thomas Gleixner --- kernel/time/timekeeping.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -499,17 +500,19 @@ EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns /* * See comment for __ktime_get_fast_ns() vs. timestamp ordering */ -static notrace u64 __ktime_get_real_fast(struct tk_fast *tkf, u64 *mono) +static bool __ktime_get_real_fast(struct tk_fast *tkf, u64 *real, u64 *mono) { struct tk_read_base *tkr; u64 basem, baser, delta; unsigned int seq; + bool hres; do { seq = raw_read_seqcount_latch(&tkf->seq); tkr = tkf->base + (seq & 0x01); basem = ktime_to_ns(tkr->base); baser = ktime_to_ns(tkr->base_real); + hres = tkr->clock->flags & CLOCK_SOURCE_VALID_FOR_HRES; delta = timekeeping_delta_to_ns(tkr, clocksource_delta(tk_clock_read(tkr), @@ -518,15 +521,23 @@ static notrace u64 __ktime_get_real_fast if (mono) *mono = basem + delta; - return baser + delta; + *real = baser + delta; + return hres; } /** * ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime. + * + * Returns the wall clock (UTC) timestamp. Caveats: + * - Returns 0 before timekeeping is initialized + * - Returns a stale value accross suspend/resume */ u64 ktime_get_real_fast_ns(void) { - return __ktime_get_real_fast(&tk_fast_mono, NULL); + u64 real; + + __ktime_get_real_fast(&tk_fast_mono, &real, NULL); + return real; } EXPORT_SYMBOL_GPL(ktime_get_real_fast_ns); @@ -535,13 +546,19 @@ EXPORT_SYMBOL_GPL(ktime_get_real_fast_ns * @ts: Pointer to timestamp storage * * Stores clock monotonic, boottime and realtime time stamps + * + * Note: This is a special implementation for printk. The early boot time + * stamps, i.e. before timekeeping is available are taken from local_clock(). */ void ktime_get_fast_timestamps(struct system_timestamps *ts) { struct timekeeper *tk = &tk_core.timekeeper; + bool hres; - ts->real = __ktime_get_real_fast(&tk_fast_mono, &ts->mono); + hres = __ktime_get_real_fast(&tk_fast_mono, &ts->real, &ts->mono); ts->boot = ts->mono + ktime_to_ns(tk->offs_boot); + if (!hres) + ts->mono = local_clock(); } /**