From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756850AbdKOS3G (ORCPT ); Wed, 15 Nov 2017 13:29:06 -0500 Received: from Galois.linutronix.de ([146.0.238.70]:42885 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933224AbdKOS2F (ORCPT ); Wed, 15 Nov 2017 13:28:05 -0500 Message-Id: <20171115182657.703928462@linutronix.de> User-Agent: quilt/0.63-1 Date: Wed, 15 Nov 2017 19:15:38 +0100 From: Thomas Gleixner To: LKML Cc: Linus Torvalds , Prarit Bhargava , Mark Salyzyn , Petr Mladek , Ingo Molnar , "H. Peter Anvin" , Peter Zijlstra , Andrew Morton , Sergey Senozhatsky , Steven Rostedt , Joe Perches Subject: [RFC patch 7/7] timekeeping: Hack to use fine grained timestamps during boot References: <20171115181531.322572387@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Disposition: inline; filename=timekeeping--Hack-to-use-fine-grained-timestamps-during-boot.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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(); } /**