From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753401AbbFHUC3 (ORCPT ); Mon, 8 Jun 2015 16:02:29 -0400 Received: from www.linutronix.de ([62.245.132.108]:43180 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752178AbbFHUCV (ORCPT ); Mon, 8 Jun 2015 16:02:21 -0400 Date: Mon, 8 Jun 2015 22:02:18 +0200 (CEST) From: Thomas Gleixner To: John Stultz cc: Peter Zijlstra , Richard Cochran , Ingo Molnar , lkml , Prarit Bhargava , Daniel Bristot de Oliveira , Jan Kara , Jiri Bohac , Ingo Molnar , Shuah Khan Subject: Re: [RFC][PATCH 4/4] time: Do leapsecond adjustment in gettime fastpaths In-Reply-To: Message-ID: References: <1432931068-4980-1-git-send-email-john.stultz@linaro.org> <1432931068-4980-5-git-send-email-john.stultz@linaro.org> <20150602090154.GA2590@gmail.com> <20150603090452.GA9490@gmail.com> <20150604064809.GA14685@gmail.com> <20150605072913.GD19282@twins.programming.kicks-ass.net> <20150605090433.GC1528@localhost.localdomain> <1433495408.1495.8.camel@twins> User-Agent: Alpine 2.11 (DEB 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 8 Jun 2015, Thomas Gleixner wrote: > On Mon, 8 Jun 2015, John Stultz wrote: > > Now, It could be possible to do a lighter weight version of my patch, > > which just does the adjustment only for the hrtimer_interrupt code > > (leaving the rest of the read paths alone). > > Yes, that should work. As long as I can keep the cached values in the > hrtimer cpu bases and the whole thing keeps the clock_was_set_seq > logic intact. > > If we do not do the conditional version, then on every hrtimer > interrupt we write THREE cachelines for nothing. > > And if we cannot cache the offsets, then we end up calling into the > timekeeping code for every timer which is not CLOCK_MONOTONIC based > and retrieve the offset. That hurts especially on 32bit machines, > because we need to protect the readout with the timekeeper sequence > counter. Below is a patch which just has the required data in the right place and the changes to ktime_get_update_offsets_now(). It's simpler than your version as: - there is no requirement to do the add in the first place as we know the monotonic time at which the leap second happens. - we can precalculate the leap adjusted offset and just replace the non adjusted offset for the window. When the whole thing is over you just need to increment the clock_was_set_seq counter so the next timer interrupt will cache the normal values again. Thanks, tglx diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index e1f5a1136554..ecd193c23676 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -90,6 +90,9 @@ struct timekeeper { ktime_t offs_tai; s32 tai_offset; unsigned int clock_was_set_seq; + ktime_t next_leap_ktime; + ktime_t offs_real_leap_adjusted; + struct timespec64 raw_time; /* The following members are for timekeeping internal use */ diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 90ed5db67c1d..0de85bf9e331 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1952,15 +1952,21 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real, base = tk->tkr_mono.base; nsecs = timekeeping_get_ns(&tk->tkr_mono); + base = ktime_add_ns(base, nsecs); + if (*cwsseq != tk->clock_was_set_seq) { *cwsseq = tk->clock_was_set_seq; *offs_real = tk->offs_real; *offs_boot = tk->offs_boot; *offs_tai = tk->offs_tai; } + + if (base.tv64 >= tk->next_leap_ktime.tv64) + *offs_real = tk->offs_real_leap_adjusted; + } while (read_seqcount_retry(&tk_core.seq, seq)); - return ktime_add_ns(base, nsecs); + return base; } /**