From patchwork Mon Oct 30 22:29:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 117505 Delivered-To: patches@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3120250qgn; Mon, 30 Oct 2017 15:29:25 -0700 (PDT) X-Received: by 10.99.66.130 with SMTP id p124mr9150309pga.0.1509402565092; Mon, 30 Oct 2017 15:29:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509402565; cv=none; d=google.com; s=arc-20160816; b=Nb77D8okhG70f90fQCaHI3cfUpRCLWtWwX9zhwsSIatQVZKIh8k0yOtWGAZ2i2SCD5 KaEp3m3JUyv6+undblgzm4iUPPLN29rLcakcu0oAG8EVBbjJ5cc2Db3yFgY9dr2FnerF jtzG+viiul/j76LwhCIROt4xmewYqfbvX6Z4UlfEHmSKCwFbQjbBipVPIsuxRmxZD/Gq 6CDMbmuJiYDkwqNAvBPndhEOUO71QE5WVLL21lb+L+uqaA9yYvuETO/d209hUaT16/I7 kQp+Fvyj6UbJVPhd2D8iX9jIXEEysmj+2VsXppeZBpstqH2X2emIXpYRO3zdKb06GdII nYug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=89a+d0SuUn8y4sQF+uzo/1+A3O5oVi/q5+C9QKFMsx0=; b=Ok6LdaHqkRm0m80Y8OoFsKoz//1/NjRaBLCmLx6sjeVQXMi7QVX5du96mjS3XlHvN6 xjboScoiBNSh5pDv1LVUswphP0Wn0465JEq5qQ8JKDyRk4gr6i4CE5x/mavPWgbVI1AT lkV3i/OuA1/CqnZCfpXOeSkpGhg5uUUlphnZiuMHQNSidNpCojps9WCA3D5/euOseTGa KcXuy2BX50oGPdbPm5FRo7LPDeidtQnXkibZjgRUeGBxmhVlCmCQ/HTYxVfTGAgxJ5/r /zRkPIE80SJY/mE0Ljn6po5zvNrxC67Q6Dqa5HQ4VO4TBktN+Qe6sw/3e8gcNWsTFNnO VuTA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YIp1jz1e; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id d92sor3017pld.1.2017.10.30.15.29.24 for (Google Transport Security); Mon, 30 Oct 2017 15:29:25 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YIp1jz1e; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=89a+d0SuUn8y4sQF+uzo/1+A3O5oVi/q5+C9QKFMsx0=; b=YIp1jz1ebulrWywpYfd+Cihy2hG5IO7N6XzQi6NyhWyzUUtsFE4IRQf9fhS+1+sAZk klj9ax0QR08fb96kBnK3DRKuUQilP+mqLuBU31/MrSraP0BGgXo+enhgqQEf/q4dzm06 DOAEwNvVutyjm+l5doNnFXoc2+Bx8JKtyU+1k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=89a+d0SuUn8y4sQF+uzo/1+A3O5oVi/q5+C9QKFMsx0=; b=O5zgXxDav3yPvU79T3ZJMccHGIwD0vY9KtI1G4jJCtET1BNBtozGCdAGrMWyjX2JUw ijhOfvoMTw+/BCs/mfmdoUWOOzXELIm3xWIi29KwmE6IUAaaOLQgirtg9kHXwr5+H2Or rdBGwYInpUxUlCJAHAcPFhJX5Squn9G+OHBFeuAl1YOJO5D016EP+sik/V6oAx2qQ9SE L/aVBqMg7EegrjZGwH1pto48ddFygFcu/uQb0tnLBXXDCrwd9IXCCvv674/zYsgq3qRn rZd4s1/N9KNyGqeNr58U9Ww6Lt4QhL+qXZuOSKYkLjf8MDlw9DccTdq7kJo4Mm3rdR8t iGaA== X-Gm-Message-State: AMCzsaVnUWCxmvycu33eBnivoKgzWzxMTEtbpZskrWXEyWsqH2xkI1PS RIjPpKd3d7/xpBP7uoV9pMEH33c206zg5w== X-Google-Smtp-Source: ABhQp+R6/7E+TbnohrSzbvwqRx5Pd19GRSwJ3Of1V3FXqSU53gQxutqytOEWGAaGEEWoQxY/dS8t/Q== X-Received: by 10.159.216.131 with SMTP id s3mr8390363plp.252.1509402564641; Mon, 30 Oct 2017 15:29:24 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g13sm27479320pfm.130.2017.10.30.15.29.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Oct 2017 15:29:23 -0700 (PDT) From: John Stultz To: lkml Cc: Jason Gunthorpe , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 1/7] rtc: Allow rtc drivers to specify the tv_nsec value for ntp Date: Mon, 30 Oct 2017 15:29:08 -0700 Message-Id: <1509402554-18437-2-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> References: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> From: Jason Gunthorpe ntp is currently hardwired to try and call the rtc set when wall clock tv_nsec is 0.5 seconds. This historical behaviour works well with certain PC RTCs, but is not universal to all rtc hardware. Change how this works by introducing the driver specific concept of set_offset_nsec, the delay between current wall clock time and the target time to set (with a 0 tv_nsecs). For x86-style CMOS set_offset_nsec should be -0.5 s which causes the last second to be written 0.5 s after it has started. For compat with the old rtc_set_ntp_time, the value is defaulted to + 0.5 s, which causes the next second to be written 0.5s before it starts, as things were before this patch. Testing shows many non-x86 RTCs would like set_offset_nsec ~= 0, so ultimately each RTC driver should set the set_offset_nsec according to its needs, and non x86 architectures should stop using update_persistent_clock64 in order to access this feature. Future patches will revise the drivers as needed. Since CMOS and RTC now have very different handling they are split into two dedicated code paths, sharing the support code, and ifdefs are replaced with IS_ENABLED. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Signed-off-by: Jason Gunthorpe Signed-off-by: John Stultz --- drivers/rtc/class.c | 3 + drivers/rtc/systohc.c | 53 +++++++++++----- include/linux/rtc.h | 43 ++++++++++++- kernel/time/ntp.c | 166 ++++++++++++++++++++++++++++++++++---------------- 4 files changed, 196 insertions(+), 69 deletions(-) -- 2.7.4 diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 2ed970d..722d683 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -161,6 +161,9 @@ static struct rtc_device *rtc_allocate_device(void) device_initialize(&rtc->dev); + /* Drivers can revise this default after allocating the device. */ + rtc->set_offset_nsec = NSEC_PER_SEC / 2; + rtc->irq_freq = 1; rtc->max_user_freq = 64; rtc->dev.class = rtc_class; diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c index b4a68ff..0c17764 100644 --- a/drivers/rtc/systohc.c +++ b/drivers/rtc/systohc.c @@ -10,6 +10,7 @@ /** * rtc_set_ntp_time - Save NTP synchronized time to the RTC * @now: Current time of day + * @target_nsec: pointer for desired now->tv_nsec value * * Replacement for the NTP platform function update_persistent_clock64 * that stores time for later retrieval by rtc_hctosys. @@ -18,30 +19,52 @@ * possible at all, and various other -errno for specific temporary failure * cases. * + * -EPROTO is returned if now.tv_nsec is not close enough to *target_nsec. + ( * If temporary failure is indicated the caller should try again 'soon' */ -int rtc_set_ntp_time(struct timespec64 now) +int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec) { struct rtc_device *rtc; struct rtc_time tm; + struct timespec64 to_set; int err = -ENODEV; - - if (now.tv_nsec < (NSEC_PER_SEC >> 1)) - rtc_time64_to_tm(now.tv_sec, &tm); - else - rtc_time64_to_tm(now.tv_sec + 1, &tm); + bool ok; rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE); - if (rtc) { - /* rtc_hctosys exclusively uses UTC, so we call set_time here, - * not set_mmss. */ - if (rtc->ops && - (rtc->ops->set_time || - rtc->ops->set_mmss64 || - rtc->ops->set_mmss)) - err = rtc_set_time(rtc, &tm); - rtc_class_close(rtc); + if (!rtc) + goto out_err; + + if (!rtc->ops || (!rtc->ops->set_time && !rtc->ops->set_mmss64 && + !rtc->ops->set_mmss)) + goto out_close; + + /* Compute the value of tv_nsec we require the caller to supply in + * now.tv_nsec. This is the value such that (now + + * set_offset_nsec).tv_nsec == 0. + */ + set_normalized_timespec64(&to_set, 0, -rtc->set_offset_nsec); + *target_nsec = to_set.tv_nsec; + + /* The ntp code must call this with the correct value in tv_nsec, if + * it does not we update target_nsec and return EPROTO to make the ntp + * code try again later. + */ + ok = rtc_tv_nsec_ok(rtc->set_offset_nsec, &to_set, &now); + if (!ok) { + err = -EPROTO; + goto out_close; } + rtc_time64_to_tm(to_set.tv_sec, &tm); + + /* rtc_hctosys exclusively uses UTC, so we call set_time here, not + * set_mmss. + */ + err = rtc_set_time(rtc, &tm); + +out_close: + rtc_class_close(rtc); +out_err: return err; } diff --git a/include/linux/rtc.h b/include/linux/rtc.h index e6d0f9c..5b13fa0 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -135,6 +135,14 @@ struct rtc_device { /* Some hardware can't support UIE mode */ int uie_unsupported; + /* Number of nsec it takes to set the RTC clock. This influences when + * the set ops are called. An offset: + * - of 0.5 s will call RTC set for wall clock time 10.0 s at 9.5 s + * - of 1.5 s will call RTC set for wall clock time 10.0 s at 8.5 s + * - of -0.5 s will call RTC set for wall clock time 10.0 s at 10.5 s + */ + long set_offset_nsec; + bool registered; struct nvmem_config *nvmem_config; @@ -172,7 +180,7 @@ extern void devm_rtc_device_unregister(struct device *dev, extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); -extern int rtc_set_ntp_time(struct timespec64 now); +extern int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec); int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm); extern int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alrm); @@ -221,6 +229,39 @@ static inline bool is_leap_year(unsigned int year) return (!(year % 4) && (year % 100)) || !(year % 400); } +/* Determine if we can call to driver to set the time. Drivers can only be + * called to set a second aligned time value, and the field set_offset_nsec + * specifies how far away from the second aligned time to call the driver. + * + * This also computes 'to_set' which is the time we are trying to set, and has + * a zero in tv_nsecs, such that: + * to_set - set_delay_nsec == now +/- FUZZ + * + */ +static inline bool rtc_tv_nsec_ok(s64 set_offset_nsec, + struct timespec64 *to_set, + const struct timespec64 *now) +{ + /* Allowed error in tv_nsec, arbitarily set to 5 jiffies in ns. */ + const unsigned long TIME_SET_NSEC_FUZZ = TICK_NSEC * 5; + struct timespec64 delay = {.tv_sec = 0, + .tv_nsec = set_offset_nsec}; + + *to_set = timespec64_add(*now, delay); + + if (to_set->tv_nsec < TIME_SET_NSEC_FUZZ) { + to_set->tv_nsec = 0; + return true; + } + + if (to_set->tv_nsec > NSEC_PER_SEC - TIME_SET_NSEC_FUZZ) { + to_set->tv_sec++; + to_set->tv_nsec = 0; + return true; + } + return false; +} + #define rtc_register_device(device) \ __rtc_register_device(THIS_MODULE, device) diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index edf19cc..bc19de1 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -492,6 +492,67 @@ int second_overflow(time64_t secs) return leap; } +static void sync_hw_clock(struct work_struct *work); +static DECLARE_DELAYED_WORK(sync_work, sync_hw_clock); + +static void sched_sync_hw_clock(struct timespec64 now, + unsigned long target_nsec, bool fail) + +{ + struct timespec64 next; + + getnstimeofday64(&next); + if (!fail) + next.tv_sec = 659; + else { + /* + * Try again as soon as possible. Delaying long periods + * decreases the accuracy of the work queue timer. Due to this + * the algorithm is very likely to require a short-sleep retry + * after the above long sleep to synchronize ts_nsec. + */ + next.tv_sec = 0; + } + + /* Compute the needed delay that will get to tv_nsec == target_nsec */ + next.tv_nsec = target_nsec - next.tv_nsec; + if (next.tv_nsec <= 0) + next.tv_nsec += NSEC_PER_SEC; + if (next.tv_nsec >= NSEC_PER_SEC) { + next.tv_sec++; + next.tv_nsec -= NSEC_PER_SEC; + } + + queue_delayed_work(system_power_efficient_wq, &sync_work, + timespec64_to_jiffies(&next)); +} + +static void sync_rtc_clock(void) +{ + unsigned long target_nsec; + struct timespec64 adjust, now; + int rc; + + if (!IS_ENABLED(CONFIG_RTC_SYSTOHC)) + return; + + getnstimeofday64(&now); + + adjust = now; + if (persistent_clock_is_local) + adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); + + /* + * The current RTC in use will provide the target_nsec it wants to be + * called at, and does rtc_tv_nsec_ok internally. + */ + rc = rtc_set_ntp_time(adjust, &target_nsec); + if (rc == -ENODEV) + return; + + sched_sync_hw_clock(now, target_nsec, rc); +} + #ifdef CONFIG_GENERIC_CMOS_UPDATE int __weak update_persistent_clock(struct timespec now) { @@ -507,76 +568,75 @@ int __weak update_persistent_clock64(struct timespec64 now64) } #endif -#if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC) -static void sync_cmos_clock(struct work_struct *work); - -static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); - -static void sync_cmos_clock(struct work_struct *work) +static bool sync_cmos_clock(void) { + static bool no_cmos; struct timespec64 now; - struct timespec64 next; - int fail = 1; + struct timespec64 adjust; + int rc = -EPROTO; + long target_nsec = NSEC_PER_SEC / 2; + + if (!IS_ENABLED(CONFIG_GENERIC_CMOS_UPDATE)) + return false; + + if (no_cmos) + return false; /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - * This code is run on a timer. If the clock is set, that timer - * may not expire at the correct time. Thus, we adjust... - * We want the clock to be within a couple of ticks from the target. + * Historically update_persistent_clock64() has followed x86 + * semantics, which match the MC146818A/etc RTC. This RTC will store + * 'adjust' and then in .5s it will advance once second. + * + * Architectures are strongly encouraged to use rtclib and not + * implement this legacy API. */ - if (!ntp_synced()) { - /* - * Not synced, exit, do not restart a timer (if one is - * running, let it run out). - */ - return; - } - getnstimeofday64(&now); - if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) { - struct timespec64 adjust = now; - - fail = -ENODEV; + if (rtc_tv_nsec_ok(-1 * target_nsec, &adjust, &now)) { if (persistent_clock_is_local) adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); -#ifdef CONFIG_GENERIC_CMOS_UPDATE - fail = update_persistent_clock64(adjust); -#endif - -#ifdef CONFIG_RTC_SYSTOHC - if (fail == -ENODEV) - fail = rtc_set_ntp_time(adjust); -#endif + rc = update_persistent_clock64(adjust); + /* + * The machine does not support update_persistent_clock64 even + * though it defines CONFIG_GENERIC_CMOS_UPDATE. + */ + if (rc == -ENODEV) { + no_cmos = true; + return false; + } } - next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); - if (next.tv_nsec <= 0) - next.tv_nsec += NSEC_PER_SEC; + sched_sync_hw_clock(now, target_nsec, rc); + return true; +} - if (!fail || fail == -ENODEV) - next.tv_sec = 659; - else - next.tv_sec = 0; +/* + * If we have an externally synchronized Linux clock, then update RTC clock + * accordingly every ~11 minutes. Generally RTCs can only store second + * precision, but many RTCs will adjust the phase of their second tick to + * match the moment of update. This infrastructure arranges to call to the RTC + * set at the correct moment to phase synchronize the RTC second tick over + * with the kernel clock. + */ +static void sync_hw_clock(struct work_struct *work) +{ + if (!ntp_synced()) + return; - if (next.tv_nsec >= NSEC_PER_SEC) { - next.tv_sec++; - next.tv_nsec -= NSEC_PER_SEC; - } - queue_delayed_work(system_power_efficient_wq, - &sync_cmos_work, timespec64_to_jiffies(&next)); + if (sync_cmos_clock()) + return; + + sync_rtc_clock(); } void ntp_notify_cmos_timer(void) { - queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); -} - -#else -void ntp_notify_cmos_timer(void) { } -#endif + if (!ntp_synced()) + return; + if (IS_ENABLED(CONFIG_GENERIC_CMOS_UPDATE) || + IS_ENABLED(CONFIG_RTC_SYSTOHC)) + queue_delayed_work(system_power_efficient_wq, &sync_work, 0); +} /* * Propagate a new txc->status value into the NTP state: From patchwork Mon Oct 30 22:29:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 117506 Delivered-To: patches@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3120284qgn; Mon, 30 Oct 2017 15:29:27 -0700 (PDT) X-Received: by 10.99.147.69 with SMTP id w5mr8884019pgm.401.1509402567010; Mon, 30 Oct 2017 15:29:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509402567; cv=none; d=google.com; s=arc-20160816; b=ePNpXkxlZkzsmzn0MG7xmOHxydRuOz31MZMdBvyBB+pE6xyxaPqxLFtb+47VWNHJsc W1odvdyvpQGRCKaNg0yNtkABS9UPeGNpYamZeGdKOOYx3QV1qXX5XzMOqTmgJoncKvWK APIbPk1VBjsiUIqSNOoz4OznIkrAvohSn0O6/SM2RkjUqgB6mBo7xArqlUleyKTGnAgB MlZG0UEkAep/44Zu40nQMruZXKxghE/4m+os1GfqGreY/Zm6ZGBPYvqZRZ1Nd7ydjxoA b4gKxMLLTXus0OaJpn7PSPt6iqReel+aODs/SulJRY5Pj6yFgv1kF0uALBMIXr3Di/NA Bucg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=hwZaS9+EHP+v5aszlOu/xzAowxKI8AtLs0DEYBM6n98=; b=krEqOT0VNsS9hTDioSjzwGhH41q/t4qOZrxljY0Yq/E3ndxZTSnlLPQdIqGofbOZlP TZpwtPSd5Qr7lCUGGe2pqniCzHZcNEtZwYhBdzWbrYPok3ROk4qd5PpP1qfVc94SDptp A9jgwnf988iswJUkfbwHvRftdb0AtsKbUwnXxskIDQHpj5PJKJA7hiQK26cr5/IXNr1X UZEIdCjhcTiJxQsnnETwl5OIZ5qVgtfQtGKN1EF3eLXlkYJLms+7xEIVZ3GYlTztZEwk 0kjtXoYxmv0Kl+ESkZYiWiiAoPyUuDpjef1wNAxaN+XBYGAE43A2BD1FR52Wjy/fDbgw 4AKQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=K7aokOIw; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id f1sor3864239pln.124.2017.10.30.15.29.26 for (Google Transport Security); Mon, 30 Oct 2017 15:29:26 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=K7aokOIw; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hwZaS9+EHP+v5aszlOu/xzAowxKI8AtLs0DEYBM6n98=; b=K7aokOIw9meti7hc6KUbfsEE19I9NKXAdvbiWSyHh3g54W2XxO0pQvMstWlVZkhfKg fWN67nh1XK3RjK5S1udPi969eXk50vkbehI5X5tPvgPpazXWeXFa+QQILNJwVlt82tok vVpiXns9wBathZg3pa+H35UwSTy9TASACuPEA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hwZaS9+EHP+v5aszlOu/xzAowxKI8AtLs0DEYBM6n98=; b=hOP25tsiQa46r52obG1VC/Yhq6/5COwWadYiAGTQNwVi3dkiKTT+tnsTzmYgJLFJRu MzkY65DfH2LfT8uACdk60oTqlshZXrC8vlAdSfL6MrGZzEC95h3iAOSHdhXH8x9f22I8 yyN9nQrIIXxPDjOrzwpHTIkh+f7AsNBFfB9eNhweF422OfLA9geb6WXTNoRuWdfCaz3w O+TP69iN+nwESBxzgKjViMHfR2s2VHLH2LPLzcKd1Sb4LDa7E33atJp/BrTXJ/DnBBCd qvOUfzwr86H9vrp6Cx+thZHhcb4MvN04YMrjOYiFLHEuDEydGe0LB1n0bQvt1t8aM8Qw DB2A== X-Gm-Message-State: AMCzsaWwxEHswJlA5dTdxH3yWrxb64nRrE70hSNUA+LeCBEmo2IujdHn hULBtoIdzyG2f2hc1hRi3k+z5Xlh X-Google-Smtp-Source: ABhQp+QoQG5AoJ3SmrNFHYaAuf2aySE+SRUAxsBQ3XtrI/hXGoown3D7dHa+5qHR7TcunSFhwc8Q4w== X-Received: by 10.84.130.41 with SMTP id 38mr8506019plc.387.1509402566532; Mon, 30 Oct 2017 15:29:26 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g13sm27479320pfm.130.2017.10.30.15.29.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Oct 2017 15:29:25 -0700 (PDT) From: John Stultz To: lkml Cc: Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 2/7] timekeeping: Consolidate timekeeping_inject_offset code Date: Mon, 30 Oct 2017 15:29:09 -0700 Message-Id: <1509402554-18437-3-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> References: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> From: Arnd Bergmann The code to check the adjtimex() or clock_adjtime() arguments is spread out across multiple files for presumably only historic reasons. As a preparatation for a rework to get rid of the use of 'struct timeval' and 'struct timespec' in there, this moves all the portions into kernel/time/timekeeping.c and marks them as 'static'. The warp_clock() function here is not as closely related as the others, but I feel it still makes sense to move it here in order to consolidate all callers of timekeeping_inject_offset(). Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Signed-off-by: Arnd Bergmann [jstultz: Whitespace fixup] Signed-off-by: John Stultz --- include/linux/time.h | 26 ---------- kernel/time/ntp.c | 61 ---------------------- kernel/time/ntp_internal.h | 1 - kernel/time/time.c | 36 +------------ kernel/time/timekeeping.c | 123 ++++++++++++++++++++++++++++++++++++++++++++- kernel/time/timekeeping.h | 2 +- 6 files changed, 123 insertions(+), 126 deletions(-) -- 2.7.4 diff --git a/include/linux/time.h b/include/linux/time.h index 9bc1f94..c0fbad0 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -134,32 +134,6 @@ static inline bool timeval_valid(const struct timeval *tv) extern struct timespec timespec_trunc(struct timespec t, unsigned gran); -/* - * Validates if a timespec/timeval used to inject a time offset is valid. - * Offsets can be postive or negative. The value of the timeval/timespec - * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must - * always be non-negative. - */ -static inline bool timeval_inject_offset_valid(const struct timeval *tv) -{ - /* We don't check the tv_sec as it can be positive or negative */ - - /* Can't have more microseconds then a second */ - if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) - return false; - return true; -} - -static inline bool timespec_inject_offset_valid(const struct timespec *ts) -{ - /* We don't check the tv_sec as it can be positive or negative */ - - /* Can't have more nanoseconds then a second */ - if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC) - return false; - return true; -} - /* Some architectures do not supply their own clocksource. * This is mainly the case in architectures that get their * inter-tick times by reading the counter on their interval diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index bc19de1..90f8458 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -713,67 +713,6 @@ static inline void process_adjtimex_modes(struct timex *txc, } - -/** - * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex - */ -int ntp_validate_timex(struct timex *txc) -{ - if (txc->modes & ADJ_ADJTIME) { - /* singleshot must not be used with any other mode bits */ - if (!(txc->modes & ADJ_OFFSET_SINGLESHOT)) - return -EINVAL; - if (!(txc->modes & ADJ_OFFSET_READONLY) && - !capable(CAP_SYS_TIME)) - return -EPERM; - } else { - /* In order to modify anything, you gotta be super-user! */ - if (txc->modes && !capable(CAP_SYS_TIME)) - return -EPERM; - /* - * if the quartz is off by more than 10% then - * something is VERY wrong! - */ - if (txc->modes & ADJ_TICK && - (txc->tick < 900000/USER_HZ || - txc->tick > 1100000/USER_HZ)) - return -EINVAL; - } - - if (txc->modes & ADJ_SETOFFSET) { - /* In order to inject time, you gotta be super-user! */ - if (!capable(CAP_SYS_TIME)) - return -EPERM; - - if (txc->modes & ADJ_NANO) { - struct timespec ts; - - ts.tv_sec = txc->time.tv_sec; - ts.tv_nsec = txc->time.tv_usec; - if (!timespec_inject_offset_valid(&ts)) - return -EINVAL; - - } else { - if (!timeval_inject_offset_valid(&txc->time)) - return -EINVAL; - } - } - - /* - * Check for potential multiplication overflows that can - * only happen on 64-bit systems: - */ - if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) { - if (LLONG_MIN / PPM_SCALE > txc->freq) - return -EINVAL; - if (LLONG_MAX / PPM_SCALE < txc->freq) - return -EINVAL; - } - - return 0; -} - - /* * adjtimex mainly allows reading (and writing, if superuser) of * kernel time-keeping variables. used by xntpd. diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h index d8a7c11..74b52cd 100644 --- a/kernel/time/ntp_internal.h +++ b/kernel/time/ntp_internal.h @@ -7,7 +7,6 @@ extern void ntp_clear(void); extern u64 ntp_tick_length(void); extern ktime_t ntp_get_next_leap(void); extern int second_overflow(time64_t secs); -extern int ntp_validate_timex(struct timex *); extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); extern void __hardpps(const struct timespec64 *, const struct timespec64 *); #endif /* _LINUX_NTP_INTERNAL_H */ diff --git a/kernel/time/time.c b/kernel/time/time.c index 44a8c14..04684e2 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -158,40 +158,6 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv, } /* - * Indicates if there is an offset between the system clock and the hardware - * clock/persistent clock/rtc. - */ -int persistent_clock_is_local; - -/* - * Adjust the time obtained from the CMOS to be UTC time instead of - * local time. - * - * This is ugly, but preferable to the alternatives. Otherwise we - * would either need to write a program to do it in /etc/rc (and risk - * confusion if the program gets run more than once; it would also be - * hard to make the program warp the clock precisely n hours) or - * compile in the timezone information into the kernel. Bad, bad.... - * - * - TYT, 1992-01-01 - * - * The best thing to do is to keep the CMOS clock in universal time (UTC) - * as real UNIX machines always do it. This avoids all headaches about - * daylight saving times and warping kernel clocks. - */ -static inline void warp_clock(void) -{ - if (sys_tz.tz_minuteswest != 0) { - struct timespec adjust; - - persistent_clock_is_local = 1; - adjust.tv_sec = sys_tz.tz_minuteswest * 60; - adjust.tv_nsec = 0; - timekeeping_inject_offset(&adjust); - } -} - -/* * In case for some reason the CMOS clock has not already been running * in UTC, but in some local time: The first time we set the timezone, * we will warp the clock so that it is ticking UTC time instead of @@ -224,7 +190,7 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz if (firsttime) { firsttime = 0; if (!tv) - warp_clock(); + timekeeping_warp_clock(); } } if (tv) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2cafb49..7d8e0e8 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1258,13 +1258,39 @@ int do_settimeofday64(const struct timespec64 *ts) } EXPORT_SYMBOL(do_settimeofday64); +/* + * Validates if a timespec/timeval used to inject a time offset is valid. + * Offsets can be postive or negative. The value of the timeval/timespec + * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must + * always be non-negative. + */ +static inline bool timeval_inject_offset_valid(const struct timeval *tv) +{ + /* We don't check the tv_sec as it can be positive or negative */ + + /* Can't have more microseconds then a second */ + if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) + return false; + return true; +} + +static inline bool timespec_inject_offset_valid(const struct timespec *ts) +{ + /* We don't check the tv_sec as it can be positive or negative */ + + /* Can't have more nanoseconds then a second */ + if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC) + return false; + return true; +} + /** * timekeeping_inject_offset - Adds or subtracts from the current time. * @tv: pointer to the timespec variable containing the offset * * Adds or subtracts an offset value from the current time. */ -int timekeeping_inject_offset(struct timespec *ts) +static int timekeeping_inject_offset(struct timespec *ts) { struct timekeeper *tk = &tk_core.timekeeper; unsigned long flags; @@ -1303,7 +1329,40 @@ int timekeeping_inject_offset(struct timespec *ts) return ret; } -EXPORT_SYMBOL(timekeeping_inject_offset); + +/* + * Indicates if there is an offset between the system clock and the hardware + * clock/persistent clock/rtc. + */ +int persistent_clock_is_local; + +/* + * Adjust the time obtained from the CMOS to be UTC time instead of + * local time. + * + * This is ugly, but preferable to the alternatives. Otherwise we + * would either need to write a program to do it in /etc/rc (and risk + * confusion if the program gets run more than once; it would also be + * hard to make the program warp the clock precisely n hours) or + * compile in the timezone information into the kernel. Bad, bad.... + * + * - TYT, 1992-01-01 + * + * The best thing to do is to keep the CMOS clock in universal time (UTC) + * as real UNIX machines always do it. This avoids all headaches about + * daylight saving times and warping kernel clocks. + */ +void timekeeping_warp_clock(void) +{ + if (sys_tz.tz_minuteswest != 0) { + struct timespec adjust; + + persistent_clock_is_local = 1; + adjust.tv_sec = sys_tz.tz_minuteswest * 60; + adjust.tv_nsec = 0; + timekeeping_inject_offset(&adjust); + } +} /** * __timekeeping_set_tai_offset - Sets the TAI offset from UTC and monotonic @@ -2248,6 +2307,66 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real, } /** + * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex + */ +static int ntp_validate_timex(struct timex *txc) +{ + if (txc->modes & ADJ_ADJTIME) { + /* singleshot must not be used with any other mode bits */ + if (!(txc->modes & ADJ_OFFSET_SINGLESHOT)) + return -EINVAL; + if (!(txc->modes & ADJ_OFFSET_READONLY) && + !capable(CAP_SYS_TIME)) + return -EPERM; + } else { + /* In order to modify anything, you gotta be super-user! */ + if (txc->modes && !capable(CAP_SYS_TIME)) + return -EPERM; + /* + * if the quartz is off by more than 10% then + * something is VERY wrong! + */ + if (txc->modes & ADJ_TICK && + (txc->tick < 900000/USER_HZ || + txc->tick > 1100000/USER_HZ)) + return -EINVAL; + } + + if (txc->modes & ADJ_SETOFFSET) { + /* In order to inject time, you gotta be super-user! */ + if (!capable(CAP_SYS_TIME)) + return -EPERM; + + if (txc->modes & ADJ_NANO) { + struct timespec ts; + + ts.tv_sec = txc->time.tv_sec; + ts.tv_nsec = txc->time.tv_usec; + if (!timespec_inject_offset_valid(&ts)) + return -EINVAL; + + } else { + if (!timeval_inject_offset_valid(&txc->time)) + return -EINVAL; + } + } + + /* + * Check for potential multiplication overflows that can + * only happen on 64-bit systems: + */ + if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) { + if (LLONG_MIN / PPM_SCALE > txc->freq) + return -EINVAL; + if (LLONG_MAX / PPM_SCALE < txc->freq) + return -EINVAL; + } + + return 0; +} + + +/** * do_adjtimex() - Accessor function to NTP __do_adjtimex function */ int do_adjtimex(struct timex *txc) diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h index d091467..44aec78 100644 --- a/kernel/time/timekeeping.h +++ b/kernel/time/timekeeping.h @@ -10,7 +10,7 @@ extern ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, extern int timekeeping_valid_for_hres(void); extern u64 timekeeping_max_deferment(void); -extern int timekeeping_inject_offset(struct timespec *ts); +extern void timekeeping_warp_clock(void); extern int timekeeping_suspend(void); extern void timekeeping_resume(void); From patchwork Mon Oct 30 22:29:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 117507 Delivered-To: patches@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3120309qgn; Mon, 30 Oct 2017 15:29:28 -0700 (PDT) X-Received: by 10.99.114.29 with SMTP id n29mr9022741pgc.303.1509402568365; Mon, 30 Oct 2017 15:29:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509402568; cv=none; d=google.com; s=arc-20160816; b=PdZ1rBdXfY91DrnUT0FOPV3DR/NgTZr3a+jC736V+UFZajXSh+QMPh2wjPI5d2WUtO 4w2z6BiqYYBabWkQ6N8b7Gu3dIXI7ieBuQUeenHOrB6hiCR4jBhbBZP7Mc8iLfq+qVZZ tjVMhLyld7pwv07aa+u5C4spkhflzBxN+IcvVkRbCkRhhGUqoU0adRPvUupD9bj9bEMl AbjstkD4hA0wet10y2nv8RCL6ibVBomVjx8jrKtelVckQ1R6zOKXlItfaHMRnWatV6Iy 1f7nPbo7741Yc2nGK9y0y+uGC0wVbdcnbOo9UUkXq9Y+LzCttNIc2gYs4M+TuQUqefLk 2KgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=/9vApLuyGKDutzrnKpbJSXiNB8MqKyaDwfRZedUNVrI=; b=yNDG+PNaVBgJ/rKxRDhuy9jzDMeTsAatBtecixlLXpRxL+MJIwWZmIMXbb/0CJ9D+B QWzxUf8NdSWPF20ouFZ8wrdieKRpp+wr4p206k3bSnotM79dBc+aNkBO8SxFKxPv8/I3 ECsiQdeAjsKrKf4IYMUH4/TI90liF8ReC+6qjy0BwS9jbxb4oDzEqwGkw16h8YjOI28A wOhxmpDa98h8pcPKzJYMVe4PWxKYtYyrkqzwd0qIWh8gbtZppkyCg/mHPyo9jr2RzcPQ 5n+BqAbr8k6U0F06XIkysD7mONjwjGS//Mco1ycxmYVJb1IbfR1p2i8w//eDGJpo0U25 zyyA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jczutyof; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id v2sor3459050pgt.313.2017.10.30.15.29.28 for (Google Transport Security); Mon, 30 Oct 2017 15:29:28 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jczutyof; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/9vApLuyGKDutzrnKpbJSXiNB8MqKyaDwfRZedUNVrI=; b=jczutyofkEoqlketf+HTo1MEz258GWBU6KGKjCKYa3ciwX6YMg9kpvlt9hAtBmn0Fm +TjhV7j9qycfk5ov5sfx2c6YiE6i36Y8IBo7odn277swJQKCAU7X2IgjCTy38mFqtt9X VFV4aJ3C7VEXlmUO8cbhRmZQvRRCh111O/+NY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/9vApLuyGKDutzrnKpbJSXiNB8MqKyaDwfRZedUNVrI=; b=kVSOzGbTSLTrQdty5+gsAcpTfwytsWjpdLKxjycNAzdr6/Nlyxf7AgwtHFyGou4jcl Za7xEh90gApgqIoCLKBhSnkUj7a7kPiTODqnM8Pi2zf2o+kxtkiNIf6W/jrDVVbYuDQO mouLb+EH3gVLGIKwFxmcqMCf5UOgMaLybjEdGnJChyVotC+HHg/X5kq4LYOaJ8e+wlIa uHmWXyCvXcEQIV4U/jH8Wm5aW0fzpQF55Yrz80EhiJh9SW6l+K91A6KpZydMN4/oPI7W Qrbjt0qD6G0AjWVZddgsbs+epgXzO75V2IfaOqQ3FMWbqYUS2B46G6/AJU5gBJaZnSJg Ew4A== X-Gm-Message-State: AMCzsaXIk7sa2F9U128gdXSHAOZwhkquzGJh8uxNtKK7Xbul7o8Raetu KYNsvH0q8ngsVtTkfKT4bi3sioGW X-Google-Smtp-Source: ABhQp+QP2u0PkEywgLZo2HirFJZDGOZtOr91zr1D7/NFlZlbLoekUPDeUAiAKYTZ2oRkRtztPkfBCg== X-Received: by 10.98.222.2 with SMTP id h2mr10313937pfg.165.1509402567954; Mon, 30 Oct 2017 15:29:27 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g13sm27479320pfm.130.2017.10.30.15.29.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Oct 2017 15:29:27 -0700 (PDT) From: John Stultz To: lkml Cc: Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 3/7] timekeeping: Use timespec64 in timekeeping_inject_offset Date: Mon, 30 Oct 2017 15:29:10 -0700 Message-Id: <1509402554-18437-4-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> References: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> From: Arnd Bergmann As part of changing all the timekeeping code to use 64-bit time_t consistently, this removes the uses of timeval and timespec as much as possible from do_adjtimex() and timekeeping_inject_offset(). The timeval_inject_offset_valid() and timespec_inject_offset_valid() just complicate this, so I'm folding them into the respective callers. This leaves the actual 'struct timex' definition, which is part of the user-space ABI and should be dealt with separately when we have agreed on the ABI change. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Signed-off-by: Arnd Bergmann Signed-off-by: John Stultz --- kernel/time/timekeeping.c | 72 ++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 47 deletions(-) -- 2.7.4 diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 7d8e0e8..c6a35fb 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1258,65 +1258,37 @@ int do_settimeofday64(const struct timespec64 *ts) } EXPORT_SYMBOL(do_settimeofday64); -/* - * Validates if a timespec/timeval used to inject a time offset is valid. - * Offsets can be postive or negative. The value of the timeval/timespec - * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must - * always be non-negative. - */ -static inline bool timeval_inject_offset_valid(const struct timeval *tv) -{ - /* We don't check the tv_sec as it can be positive or negative */ - - /* Can't have more microseconds then a second */ - if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) - return false; - return true; -} - -static inline bool timespec_inject_offset_valid(const struct timespec *ts) -{ - /* We don't check the tv_sec as it can be positive or negative */ - - /* Can't have more nanoseconds then a second */ - if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC) - return false; - return true; -} - /** * timekeeping_inject_offset - Adds or subtracts from the current time. * @tv: pointer to the timespec variable containing the offset * * Adds or subtracts an offset value from the current time. */ -static int timekeeping_inject_offset(struct timespec *ts) +static int timekeeping_inject_offset(struct timespec64 *ts) { struct timekeeper *tk = &tk_core.timekeeper; unsigned long flags; - struct timespec64 ts64, tmp; + struct timespec64 tmp; int ret = 0; - if (!timespec_inject_offset_valid(ts)) + if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC) return -EINVAL; - ts64 = timespec_to_timespec64(*ts); - raw_spin_lock_irqsave(&timekeeper_lock, flags); write_seqcount_begin(&tk_core.seq); timekeeping_forward_now(tk); /* Make sure the proposed value is valid */ - tmp = timespec64_add(tk_xtime(tk), ts64); - if (timespec64_compare(&tk->wall_to_monotonic, &ts64) > 0 || + tmp = timespec64_add(tk_xtime(tk), *ts); + if (timespec64_compare(&tk->wall_to_monotonic, ts) > 0 || !timespec64_valid_strict(&tmp)) { ret = -EINVAL; goto error; } - tk_xtime_add(tk, &ts64); - tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts64)); + tk_xtime_add(tk, ts); + tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, *ts)); error: /* even if we error out, we forwarded the time, so call update */ timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); @@ -1355,7 +1327,7 @@ int persistent_clock_is_local; void timekeeping_warp_clock(void) { if (sys_tz.tz_minuteswest != 0) { - struct timespec adjust; + struct timespec64 adjust; persistent_clock_is_local = 1; adjust.tv_sec = sys_tz.tz_minuteswest * 60; @@ -2307,9 +2279,9 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real, } /** - * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex + * timekeeping_validate_timex - Ensures the timex is ok for use in do_adjtimex */ -static int ntp_validate_timex(struct timex *txc) +static int timekeeping_validate_timex(struct timex *txc) { if (txc->modes & ADJ_ADJTIME) { /* singleshot must not be used with any other mode bits */ @@ -2337,16 +2309,22 @@ static int ntp_validate_timex(struct timex *txc) if (!capable(CAP_SYS_TIME)) return -EPERM; - if (txc->modes & ADJ_NANO) { - struct timespec ts; + /* + * Validate if a timespec/timeval used to inject a time + * offset is valid. Offsets can be postive or negative, so + * we don't check tv_sec. The value of the timeval/timespec + * is the sum of its fields,but *NOTE*: + * The field tv_usec/tv_nsec must always be non-negative and + * we can't have more nanoseconds/microseconds than a second. + */ + if (txc->time.tv_usec < 0) + return -EINVAL; - ts.tv_sec = txc->time.tv_sec; - ts.tv_nsec = txc->time.tv_usec; - if (!timespec_inject_offset_valid(&ts)) + if (txc->modes & ADJ_NANO) { + if (txc->time.tv_usec >= NSEC_PER_SEC) return -EINVAL; - } else { - if (!timeval_inject_offset_valid(&txc->time)) + if (txc->time.tv_usec >= USEC_PER_SEC) return -EINVAL; } } @@ -2378,12 +2356,12 @@ int do_adjtimex(struct timex *txc) int ret; /* Validate the data before disabling interrupts */ - ret = ntp_validate_timex(txc); + ret = timekeeping_validate_timex(txc); if (ret) return ret; if (txc->modes & ADJ_SETOFFSET) { - struct timespec delta; + struct timespec64 delta; delta.tv_sec = txc->time.tv_sec; delta.tv_nsec = txc->time.tv_usec; if (!(txc->modes & ADJ_NANO)) From patchwork Mon Oct 30 22:29:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 117508 Delivered-To: patches@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3120346qgn; Mon, 30 Oct 2017 15:29:30 -0700 (PDT) X-Received: by 10.99.154.18 with SMTP id o18mr8889597pge.18.1509402569968; Mon, 30 Oct 2017 15:29:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509402569; cv=none; d=google.com; s=arc-20160816; b=t4XXKZ4vrFxspZUAAToKsSAvaaDpJ8r+q64Jw2l5xXxKdoGshM08N2I+zlp4nh4ZV0 Q3VCv1fBCK+piGdo1UV4pT92oVOCmEG6K9MsQYo8q6V8VIUJ8/qfqBrpKmpo9CyE+DUj DNd+LRFZvAEdo7JA+mM7rlr8Aw+4Enxsdz0RdfnL227TLvDS8O6jpBERRyjBS7oT+l4f 9SPqy/Dpla/obV+bXraCDCbOiUHE4E20DbMiTJx+gCviqFN5QaoaBcvsipdRuasV2c0T e15xXUJNyGKQ15yv47D5WIQawGCEYlLxpDT8dfQX6iLG2otDfRnaMg76BCxcYdUqmc2j bfmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=+t5v60/lBsJv/2HCuJrnV4Tg64928uHOpN9NI1hwglk=; b=02Y2hvcjAnKbN/d1EOE18d58nncvvqAwCwneC+Z5EMdAFJhK20jyUdveLU4AWhcNMq hl0h7ug1SzaTZw+lVZqi05FrOS1r50IZ37Wy7sL1gkL+AEd5lQmvdz5Dz5oZeWATl54m cOTK/R31etSlfxaOKYLD8JgVTnGV8pICTDNAIqtgC71mkVqscuuxTqEB6h7iGoQXQpWd JsO8hD5PnDokyQbJi9RRt8w/J7vKoWQpG/rLVXqwi4vEqLWzouKKKC528o8f0+Es8sIl 9ZsCfUe6vTBrNgOrtUwH1/JmzgSJ/ErmZlxwd0iGkdECh53+lzKsAQyjTCOBjsLJqY4u X1Rw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=d8m/zjwm; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id u9sor2419pfh.13.2017.10.30.15.29.29 for (Google Transport Security); Mon, 30 Oct 2017 15:29:29 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=d8m/zjwm; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+t5v60/lBsJv/2HCuJrnV4Tg64928uHOpN9NI1hwglk=; b=d8m/zjwmKd0AXAt5gjkstMOJqINYDidZ1nT1cyuiX7vVsTfZBeuCKBR7lxXSuhD44L u5z1rWeWQ11HUo/xZSHvS4tpd9RcmwEd4lluASKMdIN1cyeHR/090X+Y/8apTskSk1YB ygQP1qD6d616dryAa6LbkDIT1Ula1YyV7mjfI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+t5v60/lBsJv/2HCuJrnV4Tg64928uHOpN9NI1hwglk=; b=Se3e7hd9Hof/lQqRJZ3v5fhbK7tvJwvy5aNikZekGt4c3EB4KZagOZQ4r5+1ACIk1q MWW1ZOoHZhZg1r1UgUyAmpCUd+1CcGaBnxLIIj4DSI9owHHvB3C6RVaoQGZXRg8YlGg6 zoXaOUD+heVYcI1Rx4ebcKftzMNVVqxnLk8Bvu2h7X6xGlQ83ivcbL9kCUkOiBmHYZv3 ujuY1G7G71AfHMKMPy36bK0mFBZ8Ax3iepVaiKoR4OGhgFKf9PTCvW30d4Ot+jTn6fcF Xt5n569ZR1H06E6SOAUNX87jPzugR4Y40+6R5vSAWcPc2G5FUQxgpQ7taYQlSnmlIV91 UlsQ== X-Gm-Message-State: AMCzsaV0YlJy7S0b6MpuKoX/XO7zOQFgBf1z9GL03Q8/ri+lcUxRHeIL J3Vu4/cFflJqEMng8kx3OCdcAdzZ X-Google-Smtp-Source: ABhQp+Ry94OHDzP7JiWRasuFfGQ8VzwjplB6yjkj1jlGb0ZrUmOb3YpM8kS7TV3kNU3o173UKQ2H4g== X-Received: by 10.98.148.9 with SMTP id m9mr10026751pfe.111.1509402569575; Mon, 30 Oct 2017 15:29:29 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g13sm27479320pfm.130.2017.10.30.15.29.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Oct 2017 15:29:28 -0700 (PDT) From: John Stultz To: lkml Cc: Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 4/7] time: Remove unused functions Date: Mon, 30 Oct 2017 15:29:11 -0700 Message-Id: <1509402554-18437-5-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> References: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> From: Arnd Bergmann The (slow but) ongoing work on conversion from timespec to timespec64 has led some timespec based helper functions to become unused. No new code should use them, so we can remove the functions entirely. I'm planning to obsolete additional interfaces next and remove more of these. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Signed-off-by: Arnd Bergmann Signed-off-by: John Stultz --- include/linux/time.h | 18 ------------------ include/linux/time64.h | 28 ---------------------------- kernel/time/time.c | 18 ------------------ 3 files changed, 64 deletions(-) -- 2.7.4 diff --git a/include/linux/time.h b/include/linux/time.h index c0fbad0..0e8a809 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -39,15 +39,6 @@ static inline int timespec_compare(const struct timespec *lhs, const struct time return lhs->tv_nsec - rhs->tv_nsec; } -static inline int timeval_compare(const struct timeval *lhs, const struct timeval *rhs) -{ - if (lhs->tv_sec < rhs->tv_sec) - return -1; - if (lhs->tv_sec > rhs->tv_sec) - return 1; - return lhs->tv_usec - rhs->tv_usec; -} - extern time64_t mktime64(const unsigned int year, const unsigned int mon, const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec); @@ -65,15 +56,6 @@ static inline unsigned long mktime(const unsigned int year, extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec); -/* - * timespec_add_safe assumes both values are positive and checks - * for overflow. It will return TIME_T_MAX if the reutrn would be - * smaller then either of the arguments. - */ -extern struct timespec timespec_add_safe(const struct timespec lhs, - const struct timespec rhs); - - static inline struct timespec timespec_add(struct timespec lhs, struct timespec rhs) { diff --git a/include/linux/time64.h b/include/linux/time64.h index 980c71b..402b595c7 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -53,16 +53,6 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ts; } -static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64) -{ - return *its64; -} - -static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its) -{ - return *its; -} - # define timespec64_equal timespec_equal # define timespec64_compare timespec_compare # define set_normalized_timespec64 set_normalized_timespec @@ -94,24 +84,6 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ret; } -static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64) -{ - struct itimerspec ret; - - ret.it_interval = timespec64_to_timespec(its64->it_interval); - ret.it_value = timespec64_to_timespec(its64->it_value); - return ret; -} - -static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its) -{ - struct itimerspec64 ret; - - ret.it_interval = timespec_to_timespec64(its->it_interval); - ret.it_value = timespec_to_timespec64(its->it_value); - return ret; -} - static inline int timespec64_equal(const struct timespec64 *a, const struct timespec64 *b) { diff --git a/kernel/time/time.c b/kernel/time/time.c index 04684e2..947fb61 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -819,24 +819,6 @@ unsigned long nsecs_to_jiffies(u64 n) EXPORT_SYMBOL_GPL(nsecs_to_jiffies); /* - * Add two timespec values and do a safety check for overflow. - * It's assumed that both values are valid (>= 0) - */ -struct timespec timespec_add_safe(const struct timespec lhs, - const struct timespec rhs) -{ - struct timespec res; - - set_normalized_timespec(&res, lhs.tv_sec + rhs.tv_sec, - lhs.tv_nsec + rhs.tv_nsec); - - if (res.tv_sec < lhs.tv_sec || res.tv_sec < rhs.tv_sec) - res.tv_sec = TIME_T_MAX; - - return res; -} - -/* * Add two timespec64 values and do a safety check for overflow. * It's assumed that both values are valid (>= 0). * And, each timespec64 is in normalized form. From patchwork Mon Oct 30 22:29:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 117509 Delivered-To: patches@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3120376qgn; Mon, 30 Oct 2017 15:29:31 -0700 (PDT) X-Received: by 10.99.56.19 with SMTP id f19mr9037558pga.328.1509402571859; Mon, 30 Oct 2017 15:29:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509402571; cv=none; d=google.com; s=arc-20160816; b=vmoG0WOJq/YmYJjuWuFaWDJLU7NEZN3vpwVmOf9OfxhzOQxGH7hfaIFv4qGf4B6vSS bXFeW0PqJEhvHOeZy5MoW1RgkjqraP4w3CG/AurMgA0I+e8RdZnZ542AawZ843/3Lvxp GMTN9HUhFBl6rwk+5mR0li5tkuIIyDNPq3NCSDn6wKABdpMFTeNU3WMol+14U4fyV5+B gb3nq2px7MTQMfD4rE1OXt3pgZOLMwW1gj6rZfkuGm2D8aZoMCrrYWKapxhXyx0M5KlF qTW84T/tv6GH1OqA4Fn2fXdjNVxrl/PVlShR92ykz18URJ40oZtMbfEDvRx5gKrhJWT5 tWMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=ti9LOKchJxL5aGyQuvdQurPlTdVBqmn1QckT0IbSsMw=; b=B29+yPybZPGLY6n5pFjgEN34NYmfwCBeoB0Jo2VeiR3r/HkNVZSDmu/jxU06wKD2sV 4KUjF/ev5yTXyHnKqm0HQM6fpDM/Alo34aV0zUr1qaElrZQucfuh4PmQWcJ1w3P7NL1Q r8+gG3tHtevHUwZ6F4r/BFd/RL12yyr4en7hSt8dbWJl8mDqCNT9/AlliOLoG1YPSe5/ rN1ag6LfXLW6vacRN8NefflQNJSb4LglW5TH2wXBP5Jy+1IS7/MeU4O184OqiaLcz0xK ZmvsDoHFgep6AYOmtYA/4WVcslk7dWBf0NqM01S7nReJRI0z7jAcYHH/JXXMMSL3DVf0 huwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MpkGvCMQ; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id l5sor4194646pli.125.2017.10.30.15.29.31 for (Google Transport Security); Mon, 30 Oct 2017 15:29:31 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MpkGvCMQ; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ti9LOKchJxL5aGyQuvdQurPlTdVBqmn1QckT0IbSsMw=; b=MpkGvCMQfXCVxlHg3kNznrhOMVIv9FpbWfo6sars7Xrw0mKoproKF8fo9XH0U3LVIz CDQ35gRv4BMBMyzyl+cfbzHs1LGNprmT4Aq+YgvJmjeZQlvT4wFUIpDPz6whlsNtwP8y Zdl/ROQ4+XAHcCL0SqQz6XXbTcxlNRfiflJ1Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ti9LOKchJxL5aGyQuvdQurPlTdVBqmn1QckT0IbSsMw=; b=SXFIquQWxrOA7o+np5nRbRImfphDJLqfDXU1a2562PXFe+QWfSTcvjLH11IHFqdr2N JkLsII2svXNZwgH2vehJcskme0NKCI8wFfVDkeNN+zsWyAhl6u7cSrlmMCHkKBJIOmhb SIXnce3vdXDopYf1TzDvKTJuDjgkr8M+x2rqauUHk/gkGreI8s9E7lxjA1UMPGbZ7nXx VP8Ac/v+4l3xk8d+VqTnWcxJrpv7r2NMoRsF5is5GIJA7Ot/rc0voBmnI22AtqEgUCcN /b9CUcIT+z/d8cqS15jCQpBv7wCehH/fLnagQV+9JnsQqrtNHWg3iOfVHRt/NNIA1f3S JOew== X-Gm-Message-State: AMCzsaV6kKeEL/n45u+JLfD3CZg3qUjsNMqLkJQLZsnlEa1gegyHJ12W d5C7vfyDAyur0wlR+E8j+B2RUZ2yrnifyA== X-Google-Smtp-Source: ABhQp+RJFFHqndVjallR3ikvI1jjjYZne24dY37pljvafbzEeUYKh2jL3XLvzpO2M8tpbbZlDjiy/g== X-Received: by 10.159.253.9 with SMTP id p9mr8675594pls.323.1509402571445; Mon, 30 Oct 2017 15:29:31 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g13sm27479320pfm.130.2017.10.30.15.29.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Oct 2017 15:29:30 -0700 (PDT) From: John Stultz To: lkml Cc: Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 5/7] time: Move time_t based interfaces to time32.h Date: Mon, 30 Oct 2017 15:29:12 -0700 Message-Id: <1509402554-18437-6-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> References: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> From: Arnd Bergmann Interfaces based on 'struct timespec' or 'struct timeval' should no longer be used for new code, which can use either ktime_t or 'struct timespec64' instead. To make this a little clearer, this moves the various helpers into a new time32.h header. For the moment, this gets included by the normal time.h, but we may be able to separate it entirely when most users of time32.h are gone. Individual helpers in the new file can get removed once they become unused in the future. Since the contents of time32.h look a lot like what's in time64.h, I'm reordering them during the move to make them more similar, and to allow a follow-up patch to redirect the 'timespec' based functions to thei 'timespec64' based counterparts on 64-bit architectures later. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Signed-off-by: Arnd Bergmann [jstultz: Whitespace & checkpatch fixups] Signed-off-by: John Stultz --- include/linux/time.h | 163 +-------------------------------------------- include/linux/time32.h | 176 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 162 deletions(-) create mode 100644 include/linux/time32.h -- 2.7.4 diff --git a/include/linux/time.h b/include/linux/time.h index 0e8a809..c375f54 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -17,105 +17,10 @@ int get_itimerspec64(struct itimerspec64 *it, int put_itimerspec64(const struct itimerspec64 *it, struct itimerspec __user *uit); -#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) - -static inline int timespec_equal(const struct timespec *a, - const struct timespec *b) -{ - return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec); -} - -/* - * lhs < rhs: return <0 - * lhs == rhs: return 0 - * lhs > rhs: return >0 - */ -static inline int timespec_compare(const struct timespec *lhs, const struct timespec *rhs) -{ - if (lhs->tv_sec < rhs->tv_sec) - return -1; - if (lhs->tv_sec > rhs->tv_sec) - return 1; - return lhs->tv_nsec - rhs->tv_nsec; -} - extern time64_t mktime64(const unsigned int year, const unsigned int mon, const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec); -/** - * Deprecated. Use mktime64(). - */ -static inline unsigned long mktime(const unsigned int year, - const unsigned int mon, const unsigned int day, - const unsigned int hour, const unsigned int min, - const unsigned int sec) -{ - return mktime64(year, mon, day, hour, min, sec); -} - -extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec); - -static inline struct timespec timespec_add(struct timespec lhs, - struct timespec rhs) -{ - struct timespec ts_delta; - set_normalized_timespec(&ts_delta, lhs.tv_sec + rhs.tv_sec, - lhs.tv_nsec + rhs.tv_nsec); - return ts_delta; -} - -/* - * sub = lhs - rhs, in normalized form - */ -static inline struct timespec timespec_sub(struct timespec lhs, - struct timespec rhs) -{ - struct timespec ts_delta; - set_normalized_timespec(&ts_delta, lhs.tv_sec - rhs.tv_sec, - lhs.tv_nsec - rhs.tv_nsec); - return ts_delta; -} - -/* - * Returns true if the timespec is norm, false if denorm: - */ -static inline bool timespec_valid(const struct timespec *ts) -{ - /* Dates before 1970 are bogus */ - if (ts->tv_sec < 0) - return false; - /* Can't have more nanoseconds then a second */ - if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) - return false; - return true; -} - -static inline bool timespec_valid_strict(const struct timespec *ts) -{ - if (!timespec_valid(ts)) - return false; - /* Disallow values that could overflow ktime_t */ - if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) - return false; - return true; -} - -static inline bool timeval_valid(const struct timeval *tv) -{ - /* Dates before 1970 are bogus */ - if (tv->tv_sec < 0) - return false; - - /* Can't have more microseconds then a second */ - if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) - return false; - - return true; -} - -extern struct timespec timespec_trunc(struct timespec t, unsigned gran); - /* Some architectures do not supply their own clocksource. * This is mainly the case in architectures that get their * inter-tick times by reading the counter on their interval @@ -164,73 +69,7 @@ struct tm { void time64_to_tm(time64_t totalsecs, int offset, struct tm *result); -/** - * time_to_tm - converts the calendar time to local broken-down time - * - * @totalsecs the number of seconds elapsed since 00:00:00 on January 1, 1970, - * Coordinated Universal Time (UTC). - * @offset offset seconds adding to totalsecs. - * @result pointer to struct tm variable to receive broken-down time - */ -static inline void time_to_tm(time_t totalsecs, int offset, struct tm *result) -{ - time64_to_tm(totalsecs, offset, result); -} - -/** - * timespec_to_ns - Convert timespec to nanoseconds - * @ts: pointer to the timespec variable to be converted - * - * Returns the scalar nanosecond representation of the timespec - * parameter. - */ -static inline s64 timespec_to_ns(const struct timespec *ts) -{ - return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec; -} - -/** - * timeval_to_ns - Convert timeval to nanoseconds - * @ts: pointer to the timeval variable to be converted - * - * Returns the scalar nanosecond representation of the timeval - * parameter. - */ -static inline s64 timeval_to_ns(const struct timeval *tv) -{ - return ((s64) tv->tv_sec * NSEC_PER_SEC) + - tv->tv_usec * NSEC_PER_USEC; -} - -/** - * ns_to_timespec - Convert nanoseconds to timespec - * @nsec: the nanoseconds value to be converted - * - * Returns the timespec representation of the nsec parameter. - */ -extern struct timespec ns_to_timespec(const s64 nsec); - -/** - * ns_to_timeval - Convert nanoseconds to timeval - * @nsec: the nanoseconds value to be converted - * - * Returns the timeval representation of the nsec parameter. - */ -extern struct timeval ns_to_timeval(const s64 nsec); - -/** - * timespec_add_ns - Adds nanoseconds to a timespec - * @a: pointer to timespec to be incremented - * @ns: unsigned nanoseconds value to be added - * - * This must always be inlined because its used from the x86-64 vdso, - * which cannot call other kernel functions. - */ -static __always_inline void timespec_add_ns(struct timespec *a, u64 ns) -{ - a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns); - a->tv_nsec = ns; -} +# include static inline bool itimerspec64_valid(const struct itimerspec64 *its) { diff --git a/include/linux/time32.h b/include/linux/time32.h new file mode 100644 index 0000000..9b9c43f --- /dev/null +++ b/include/linux/time32.h @@ -0,0 +1,176 @@ +#ifndef _LINUX_TIME32_H +#define _LINUX_TIME32_H +/* + * These are all interfaces based on the old time_t definition + * that overflows in 2038 on 32-bit architectures. New code + * should use the replacements based on time64_t and timespec64. + * + * Any interfaces in here that become unused as we migrate + * code to time64_t should get removed. + */ + +#include + +#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) + +static inline int timespec_equal(const struct timespec *a, + const struct timespec *b) +{ + return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec); +} + +/* + * lhs < rhs: return <0 + * lhs == rhs: return 0 + * lhs > rhs: return >0 + */ +static inline int timespec_compare(const struct timespec *lhs, const struct timespec *rhs) +{ + if (lhs->tv_sec < rhs->tv_sec) + return -1; + if (lhs->tv_sec > rhs->tv_sec) + return 1; + return lhs->tv_nsec - rhs->tv_nsec; +} + +extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec); + +static inline struct timespec timespec_add(struct timespec lhs, + struct timespec rhs) +{ + struct timespec ts_delta; + + set_normalized_timespec(&ts_delta, lhs.tv_sec + rhs.tv_sec, + lhs.tv_nsec + rhs.tv_nsec); + return ts_delta; +} + +/* + * sub = lhs - rhs, in normalized form + */ +static inline struct timespec timespec_sub(struct timespec lhs, + struct timespec rhs) +{ + struct timespec ts_delta; + + set_normalized_timespec(&ts_delta, lhs.tv_sec - rhs.tv_sec, + lhs.tv_nsec - rhs.tv_nsec); + return ts_delta; +} + +/* + * Returns true if the timespec is norm, false if denorm: + */ +static inline bool timespec_valid(const struct timespec *ts) +{ + /* Dates before 1970 are bogus */ + if (ts->tv_sec < 0) + return false; + /* Can't have more nanoseconds then a second */ + if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) + return false; + return true; +} + +static inline bool timespec_valid_strict(const struct timespec *ts) +{ + if (!timespec_valid(ts)) + return false; + /* Disallow values that could overflow ktime_t */ + if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) + return false; + return true; +} + +/** + * timespec_to_ns - Convert timespec to nanoseconds + * @ts: pointer to the timespec variable to be converted + * + * Returns the scalar nanosecond representation of the timespec + * parameter. + */ +static inline s64 timespec_to_ns(const struct timespec *ts) +{ + return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec; +} + +/** + * ns_to_timespec - Convert nanoseconds to timespec + * @nsec: the nanoseconds value to be converted + * + * Returns the timespec representation of the nsec parameter. + */ +extern struct timespec ns_to_timespec(const s64 nsec); + +/** + * timespec_add_ns - Adds nanoseconds to a timespec + * @a: pointer to timespec to be incremented + * @ns: unsigned nanoseconds value to be added + * + * This must always be inlined because its used from the x86-64 vdso, + * which cannot call other kernel functions. + */ +static __always_inline void timespec_add_ns(struct timespec *a, u64 ns) +{ + a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns); + a->tv_nsec = ns; +} + +/** + * time_to_tm - converts the calendar time to local broken-down time + * + * @totalsecs the number of seconds elapsed since 00:00:00 on January 1, 1970, + * Coordinated Universal Time (UTC). + * @offset offset seconds adding to totalsecs. + * @result pointer to struct tm variable to receive broken-down time + */ +static inline void time_to_tm(time_t totalsecs, int offset, struct tm *result) +{ + time64_to_tm(totalsecs, offset, result); +} + +static inline unsigned long mktime(const unsigned int year, + const unsigned int mon, const unsigned int day, + const unsigned int hour, const unsigned int min, + const unsigned int sec) +{ + return mktime64(year, mon, day, hour, min, sec); +} + +static inline bool timeval_valid(const struct timeval *tv) +{ + /* Dates before 1970 are bogus */ + if (tv->tv_sec < 0) + return false; + + /* Can't have more microseconds then a second */ + if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) + return false; + + return true; +} + +extern struct timespec timespec_trunc(struct timespec t, unsigned int gran); + +/** + * timeval_to_ns - Convert timeval to nanoseconds + * @ts: pointer to the timeval variable to be converted + * + * Returns the scalar nanosecond representation of the timeval + * parameter. + */ +static inline s64 timeval_to_ns(const struct timeval *tv) +{ + return ((s64) tv->tv_sec * NSEC_PER_SEC) + + tv->tv_usec * NSEC_PER_USEC; +} + +/** + * ns_to_timeval - Convert nanoseconds to timeval + * @nsec: the nanoseconds value to be converted + * + * Returns the timeval representation of the nsec parameter. + */ +extern struct timeval ns_to_timeval(const s64 nsec); + +#endif From patchwork Mon Oct 30 22:29:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 117510 Delivered-To: patches@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3120395qgn; Mon, 30 Oct 2017 15:29:33 -0700 (PDT) X-Received: by 10.101.64.198 with SMTP id u6mr9044088pgp.44.1509402573331; Mon, 30 Oct 2017 15:29:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509402573; cv=none; d=google.com; s=arc-20160816; b=OlRT6RK9xURBSmg405jjWax6KUlXyXs1E+GUlSrvZiOyQxRtQHIkaVhRtWMGIUJsj/ I+3+5vu7hNcpCgDXAO2+9hoIi0MMc5YlHhMS085f1jWnIfC2vcUXbTq2yPF6FDHdyCmF O3+1uXdnfU8JFsm68KIYg5HO25C7f+VMtr4KD1RzQF8VvXXpxj2s5o6MyadQL+e4GSoo RRXz/YGY9PQkrBDaQzpDUsoXMhpbumppN+wz2KqpOUeYF/eRRgu5jnPdx19SU/nvBf98 ZLM6zu9Zxjz0SsnsJOAQpT77A5QjwngMZZ0JcH/er3PxHv9nsL2qNe+3dhv2v7Cw2+Tr LW5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=PhUB2YYEL41LMm6SJUh2B2XgySMfg6h/YjnKgXK8054=; b=P9ng0NbL3SsmxhYhO+uXAfH/sh220PKKcZUp+d1e6QXO1dwIZTsjaiBI53RQPwQfop 17bf7HKM/r2wYBJ0H1OYNL2XCFqN0BNb09aLFbi6RjERfGyK5YXBX5JDphtn4ELsTzpe ZACL3G0qMMW1bZDcfle8iB064LLdoXOrE1wKnqDuejqlXY+L6j28XXxpVb+4wJoO0kBc ioPzjcpGKPmmRXoVy9g1eDWmDELLF6bQoWqFhe+GrVfClcK1WZpUuOvbdwkVL/DH/aat VYyh2r1jvAJMuYUIAt2UwFtdHdJHacvhWwI/CfC2i9WdLhe5W6wG7qWRreVPRmEdsb4e XXNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Qn2UwZyj; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id n89sor1657pfh.19.2017.10.30.15.29.33 for (Google Transport Security); Mon, 30 Oct 2017 15:29:33 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Qn2UwZyj; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PhUB2YYEL41LMm6SJUh2B2XgySMfg6h/YjnKgXK8054=; b=Qn2UwZyj7vylF+V9bGnE8W9RMAv3cpWN73De4tSZrcLb/JTAX+psX+KfD+kPhEqo1I Ywb3FSMUBnkAs3NN+rhFqtOGJPimd0FSpLkM2jeOsrtMMqUXhsfRxMmXh4qaTR5cn2z3 4RCGEwvv8+jpMVH3COR0EySlfFJvxRIBzp4Wk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PhUB2YYEL41LMm6SJUh2B2XgySMfg6h/YjnKgXK8054=; b=lY05179k8O5I/U10Id29RHVnA28ibKRINs8piYfAIAub5BLHSaipqoqs9bnZKScE83 R6myaAxwvtcPrfypqpGhVGbk/sPLiD3f8jZn4aDzAg+HMRfd90z92K3rFTSrfQONTBB5 wWpn6t8yN9ktYoNC4iXldhwvesW/Vvwkp2ltDODR+LSwLlwZ42HReyFt6uHo3fde9wL4 dT8JFw3k3hEflY8dQ8HylFGiOId5UVrefWlo903obvncKoi6TB2lxJuD4Pds55kyuiUq VgWUhQCBUhSt7WC6Hol+vK0CVagprjJ4ex6zDsHykpiyvNibjuo+EfN7+vtH76xH96ts lj7Q== X-Gm-Message-State: AMCzsaXevEzrGO6i/+X0QHq9iXRigXD0cAtqZZMNJbQbgpZ/6mxTOafX HmVSiPkuz5+7EBGjPae7aqXDcWXR X-Google-Smtp-Source: ABhQp+Qz6h7drtYgmRY5HALyQETSiAqIrsO4olLVglVMn3yjQenudU4+p+ysNT7URo0czoE/J8RQGA== X-Received: by 10.98.147.197 with SMTP id r66mr10273781pfk.20.1509402572900; Mon, 30 Oct 2017 15:29:32 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g13sm27479320pfm.130.2017.10.30.15.29.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Oct 2017 15:29:31 -0700 (PDT) From: John Stultz To: lkml Cc: Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 6/7] time: Move time_t conversion helpers to time32.h Date: Mon, 30 Oct 2017 15:29:13 -0700 Message-Id: <1509402554-18437-7-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> References: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> From: Arnd Bergmann On 64-bit architectures, the timespec64 based helpers in linux/time.h are defined as macros pointing to their timespec based counterparts. This made sense when they were first introduced, but as we are migrating away from timespec in general, it's much less intuitive now. This changes the macros to work in the exact opposite way: we always provide the timespec64 based helpers and define the old interfaces as macros for them. Now we can move those macros into linux/time32.h, which already contains the respective helpers for 32-bit architectures. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Signed-off-by: Arnd Bergmann Signed-off-by: John Stultz --- include/linux/time32.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/time64.h | 50 +------------------------------------------------- kernel/time/time.c | 5 +++-- 3 files changed, 49 insertions(+), 51 deletions(-) -- 2.7.4 diff --git a/include/linux/time32.h b/include/linux/time32.h index 9b9c43f..65b1de2 100644 --- a/include/linux/time32.h +++ b/include/linux/time32.h @@ -13,6 +13,49 @@ #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) +#if __BITS_PER_LONG == 64 + +/* timespec64 is defined as timespec here */ +static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) +{ + return ts64; +} + +static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) +{ + return ts; +} + +# define timespec_equal timespec64_equal +# define timespec_compare timespec64_compare +# define set_normalized_timespec set_normalized_timespec64 +# define timespec_add timespec64_add +# define timespec_sub timespec64_sub +# define timespec_valid timespec64_valid +# define timespec_valid_strict timespec64_valid_strict +# define timespec_to_ns timespec64_to_ns +# define ns_to_timespec ns_to_timespec64 +# define timespec_add_ns timespec64_add_ns + +#else +static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) +{ + struct timespec ret; + + ret.tv_sec = (time_t)ts64.tv_sec; + ret.tv_nsec = ts64.tv_nsec; + return ret; +} + +static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) +{ + struct timespec64 ret; + + ret.tv_sec = ts.tv_sec; + ret.tv_nsec = ts.tv_nsec; + return ret; +} + static inline int timespec_equal(const struct timespec *a, const struct timespec *b) { @@ -116,6 +159,8 @@ static __always_inline void timespec_add_ns(struct timespec *a, u64 ns) a->tv_nsec = ns; } +#endif + /** * time_to_tm - converts the calendar time to local broken-down time * diff --git a/include/linux/time64.h b/include/linux/time64.h index 402b595c7..ec1888c 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -7,11 +7,8 @@ typedef __s64 time64_t; typedef __u64 timeu64_t; -/* - * This wants to go into uapi/linux/time.h once we agreed about the - * userspace interfaces. - */ #if __BITS_PER_LONG == 64 +/* this trick allows us to optimize out timespec64_to_timespec */ # define timespec64 timespec #define itimerspec64 itimerspec #else @@ -41,49 +38,6 @@ struct itimerspec64 { #define KTIME_MAX ((s64)~((u64)1 << 63)) #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) -#if __BITS_PER_LONG == 64 - -static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) -{ - return ts64; -} - -static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) -{ - return ts; -} - -# define timespec64_equal timespec_equal -# define timespec64_compare timespec_compare -# define set_normalized_timespec64 set_normalized_timespec -# define timespec64_add timespec_add -# define timespec64_sub timespec_sub -# define timespec64_valid timespec_valid -# define timespec64_valid_strict timespec_valid_strict -# define timespec64_to_ns timespec_to_ns -# define ns_to_timespec64 ns_to_timespec -# define timespec64_add_ns timespec_add_ns - -#else - -static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) -{ - struct timespec ret; - - ret.tv_sec = (time_t)ts64.tv_sec; - ret.tv_nsec = ts64.tv_nsec; - return ret; -} - -static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) -{ - struct timespec64 ret; - - ret.tv_sec = ts.tv_sec; - ret.tv_nsec = ts.tv_nsec; - return ret; -} - static inline int timespec64_equal(const struct timespec64 *a, const struct timespec64 *b) { @@ -185,8 +139,6 @@ static __always_inline void timespec64_add_ns(struct timespec64 *a, u64 ns) a->tv_nsec = ns; } -#endif - /* * timespec64_add_safe assumes both values are positive and checks for * overflow. It will return TIME64_MAX in case of overflow. diff --git a/kernel/time/time.c b/kernel/time/time.c index 947fb61..fe60ebd 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -407,6 +407,7 @@ time64_t mktime64(const unsigned int year0, const unsigned int mon0, } EXPORT_SYMBOL(mktime64); +#if __BITS_PER_LONG == 32 /** * set_normalized_timespec - set timespec sec and nsec parts and normalize * @@ -467,6 +468,7 @@ struct timespec ns_to_timespec(const s64 nsec) return ts; } EXPORT_SYMBOL(ns_to_timespec); +#endif /** * ns_to_timeval - Convert nanoseconds to timeval @@ -486,7 +488,6 @@ struct timeval ns_to_timeval(const s64 nsec) } EXPORT_SYMBOL(ns_to_timeval); -#if BITS_PER_LONG == 32 /** * set_normalized_timespec - set timespec sec and nsec parts and normalize * @@ -547,7 +548,7 @@ struct timespec64 ns_to_timespec64(const s64 nsec) return ts; } EXPORT_SYMBOL(ns_to_timespec64); -#endif + /** * msecs_to_jiffies: - convert milliseconds to jiffies * @m: time in milliseconds From patchwork Mon Oct 30 22:29:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 117511 Delivered-To: patches@linaro.org Received: by 10.140.22.164 with SMTP id 33csp3120423qgn; Mon, 30 Oct 2017 15:29:34 -0700 (PDT) X-Received: by 10.98.204.157 with SMTP id j29mr10245658pfk.236.1509402574776; Mon, 30 Oct 2017 15:29:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509402574; cv=none; d=google.com; s=arc-20160816; b=mIIkqQmSujOc1WXN1HaX4oQ8b/MMEpAtpDjBHQE1ksHVA7y5uPvgydpJV2CE/PF0M8 f3a9AyM/0ozQB+fvnyRyXGbpPAx/sGPQcp70IQL6iBVKhqHEpChu2fTbUlIVPHwKkCvf n1fxMPwbboh+znRsHigybqfC3ZknlQG6YxbLEVj1OOjIjL5pduKxNtp5+ocqtAo1tWoK HgWJTPZRj8rKEPB2UG1kA1+3A230rgisi//8D2Tw3KTBv9bqrwuStrOPghRDxSCohce7 FtdLcrka6e6LYrpK70DlrO7yzbCMjYUr1N7WNpMfWXaRJVrCG1XXPekHFdcQFkMVogiN Rd8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=NiNp4rT9SMi8mgow5LcPtFY8In2XP19gBPmAZ67v/2Q=; b=RgFRj6mxZT2WGdwnJ1Qw0ttJxmfqkzByYl0sz1ZypuQw+HsPIUNFFVlX4YpS+g/qDK N/dNYWxuN2rlKMIgDliQl02yMsbT0l0q6J9vojxs7kNCLkOGiw3tJ37eYwb+z9cdn6L1 BWUVw5IWapGEeTH2a3iHIZ4HA8BS4b16sfOqAFqo0NsYXpkdpNXpPd2dwg5Hd1btA5CJ 8y00rFh1S66hc0gAzvrMtasvKSEFcziwALBFYpfOUZL04UKg8K5Hl6xVQhxMgj/kjjmV 2vMZDVBo75ddxS79yMLspvigWr+5N4fbFXc70rTIWusk7rqXpnYm7Tllkwtw0nbs6pRS X5yg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Znvkb1Zh; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id t67sor4222210pfi.75.2017.10.30.15.29.34 for (Google Transport Security); Mon, 30 Oct 2017 15:29:34 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Znvkb1Zh; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=NiNp4rT9SMi8mgow5LcPtFY8In2XP19gBPmAZ67v/2Q=; b=Znvkb1ZhmJrova2rd3/WcTL2dG6xW3L3TtRugYGAI35oJprh2O/CqTsU9GkxkJCFGf EJ/pcJpnUQZMsFFnNWwZafNFx056yDvC7Qp/AbhSL/p9R0t1qnbQPoSWK1htlCYhOLAM 6/uG95MwrSanME0KwE4BVlll1ornh6dxnjFnI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NiNp4rT9SMi8mgow5LcPtFY8In2XP19gBPmAZ67v/2Q=; b=gTgwmxCjIFApXweoa2PfqOMsOC7U1r8lhYQiDngnpm0+wYppV0eSy2SN4rCqJe1I+I CFimOdzfjVrzwmyIt5HkFfK5SxQrMfBpRKHTFHUYUTuFpRA0gaRgWGm/XejmvJ7BJWBV 1TzALiSEIyM8QmSULjnASOBVNnVFJC/KVGv+Hk+XlEnsVCjgOBKzOBpzEOsHlJ7MUAVH vYPjhqRLh/HM0xZs7DE+dUoHrzd5TXqFPGfGqtG7CTEJn3dh9++v/CVtzK0zX0rbeR54 ivGBhtBZ13KNzsoyTYoYS0Dv3l4xQE75NkHL7+4AmgdLdQqx35LmzXqqkzU99YyYg25B Fb4Q== X-Gm-Message-State: AMCzsaV4PiDUa6iQ2a62jMbIdqo+tZebGkdcRoJTbU03CBAyFhmPzNEF KEiFp4u2lf6ktYdvvIgJXt9PcTnE X-Google-Smtp-Source: ABhQp+TwrOK1y5oW3pvfBRuO/1wxI9oeVGtgnd+8qKSQvpD6jIcVWRqZ4gBP3xeHVJyjLMvoXolinw== X-Received: by 10.98.186.13 with SMTP id k13mr10204898pff.166.1509402574359; Mon, 30 Oct 2017 15:29:34 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g13sm27479320pfm.130.2017.10.30.15.29.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Oct 2017 15:29:33 -0700 (PDT) From: John Stultz To: lkml Cc: Arnd Bergmann , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , John Stultz Subject: [PATCH 7/7] time: Move old timekeeping interfaces to timekeeping32.h Date: Mon, 30 Oct 2017 15:29:14 -0700 Message-Id: <1509402554-18437-8-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> References: <1509402554-18437-1-git-send-email-john.stultz@linaro.org> From: Arnd Bergmann The interfaces based on 'struct timespec' and 'unsigned long' seconds are no longer recommended for new code, and we are trying to migrate to ktime_t based interfaces and other y2038-safe variants. This moves all the legacy interfaces from linux/timekeeping.h into a new timekeeping32.h to better document this. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Signed-off-by: Arnd Bergmann Signed-off-by: John Stultz --- include/linux/ktime.h | 1 + include/linux/timekeeping.h | 137 +------------------------------------- include/linux/timekeeping32.h | 151 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 135 deletions(-) create mode 100644 include/linux/timekeeping32.h -- 2.7.4 diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 0c8bd45..5b9fddb 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -270,5 +270,6 @@ static inline ktime_t ms_to_ktime(u64 ms) } # include +# include #endif diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index ddc229f..405beea4e 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -15,27 +15,16 @@ extern void xtime_update(unsigned long ticks); /* * Get and set timeofday */ -extern void do_gettimeofday(struct timeval *tv); extern int do_settimeofday64(const struct timespec64 *ts); extern int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz); /* * Kernel time accessors */ -unsigned long get_seconds(void); struct timespec64 current_kernel_time64(void); -/* does not take xtime_lock */ -struct timespec __current_kernel_time(void); - -static inline struct timespec current_kernel_time(void) -{ - struct timespec64 now = current_kernel_time64(); - - return timespec64_to_timespec(now); -} /* - * timespec based interfaces + * timespec64 based interfaces */ struct timespec64 get_monotonic_coarse64(void); extern void getrawmonotonic64(struct timespec64 *ts); @@ -47,116 +36,6 @@ extern int __getnstimeofday64(struct timespec64 *tv); extern void getnstimeofday64(struct timespec64 *tv); extern void getboottime64(struct timespec64 *ts); -#if BITS_PER_LONG == 64 -/** - * Deprecated. Use do_settimeofday64(). - */ -static inline int do_settimeofday(const struct timespec *ts) -{ - return do_settimeofday64(ts); -} - -static inline int __getnstimeofday(struct timespec *ts) -{ - return __getnstimeofday64(ts); -} - -static inline void getnstimeofday(struct timespec *ts) -{ - getnstimeofday64(ts); -} - -static inline void ktime_get_ts(struct timespec *ts) -{ - ktime_get_ts64(ts); -} - -static inline void ktime_get_real_ts(struct timespec *ts) -{ - getnstimeofday64(ts); -} - -static inline void getrawmonotonic(struct timespec *ts) -{ - getrawmonotonic64(ts); -} - -static inline struct timespec get_monotonic_coarse(void) -{ - return get_monotonic_coarse64(); -} - -static inline void getboottime(struct timespec *ts) -{ - return getboottime64(ts); -} -#else -/** - * Deprecated. Use do_settimeofday64(). - */ -static inline int do_settimeofday(const struct timespec *ts) -{ - struct timespec64 ts64; - - ts64 = timespec_to_timespec64(*ts); - return do_settimeofday64(&ts64); -} - -static inline int __getnstimeofday(struct timespec *ts) -{ - struct timespec64 ts64; - int ret = __getnstimeofday64(&ts64); - - *ts = timespec64_to_timespec(ts64); - return ret; -} - -static inline void getnstimeofday(struct timespec *ts) -{ - struct timespec64 ts64; - - getnstimeofday64(&ts64); - *ts = timespec64_to_timespec(ts64); -} - -static inline void ktime_get_ts(struct timespec *ts) -{ - struct timespec64 ts64; - - ktime_get_ts64(&ts64); - *ts = timespec64_to_timespec(ts64); -} - -static inline void ktime_get_real_ts(struct timespec *ts) -{ - struct timespec64 ts64; - - getnstimeofday64(&ts64); - *ts = timespec64_to_timespec(ts64); -} - -static inline void getrawmonotonic(struct timespec *ts) -{ - struct timespec64 ts64; - - getrawmonotonic64(&ts64); - *ts = timespec64_to_timespec(ts64); -} - -static inline struct timespec get_monotonic_coarse(void) -{ - return timespec64_to_timespec(get_monotonic_coarse64()); -} - -static inline void getboottime(struct timespec *ts) -{ - struct timespec64 ts64; - - getboottime64(&ts64); - *ts = timespec64_to_timespec(ts64); -} -#endif - #define ktime_get_real_ts64(ts) getnstimeofday64(ts) /* @@ -241,23 +120,13 @@ extern u64 ktime_get_raw_fast_ns(void); extern u64 ktime_get_boot_fast_ns(void); /* - * Timespec interfaces utilizing the ktime based ones + * timespec64 interfaces utilizing the ktime based ones */ -static inline void get_monotonic_boottime(struct timespec *ts) -{ - *ts = ktime_to_timespec(ktime_get_boottime()); -} - static inline void get_monotonic_boottime64(struct timespec64 *ts) { *ts = ktime_to_timespec64(ktime_get_boottime()); } -static inline void timekeeping_clocktai(struct timespec *ts) -{ - *ts = ktime_to_timespec(ktime_get_clocktai()); -} - static inline void timekeeping_clocktai64(struct timespec64 *ts) { *ts = ktime_to_timespec64(ktime_get_clocktai()); @@ -340,10 +209,8 @@ extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot); */ extern int persistent_clock_is_local; -extern void read_persistent_clock(struct timespec *ts); extern void read_persistent_clock64(struct timespec64 *ts); extern void read_boot_clock64(struct timespec64 *ts); -extern int update_persistent_clock(struct timespec now); extern int update_persistent_clock64(struct timespec64 now); diff --git a/include/linux/timekeeping32.h b/include/linux/timekeeping32.h new file mode 100644 index 0000000..af4114d --- /dev/null +++ b/include/linux/timekeeping32.h @@ -0,0 +1,151 @@ +#ifndef _LINUX_TIMEKEEPING32_H +#define _LINUX_TIMEKEEPING32_H +/* + * These interfaces are all based on the old timespec type + * and should get replaced with the timespec64 based versions + * over time so we can remove the file here. + */ + +extern void do_gettimeofday(struct timeval *tv); +unsigned long get_seconds(void); + +/* does not take xtime_lock */ +struct timespec __current_kernel_time(void); + +static inline struct timespec current_kernel_time(void) +{ + struct timespec64 now = current_kernel_time64(); + + return timespec64_to_timespec(now); +} + +#if BITS_PER_LONG == 64 +/** + * Deprecated. Use do_settimeofday64(). + */ +static inline int do_settimeofday(const struct timespec *ts) +{ + return do_settimeofday64(ts); +} + +static inline int __getnstimeofday(struct timespec *ts) +{ + return __getnstimeofday64(ts); +} + +static inline void getnstimeofday(struct timespec *ts) +{ + getnstimeofday64(ts); +} + +static inline void ktime_get_ts(struct timespec *ts) +{ + ktime_get_ts64(ts); +} + +static inline void ktime_get_real_ts(struct timespec *ts) +{ + getnstimeofday64(ts); +} + +static inline void getrawmonotonic(struct timespec *ts) +{ + getrawmonotonic64(ts); +} + +static inline struct timespec get_monotonic_coarse(void) +{ + return get_monotonic_coarse64(); +} + +static inline void getboottime(struct timespec *ts) +{ + return getboottime64(ts); +} +#else +/** + * Deprecated. Use do_settimeofday64(). + */ +static inline int do_settimeofday(const struct timespec *ts) +{ + struct timespec64 ts64; + + ts64 = timespec_to_timespec64(*ts); + return do_settimeofday64(&ts64); +} + +static inline int __getnstimeofday(struct timespec *ts) +{ + struct timespec64 ts64; + int ret = __getnstimeofday64(&ts64); + + *ts = timespec64_to_timespec(ts64); + return ret; +} + +static inline void getnstimeofday(struct timespec *ts) +{ + struct timespec64 ts64; + + getnstimeofday64(&ts64); + *ts = timespec64_to_timespec(ts64); +} + +static inline void ktime_get_ts(struct timespec *ts) +{ + struct timespec64 ts64; + + ktime_get_ts64(&ts64); + *ts = timespec64_to_timespec(ts64); +} + +static inline void ktime_get_real_ts(struct timespec *ts) +{ + struct timespec64 ts64; + + getnstimeofday64(&ts64); + *ts = timespec64_to_timespec(ts64); +} + +static inline void getrawmonotonic(struct timespec *ts) +{ + struct timespec64 ts64; + + getrawmonotonic64(&ts64); + *ts = timespec64_to_timespec(ts64); +} + +static inline struct timespec get_monotonic_coarse(void) +{ + return timespec64_to_timespec(get_monotonic_coarse64()); +} + +static inline void getboottime(struct timespec *ts) +{ + struct timespec64 ts64; + + getboottime64(&ts64); + *ts = timespec64_to_timespec(ts64); +} +#endif + +/* + * Timespec interfaces utilizing the ktime based ones + */ +static inline void get_monotonic_boottime(struct timespec *ts) +{ + *ts = ktime_to_timespec(ktime_get_boottime()); +} + +static inline void timekeeping_clocktai(struct timespec *ts) +{ + *ts = ktime_to_timespec(ktime_get_clocktai()); +} + +/* + * Persistent clock related interfaces + */ +extern void read_persistent_clock(struct timespec *ts); +extern int update_persistent_clock(struct timespec now); + +#endif