From patchwork Tue Sep 11 23:26:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 11337 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 CCCCE23E02 for ; Tue, 11 Sep 2012 23:26:21 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id 3526A3D0A6B9 for ; Tue, 11 Sep 2012 23:26:21 +0000 (UTC) Received: by ieak11 with SMTP id k11so1847219iea.11 for ; Tue, 11 Sep 2012 16:26:20 -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:x-content-scanned:x-cbid :x-gm-message-state; bh=Quao3oJvX1zi+KQIXmcc7BF4+PBVn4TrbD1O9/un5bg=; b=hdilAuIL9UCujNzST+R3FOW8rzaSf8dVYRWla6S2eKWijVhlb1R5iiZF50C5G8bTKQ r3iD1RdzkYmhi5Pv37nQcz9t2EDA+OM9suQKgit8Da+lqCDMpyRI7qjajDTCymcB3E1P fx1P6flWOg7uOMBQTBLKvA915scEuAdX83a4bOduaTi9AMQ8jNJfCwQTuBCo1H79O/SA 2eCthfFv7p3a4Pi97JKb11jLamWg5gBBfb7P99Ca0uN4RQ59cnsPUwARaverWkeNgCZ7 hNub2ANF+kIZSdBrSgvhcUZLYsSgICiaMNZzDV6j/10ywx5ONp2yl+VH11+oh7djlD3l zs4Q== Received: by 10.50.242.3 with SMTP id wm3mr18235500igc.0.1347405980332; Tue, 11 Sep 2012 16:26:20 -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.184.232 with SMTP id ex8csp39957igc; Tue, 11 Sep 2012 16:26:19 -0700 (PDT) Received: by 10.50.193.202 with SMTP id hq10mr17755842igc.35.1347405979375; Tue, 11 Sep 2012 16:26:19 -0700 (PDT) Received: from e5.ny.us.ibm.com (e5.ny.us.ibm.com. [32.97.182.145]) by mx.google.com with ESMTPS id pp3si4886825igb.17.2012.09.11.16.26.18 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 11 Sep 2012 16:26:19 -0700 (PDT) Received-SPF: neutral (google.com: 32.97.182.145 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=32.97.182.145; Authentication-Results: mx.google.com; spf=neutral (google.com: 32.97.182.145 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 e5.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 11 Sep 2012 19:26:18 -0400 Received: from d01dlp02.pok.ibm.com (9.56.250.167) by e5.ny.us.ibm.com (192.168.1.105) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 11 Sep 2012 19:26:17 -0400 Received: from d01relay06.pok.ibm.com (d01relay06.pok.ibm.com [9.56.227.116]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id 596A36E803F; Tue, 11 Sep 2012 19:26:16 -0400 (EDT) Received: from d01av02.pok.ibm.com (d01av02.pok.ibm.com [9.56.224.216]) by d01relay06.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q8BNQGAU24051718; Tue, 11 Sep 2012 19:26:16 -0400 Received: from d01av02.pok.ibm.com (loopback [127.0.0.1]) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q8BNQFOA031192; Tue, 11 Sep 2012 20:26:15 -0300 Received: from kernel-pok.stglabs.ibm.com (kernel.stglabs.ibm.com [9.114.214.19]) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q8BNQF71031169; Tue, 11 Sep 2012 20:26:15 -0300 From: John Stultz To: Linux Kernel Cc: John Stultz , Ingo Molnar , Richard Cochran , Prarit Bhargava , Thomas Gleixner , Daniel Lezcano Subject: [PATCH] time: Fix timeekeping_get_ns overflow on 32bit systems Date: Tue, 11 Sep 2012 19:26:03 -0400 Message-Id: <1347405963-35715-1-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12091123-5930-0000-0000-00000BF27ADD X-Gm-Message-State: ALoCoQmpoiRcOJ2GIS+iGfhV1bbdkALFOSaDWU1IbmMFQL2bttE9g8m2++oLNJtKKd/xN+55chhD Thomas: Please queue this in tip/timers/urgent for 3.6. Daniel Lezcano reported seeing multi-second stalls from keyboard input on his T61 laptop when NOHZ and CPU_IDLE were enabled on a 32bit kernel. He bisected the problem down to 1e75fa8be9fb61e1af46b5b3b176347a4c958ca1 (time: Condense timekeeper.xtime into xtime_sec). After reproducing this issue, I narrowed the problem down to the fact that timekeeping_get_ns() returns a 64bit nsec value that hasn't been accumulated. In some cases this value was being then stored in timespec.tv_nsec (which is a long). On 32bit systems, With idle times larger then 4 seconds (or less, depending on the value of xtime_nsec), the returned nsec value would overflow 32bits. This limited kept time from increasing, causing timers to not expire. The fix is to make sure we don't directly store the result of timekeeping_get_ns() into a tv_nsec field, instead using a 64bit nsec value which can then be added into the timespec via timespec_add_ns(). Cc: Ingo Molnar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Daniel Lezcano Reported-and-bisected-by: Daniel Lezcano Tested-by: Daniel Lezcano Signed-off-by: John Stultz --- kernel/time/timekeeping.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 34e5eac..d3b91e7 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -303,10 +303,11 @@ void getnstimeofday(struct timespec *ts) seq = read_seqbegin(&tk->lock); ts->tv_sec = tk->xtime_sec; - ts->tv_nsec = timekeeping_get_ns(tk); + nsecs = timekeeping_get_ns(tk); } while (read_seqretry(&tk->lock, seq)); + ts->tv_nsec = 0; timespec_add_ns(ts, nsecs); } EXPORT_SYMBOL(getnstimeofday); @@ -345,6 +346,7 @@ void ktime_get_ts(struct timespec *ts) { struct timekeeper *tk = &timekeeper; struct timespec tomono; + s64 nsec; unsigned int seq; WARN_ON(timekeeping_suspended); @@ -352,13 +354,14 @@ void ktime_get_ts(struct timespec *ts) do { seq = read_seqbegin(&tk->lock); ts->tv_sec = tk->xtime_sec; - ts->tv_nsec = timekeeping_get_ns(tk); + nsec = timekeeping_get_ns(tk); tomono = tk->wall_to_monotonic; } while (read_seqretry(&tk->lock, seq)); - set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, - ts->tv_nsec + tomono.tv_nsec); + ts->tv_sec += tomono.tv_sec; + ts->tv_nsec = 0; + timespec_add_ns(ts, nsec + tomono.tv_nsec); } EXPORT_SYMBOL_GPL(ktime_get_ts); @@ -1244,6 +1247,7 @@ void get_monotonic_boottime(struct timespec *ts) { struct timekeeper *tk = &timekeeper; struct timespec tomono, sleep; + s64 nsec; unsigned int seq; WARN_ON(timekeeping_suspended); @@ -1251,14 +1255,15 @@ void get_monotonic_boottime(struct timespec *ts) do { seq = read_seqbegin(&tk->lock); ts->tv_sec = tk->xtime_sec; - ts->tv_nsec = timekeeping_get_ns(tk); + nsec = timekeeping_get_ns(tk); tomono = tk->wall_to_monotonic; sleep = tk->total_sleep_time; } while (read_seqretry(&tk->lock, seq)); - set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec, - ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec); + ts->tv_sec += tomono.tv_sec + sleep.tv_sec; + ts->tv_nsec = 0; + timespec_add_ns(ts, nsec + tomono.tv_nsec + sleep.tv_nsec); } EXPORT_SYMBOL_GPL(get_monotonic_boottime);