From patchwork Tue Jul 31 06:35:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 10376 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id C1F4E24000 for ; Tue, 31 Jul 2012 06:37:11 +0000 (UTC) Received: from mail-yw0-f52.google.com (mail-yw0-f52.google.com [209.85.213.52]) by fiordland.canonical.com (Postfix) with ESMTP id 7D0C7A18832 for ; Tue, 31 Jul 2012 06:37:11 +0000 (UTC) Received: by yhpp61 with SMTP id p61so5612206yhp.11 for ; Mon, 30 Jul 2012 23:37:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :x-content-scanned:x-cbid:x-gm-message-state; bh=E7brZ8P31nTKbZ+3UqlL+sw8eru/uU+XhM58iPVaO3c=; b=H+AN6HAGnuLbaJIGzaEVzSvpNRtz/CmP7kWi9qyhjJ8glpSlQdxWi5oRNGuWev9Xti 8mwIne0dAZPtBOXMqX5zXR3/vj8ks6be6NQURnOIoxvyvQ9C5BwrI1OcwDhFl4WtjrGM Q5eoLx2q9a4QtAnDbYY2RZ5cLZ76SMZtJARovfZBdrK3sndqBdEKHeJRJPx6nPE0savb 2jHQK25xRaXDjc+kyBj+aa1ebByIVZ2H7mcoTgaCdlI2vxefqlTLdhcIzOZv0AshEVzb krmjVz6YL1YEtyQhTpx4qpP4LZW2o4F3vRIJ9+rLcWE1oQDuuzjqXaI6PGIJr5ukDY+L qSUA== Received: by 10.50.47.161 with SMTP id e1mr1174818ign.11.1343716630638; Mon, 30 Jul 2012 23:37:10 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.87.40 with SMTP id u8csp126611igz; Mon, 30 Jul 2012 23:37:10 -0700 (PDT) Received: by 10.182.75.100 with SMTP id b4mr21687227obw.12.1343716630122; Mon, 30 Jul 2012 23:37:10 -0700 (PDT) Received: from e33.co.us.ibm.com (e33.co.us.ibm.com. [32.97.110.151]) by mx.google.com with ESMTPS id r4si10213715obz.162.2012.07.30.23.37.09 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 30 Jul 2012 23:37:10 -0700 (PDT) Received-SPF: neutral (google.com: 32.97.110.151 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=32.97.110.151; Authentication-Results: mx.google.com; spf=neutral (google.com: 32.97.110.151 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) smtp.mail=john.stultz@linaro.org Received: from /spool/local by e33.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 31 Jul 2012 00:37:09 -0600 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e33.co.us.ibm.com (192.168.1.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 31 Jul 2012 00:37:07 -0600 Received: from d03relay05.boulder.ibm.com (d03relay05.boulder.ibm.com [9.17.195.107]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id 52E2719D8039; Tue, 31 Jul 2012 06:36:36 +0000 (WET) Received: from d03av01.boulder.ibm.com (d03av01.boulder.ibm.com [9.17.195.167]) by d03relay05.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6V6aJ5a147176; Tue, 31 Jul 2012 00:36:24 -0600 Received: from d03av01.boulder.ibm.com (loopback [127.0.0.1]) by d03av01.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q6V6a3f8011093; Tue, 31 Jul 2012 00:36:04 -0600 Received: from kernel-pok.stglabs.ibm.com (kernel.stglabs.ibm.com [9.114.214.19]) by d03av01.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q6V6Zw2x010780; Tue, 31 Jul 2012 00:36:03 -0600 From: John Stultz To: linux-kernel Cc: John Stultz , Ingo Molnar , Peter Zijlstra , Prarit Bhargava , Thomas Gleixner , Zhouping Liu , CAI Qian Subject: [PATCH 1/2] [RFC] time: Fix problem with large timespecs & ktime_get_update_offsets Date: Tue, 31 Jul 2012 02:35:47 -0400 Message-Id: <1343716548-38742-2-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1343716548-38742-1-git-send-email-john.stultz@linaro.org> References: <1343716548-38742-1-git-send-email-john.stultz@linaro.org> X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12073106-2398-0000-0000-000008FF546E X-Gm-Message-State: ALoCoQnfbjWZSY3UuM1sODPkr3nVhwP+CvxW41hU7cIhkyWB7NN5/d7vxtv+SVBgIfhFgVmgXhac There's currently a slight difference in ktime_get_update_offsets() vs ktime_get() which can result in boot time crashes when booting with insane CMOS clock values larger then ~2264. ktime_get() does basically the following: return timespec_to_ktime(timespec_add(xtime, wall_to_monotonic)) Where as ktime_get_update_offsets does approximately: return ktime_sub(timespec_to_ktime(xtime), realtime_offset); The problem is, at boot we set xtime = year 8200 and wall_to_monotonic = year -8200, ktime_get adds both values, mostly nulling the difference out (leaving only how long the system has been up), then converts that relatively small value to a ktime_t properly without losing any information. ktime_get_update_offsets however, since it converts xtime (again set to some value greater then year 8200), to a ktime, it gets clamped at KTIME_MAX, then we subtract realtime_offset, which is _also_ clamped at KTIME_MAX, resulting in us always returning almost[1] zero. This causes us to stop expiring timers. Now, one of the reasons Thomas and I changed the logic was that using the precalculated realtime_offset was slightly more efficient then re-adding xtime and wall_to_monotonic's components separately. But how valuable this unmeasured slight efficiency is vs extra robustness for crazy time values is questionable. So switch back to the ktime_get implementation for ktime_get_update_offsets Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Zhouping Liu Cc: CAI Qian Reported-by: CAI Qian Signed-off-by: John Stultz --- kernel/time/timekeeping.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3447cfa..96179ab 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1283,15 +1283,15 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, */ ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) { - ktime_t now; unsigned int seq; u64 secs, nsecs; do { seq = read_seqbegin(&timekeeper.lock); - - secs = timekeeper.xtime.tv_sec; - nsecs = timekeeper.xtime.tv_nsec; + secs = timekeeper.xtime.tv_sec + + timekeeper.wall_to_monotonic.tv_sec; + nsecs = timekeeper.xtime.tv_nsec + + timekeeper.wall_to_monotonic.tv_nsec; nsecs += timekeeping_get_ns(); /* If arch requires, add in gettimeoffset() */ nsecs += arch_gettimeoffset(); @@ -1300,9 +1300,7 @@ ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) *offs_boot = timekeeper.offs_boot; } while (read_seqretry(&timekeeper.lock, seq)); - now = ktime_add_ns(ktime_set(secs, 0), nsecs); - now = ktime_sub(now, *offs_real); - return now; + return ktime_add_ns(ktime_set(secs, 0), nsecs); } #endif