From patchwork Sat Mar 7 02:49:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 45510 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f71.google.com (mail-wg0-f71.google.com [74.125.82.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id A4F2C214A0 for ; Sat, 7 Mar 2015 02:50:39 +0000 (UTC) Received: by wghb13 with SMTP id b13sf46298480wgh.2 for ; Fri, 06 Mar 2015 18:50:39 -0800 (PST) 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=Uy1KcD9cwPHm4WK8XDskPaPXUAVCkdYmQ/sTlXGM8EY=; b=jHfoBBMqHQ1pcFL183eP3ts48ox432puBswpG2S04pSp4lcT1LMtVPW4LIl/Cp8ExT yhFjh0I2s/sO3J3Hky4/14EuiWlL9NW7wQwJWKI9uXW9ZYfgyaM69oEVnclRE04gp2/o XUt+jfBgiVxZhSNQ0tKYjX141cAZcrqHNq2dVDber8Y0jOkL5e5yGOOlelUngZ71TkuE lNdLkIcvxFd+vLbhWLCARGOwTefSvVwG+6qP8CZgcUYRiA5+JEnNiX9HnlYyXd5As8Uz wdwczAg/p3SEVSQYNxyEUxYLwKhvfHRU/jrepGgQqjAj8HikxW9Rb03dNRqgjOvsBAqf sxoA== X-Gm-Message-State: ALoCoQlcnclpUI96x/VoAxbIPLXs1J7mc8FpPv9zkZJxpegYdgT0NaOZrVCxjjRaO8SqremQzn6Q X-Received: by 10.112.44.167 with SMTP id f7mr141006lbm.9.1425696638943; Fri, 06 Mar 2015 18:50:38 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.197.34 with SMTP id ir2ls134965lac.84.gmail; Fri, 06 Mar 2015 18:50:38 -0800 (PST) X-Received: by 10.112.160.10 with SMTP id xg10mr4659802lbb.83.1425696638798; Fri, 06 Mar 2015 18:50:38 -0800 (PST) Received: from mail-la0-f49.google.com (mail-la0-f49.google.com. [209.85.215.49]) by mx.google.com with ESMTPS id al5si1453318lbc.80.2015.03.06.18.50.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Mar 2015 18:50:38 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) client-ip=209.85.215.49; Received: by labgq15 with SMTP id gq15so7263292lab.13 for ; Fri, 06 Mar 2015 18:50:38 -0800 (PST) X-Received: by 10.112.224.3 with SMTP id qy3mr15639973lbc.36.1425696638699; Fri, 06 Mar 2015 18:50:38 -0800 (PST) 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 h5csp256478lbj; Fri, 6 Mar 2015 18:50:37 -0800 (PST) X-Received: by 10.68.68.240 with SMTP id z16mr31010118pbt.77.1425696632428; Fri, 06 Mar 2015 18:50:32 -0800 (PST) Received: from mail-pa0-f41.google.com (mail-pa0-f41.google.com. [209.85.220.41]) by mx.google.com with ESMTPS id ou8si14345392pdb.173.2015.03.06.18.50.31 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Mar 2015 18:50:32 -0800 (PST) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Received: by padet14 with SMTP id et14so32311439pad.11 for ; Fri, 06 Mar 2015 18:50:31 -0800 (PST) X-Received: by 10.66.218.231 with SMTP id pj7mr29955723pac.147.1425696631534; Fri, 06 Mar 2015 18:50:31 -0800 (PST) Received: from localhost.localdomain (c-67-170-153-23.hsd1.or.comcast.net. [67.170.153.23]) by mx.google.com with ESMTPSA id a2sm8381456pbu.27.2015.03.06.18.50.30 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Mar 2015 18:50:30 -0800 (PST) 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 08/12] time: Add warnings when overflows or underflows are observed Date: Fri, 6 Mar 2015 18:49:59 -0800 Message-Id: <1425696603-16878-9-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1425696603-16878-1-git-send-email-john.stultz@linaro.org> References: <1425696603-16878-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.49 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 consequnece. The big complication is that we're only under a read seqlock, so the data could shift under us during our calcualtion 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 ratelimiting 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 | 58 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 4e8ccde..5f62308 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -119,11 +119,23 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta) } #ifdef CONFIG_DEBUG_TIMEKEEPING +#define WARNINGFREQ (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; + static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset) { cycle_t max_cycles = tk->tkr.clock->max_cycles; const char *name = tk->tkr.clock->name; + static long last_warning; /* we always hold write on timekeeper lock */ if (offset > max_cycles) printk_deferred("ERROR: cycle offset (%lld) is larger then" @@ -133,28 +145,60 @@ static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset) printk_deferred("WARNING: cycle offset (%lld) is past" " the %s 50%% safety margin (%lld)\n", offset, name, max_cycles>>1); + + if (timekeeping_underflow_seen) { + if (jiffies - last_warning > WARNINGFREQ) { + printk_deferred("WARNING: Clocksource underflow observed\n"); + last_warning = jiffies; + } + timekeeping_underflow_seen = 0; + } + if (timekeeping_overflow_seen) { + if (jiffies - last_warning > WARNINGFREQ) { + printk_deferred("WARNING: Clocksource overflow observed\n"); + 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 doign 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; }