From patchwork Thu Mar 12 04:16:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 45720 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 0D53B214BF for ; Thu, 12 Mar 2015 04:17:07 +0000 (UTC) Received: by lams18 with SMTP id s18sf9771748lam.2 for ; Wed, 11 Mar 2015 21:17:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=vOauSO/gIHEzCjmjcOOiCk6YObzlyckG28iHWAPeWQc=; b=jHwJOjRkutgW2w9+2dzLU6rvl55bsY72GXNtGuhivtgi12wnEgQBGcixw2AQl+cTGX u6H6oXNnxF44RCDVRUTVzF4TpQUIPM9ymDTYKsZ5PA9M9j3+rYQiEbY7hkYlzi4b2PD2 sgX6ue4xTWSWd/JRoI3sotjoyjimDpXTiw5jvmxfMY1mh1jQ37s9AyTQ3+YWBiI3nBH0 /7QTJp8RI/32CvuQFGqj7BpUs71rg9EK8lWN1fytvBvR5q98NXa389JRxtmpqhavVx2T r1+cgezK0ZdWCOpQ/LZQepjM2JYyllfV3XAlLfpYOjPxcedDysxmskVytz0UPTA8L9N9 AK5Q== X-Gm-Message-State: ALoCoQl4N2H5ddD/jv3DnkXsZCLz1LOmSW4Wd4J7JNs44EexJKnhPP2EWnmkgj4yMx4iwEXvjcRS X-Received: by 10.152.21.9 with SMTP id r9mr5967873lae.0.1426133825592; Wed, 11 Mar 2015 21:17:05 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.180.75 with SMTP id dm11ls237032lac.70.gmail; Wed, 11 Mar 2015 21:17:05 -0700 (PDT) X-Received: by 10.112.139.136 with SMTP id qy8mr37342402lbb.38.1426133825423; Wed, 11 Mar 2015 21:17:05 -0700 (PDT) Received: from mail-la0-f54.google.com (mail-la0-f54.google.com. [209.85.215.54]) by mx.google.com with ESMTPS id rl7si3575868lac.100.2015.03.11.21.17.05 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Mar 2015 21:17:05 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.54 as permitted sender) client-ip=209.85.215.54; Received: by lams18 with SMTP id s18so13259491lam.2 for ; Wed, 11 Mar 2015 21:17:05 -0700 (PDT) X-Received: by 10.152.8.15 with SMTP id n15mr10465930laa.41.1426133825263; Wed, 11 Mar 2015 21:17:05 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.35.133 with SMTP id h5csp3173274lbj; Wed, 11 Mar 2015 21:17:04 -0700 (PDT) X-Received: by 10.70.42.70 with SMTP id m6mr86479439pdl.19.1426133813367; Wed, 11 Mar 2015 21:16:53 -0700 (PDT) Received: from mail-pa0-f54.google.com (mail-pa0-f54.google.com. [209.85.220.54]) by mx.google.com with ESMTPS id u11si10465996pdl.240.2015.03.11.21.16.52 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Mar 2015 21:16:53 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.54 as permitted sender) client-ip=209.85.220.54; Received: by padfb1 with SMTP id fb1so17061963pad.7 for ; Wed, 11 Mar 2015 21:16:52 -0700 (PDT) X-Received: by 10.66.102.65 with SMTP id fm1mr84992253pab.115.1426133812479; Wed, 11 Mar 2015 21:16:52 -0700 (PDT) Received: from localhost.localdomain (c-67-170-153-23.hsd1.or.comcast.net. [67.170.153.23]) by mx.google.com with ESMTPSA id x1sm3070268pdp.1.2015.03.11.21.16.51 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 11 Mar 2015 21:16:51 -0700 (PDT) From: John Stultz To: lkml Cc: John Stultz , Dave Jones , Linus Torvalds , Thomas Gleixner , Richard Cochran , Prarit Bhargava , Stephen Boyd , Ingo Molnar , Peter Zijlstra Subject: [PATCH 07/12] time: Add warnings when overflows or underflows are observed Date: Wed, 11 Mar 2015 21:16:35 -0700 Message-Id: <1426133800-29329-8-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1426133800-29329-1-git-send-email-john.stultz@linaro.org> References: <1426133800-29329-1-git-send-email-john.stultz@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: john.stultz@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.54 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , It was suggested that the underflow/overflow protection should probably throw some sort of warning out, rather then just silently fixing the issue. So this patch adds some warnings here. The flag variables used are not protected by locks, but since we can't print from the reading functions, just being able to say we saw an issue in the update interval is useful enough, and can be slightly racy without real consequence. The big complication is that we're only under a read seqlock, so the data could shift under us during our calculation to see if there was a problem. This patch avoids this issue by nesting another seqlock which allows us to snapshot the just required values atomically. So we shouldn't see false positives. I also added some basic rate-limiting here, since on one build machine w/ skewed TSCs it was fairly noisy at bootup. Cc: Dave Jones Cc: Linus Torvalds Cc: Thomas Gleixner Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Cc: Ingo Molnar Cc: Peter Zijlstra Signed-off-by: John Stultz --- kernel/time/timekeeping.c | 62 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2ba62fe..a7204ad 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -119,6 +119,20 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta) } #ifdef CONFIG_DEBUG_TIMEKEEPING +#define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */ +/* + * These simple flag variables are managed + * without locks, which is racy, but ok since + * we don't really care about being super + * precise about how many events were seen, + * just that a problem was observed. + */ +static int timekeeping_underflow_seen; +static int timekeeping_overflow_seen; + +/* last_warning is only modified under the timekeeping lock */ +static long timekeeping_last_warning; + static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset) { @@ -134,28 +148,62 @@ static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset) offset, name, max_cycles>>1); } } + + if (timekeeping_underflow_seen) { + if (jiffies - timekeeping_last_warning > WARNING_FREQ) { + printk_deferred("WARNING: Clocksource %s underflow observed. You should report\n", name); + printk_deferred(" this, consider using a different clocksource.\n"); + timekeeping_last_warning = jiffies; + } + timekeeping_underflow_seen = 0; + } + + if (timekeeping_overflow_seen) { + if (jiffies - timekeeping_last_warning > WARNING_FREQ) { + printk_deferred("WARNING: Clocksource %s overflow observed. You should report\n", name); + printk_deferred(" this, consider using a different clocksource.\n"); + timekeeping_last_warning = jiffies; + } + timekeeping_overflow_seen = 0; + } } static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr) { - cycle_t cycle_now, delta; + cycle_t now, last, mask, max, delta; + unsigned int seq; - /* read clocksource */ - cycle_now = tkr->read(tkr->clock); + /* + * Since we're called holding a seqlock, the data may shift + * under us while we're doing the calculation. This can cause + * false positives, since we'd note a problem but throw the + * results away. So nest another seqlock here to atomically + * grab the points we are checking with. + */ + do { + seq = read_seqcount_begin(&tk_core.seq); + now = tkr->read(tkr->clock); + last = tkr->cycle_last; + mask = tkr->mask; + max = tkr->clock->max_cycles; + } while (read_seqcount_retry(&tk_core.seq, seq)); - /* calculate the delta since the last update_wall_time */ - delta = clocksource_delta(cycle_now, tkr->cycle_last, tkr->mask); + delta = clocksource_delta(now, last, mask); /* * Try to catch underflows by checking if we are seeing small * mask-relative negative values. */ - if (unlikely((~delta & tkr->mask) < (tkr->mask >> 3))) + if (unlikely((~delta & mask) < (mask >> 3))) { + timekeeping_underflow_seen = 1; delta = 0; + } /* Cap delta value to the max_cycles values to avoid mult overflows */ - if (unlikely(delta > tkr->clock->max_cycles)) + if (unlikely(delta > max)) { + timekeeping_overflow_seen = 1; delta = tkr->clock->max_cycles; + } return delta; }