From patchwork Thu Dec 3 19:02:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 57667 Delivered-To: patches@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp108523lbb; Thu, 3 Dec 2015 11:02:38 -0800 (PST) X-Received: by 10.98.86.210 with SMTP id h79mr15499918pfj.87.1449169358009; Thu, 03 Dec 2015 11:02:38 -0800 (PST) Return-Path: Received: from mail-pa0-x234.google.com (mail-pa0-x234.google.com. [2607:f8b0:400e:c03::234]) by mx.google.com with ESMTPS id 73si13560008pfq.207.2015.12.03.11.02.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 03 Dec 2015 11:02:37 -0800 (PST) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c03::234 as permitted sender) client-ip=2607:f8b0:400e:c03::234; Authentication-Results: mx.google.com; spf=pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c03::234 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dkim=pass header.i=@linaro-org.20150623.gappssmtp.com Received: by pabfh17 with SMTP id fh17so75543078pab.0 for ; Thu, 03 Dec 2015 11:02:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=rBpn8Pu3+h6ErEBx0dIplYdXOYt0ysL+TjtUMyQWLPU=; b=gz0gLb6RRxl3l9TasfI9YVYWHvqMII2Eket72T3PdPcEEgyPKNdDIhEKRmpntaQGNR ISntmtrLzMa/Z7apQCtHvlrb5gmofWxLJeWWeo3SweBBMOe4+iCOjFzFPwco9Be3scUM X5j7ksbXmQx/Fr7R19o63y3psYf2Gk8AlBQPHwwyJ2h5ItMM9t44OpWaCm0D/mtyImkU YYCNhYmNxM9Qbc1QpK6ECMEEyh1E7IFPlTk7AOeAvo5StWuF7hbxIavYiklw46yCGMyn GyH6NMNEj2LwL+ZL1IHoDeIIg7DXMoBx6Tif9Psr2ZgsXMnvWGcO+lT1xvnMBY5IsERE f1Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=rBpn8Pu3+h6ErEBx0dIplYdXOYt0ysL+TjtUMyQWLPU=; b=Y59Xi2h9F/brc9Kl0YM+Af/EGI6mJ1NXa0OqWJxQey9NcywLl975gJqCJvtOIpGMWM dN5hQcMuuegU5IH3UC7mVHXzsrCPkSY7PDYAfqLafnVq0iqo9as0vyTOfGA7VQ/MUjat iCH31z2837qdKCSQTYC6ZZIkpPi/X0Q/1/2aBUrhAq+uHRpRhv3cRABf95ezvrrOvTSb FeaLBvo0t6Lqzu3fDEhlLXh2W46fgB9E8JLc5h6225g6ikafK0RXSpeNJ3O4r4WgDES9 06+Lw/L1tB9xROMxRkSRw/anKotTHUhq7fCjoqKBPq11F+Q8Hq6v7TqvHlw/rBDpW+HU eHtA== X-Gm-Message-State: ALoCoQn6PthCI2KDmBLKPmC65bzNws5I2wTgW1rVnAVW0kzjKADhkKRtCC7sasrsvrGDjGfMQgyQ X-Received: by 10.66.154.129 with SMTP id vo1mr15490825pab.152.1449169357607; Thu, 03 Dec 2015 11:02:37 -0800 (PST) Return-Path: Received: from localhost.localdomain (c-76-115-103-22.hsd1.or.comcast.net. [76.115.103.22]) by smtp.gmail.com with ESMTPSA id n18sm12230441pfi.29.2015.12.03.11.02.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 03 Dec 2015 11:02:36 -0800 (PST) From: John Stultz To: Miroslav Lichvar Cc: John Stultz Subject: [PRESEND][PATCH] timekeeping: Cap adjustments so they don't exceede the maxadj value Date: Thu, 3 Dec 2015 11:02:31 -0800 Message-Id: <1449169351-1901-1-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 Thus its been occasionally noted that users have seen confusing warnings like: Adjusting tsc more than 11% (5941981 vs 7759439) We try to limit the maximum total adjustment to 11% (10% tick adjustment + 0.5% frequency adjustment). But this is done by bounding the requested adjustment values, and the internal steering that is done by tracking the error from what was requested and what was applied, does not have any such limits. This is usually not problematic, but in some cases has a risk that an adjustment could cause the clocksource mult value to overflow, so its an indication things are outside of what is expected. It ends up most of the reports of this 11% warning are on systems using chrony, which utilizes the adjtimex() ADJ_TICK interface (which allows a +-10% adjustment). The original ratonal for ADJ_TICK unlcear to me but my assumption it was originally added to allow broken systems to get a big constant correction at boot (see adjtimex userspace package for an example) which would allow the system to work w/ ntpd's 0.5% adjustment limit. Chrony uses ADJ_TICK to make very aggressive short term corrections (usually right at startup). Which push us close enough to the max bound that a few late ticks can cause the internal steering to push past the max adjust value (tripping the warning). Thus this patch adds some extra logic to enforce the max adjustment cap in the internal steering. Signed-off-by: John Stultz --- kernel/time/timekeeping.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) -- 1.9.1 diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index d563c19..4e38902 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1594,7 +1594,9 @@ static __always_inline void timekeeping_freqadjust(struct timekeeper *tk, s64 xinterval = tk->xtime_interval; s64 tick_error; bool negative; - u32 adj; + u32 adj_scale; + s32 cur_adj; + u32 max; /* Remove any current error adj from freq calculation */ if (tk->ntp_err_mult) @@ -1613,13 +1615,24 @@ static __always_inline void timekeeping_freqadjust(struct timekeeper *tk, /* preserve the direction of correction */ negative = (tick_error < 0); - /* Sort out the magnitude of the correction */ + /* + * Sort out the magnitude of the correction, but + * avoid making so large a correction that we go + * over the max adjustment. + */ + adj_scale = 0; + max = tk->tkr_mono.clock->maxadj; + cur_adj = tk->tkr_mono.mult - tk->tkr_mono.clock->mult; tick_error = abs(tick_error); - for (adj = 0; tick_error > interval; adj++) + while((tick_error > interval) && + (abs(cur_adj - (1 << (adj_scale + 1)) < max)) && + (abs(cur_adj + (1 << (adj_scale + 1)) < max))) { + adj_scale++; tick_error >>= 1; + } /* scale the corrections */ - timekeeping_apply_adjustment(tk, offset, negative, adj); + timekeeping_apply_adjustment(tk, offset, negative, adj_scale); } /*