Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp4534070imm; Mon, 17 Sep 2018 16:02:01 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbnRCrTOJPCpaYWuhIlAHfomM0hOa3qwCYsmyjNpty5gWNNZyK9QUSvgdPTJJF9i5CDS825 X-Received: by 2002:a62:9f4c:: with SMTP id g73-v6mr27914144pfe.142.1537225321558; Mon, 17 Sep 2018 16:02:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537225321; cv=none; d=google.com; s=arc-20160816; b=LQF62SEui23wFwBKOxKw/CS8EoY8V5MzrCUq68mPEIws7sifPVpkLOGJN1D/2JHBVq WFkWc3gO6OI5V2R81Kw9KjKS3Kw5whxsT83uogu2P0sQeFz+1bYAN/dJTULwNAG7wiIi CTlVbbnjLEZEYpzmRcIOwtaU0m/iIftFsKWhap4Hl6DjN2mOSUEVgLoltN4Bz/gLIz+t 43OBgInRVzLb1UsqyhKuFqONGp3/PC8FqT/kqOkI5AvkmgueHMZOUFlieDePURkRuSr1 tYtyohUQxMcFsGBfwkGfQ0hJNx9g902dBq5PifkNuYECht6N/hqjpcuaC4O9cBTIfcMl fF4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=VlgkC7dkeL5t0Ps7lHMmlqFY2p40z4oh/rQNL/5eTak=; b=dZqlBoYFxDy7eWjsCANsfiBw1Fwjc8JezGAoYscyrCDMaIE0zYRNf59tA4t6lP4a+Z 16a9bZo6d+nrN3a2cC95TUW4jc6o9jtqwWWnKCz2r38bPMRW5ZRXlJXEJgbOiLxmlLrV j8T5askAsUJBEWohQeg0MOoFJxrm4xM0FUA5ya2MnPCfqF6wBDVRtaXspEE4Z/zjQ4Bb cJjUpRE1yTD/lFI1b9gpJkltYmCrR+32iLU2LmkbF/Bapz1bxY/nWUGs+AigH79pZzUp Hpuf4oRcPMFtljUq4hLr0phHUjvBhbTI8Ir4XHfup4v4Bkxa0s4ULcRkyZHtuI0N6WWG 4x5A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a20-v6si15662987pgi.184.2018.09.17.16.01.45; Mon, 17 Sep 2018 16:02:01 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730194AbeIREaw (ORCPT + 99 others); Tue, 18 Sep 2018 00:30:52 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:48274 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728884AbeIREaw (ORCPT ); Tue, 18 Sep 2018 00:30:52 -0400 Received: from localhost (li1825-44.members.linode.com [172.104.248.44]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 9A63CC03; Mon, 17 Sep 2018 23:01:23 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Gaurav Kohli , Thomas Gleixner , john.stultz@linaro.org, sboyd@kernel.org, linux-arm-msm@vger.kernel.org, Sasha Levin Subject: [PATCH 4.14 035/126] timers: Clear timer_base::must_forward_clk with timer_base::lock held Date: Tue, 18 Sep 2018 00:41:23 +0200 Message-Id: <20180917211707.091416499@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180917211703.481236999@linuxfoundation.org> References: <20180917211703.481236999@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Gaurav Kohli [ Upstream commit 363e934d8811d799c88faffc5bfca782fd728334 ] timer_base::must_forward_clock is indicating that the base clock might be stale due to a long idle sleep. The forwarding of the base clock takes place in the timer softirq or when a timer is enqueued to a base which is idle. If the enqueue of timer to an idle base happens from a remote CPU, then the following race can happen: CPU0 CPU1 run_timer_softirq mod_timer base = lock_timer_base(timer); base->must_forward_clk = false if (base->must_forward_clk) forward(base); -> skipped enqueue_timer(base, timer, idx); -> idx is calculated high due to stale base unlock_timer_base(timer); base = lock_timer_base(timer); forward(base); The root cause is that timer_base::must_forward_clk is cleared outside the timer_base::lock held region, so the remote queuing CPU observes it as cleared, but the base clock is still stale. This can cause large granularity values for timers, i.e. the accuracy of the expiry time suffers. Prevent this by clearing the flag with timer_base::lock held, so that the forwarding takes place before the cleared flag is observable by a remote CPU. Signed-off-by: Gaurav Kohli Signed-off-by: Thomas Gleixner Cc: john.stultz@linaro.org Cc: sboyd@kernel.org Cc: linux-arm-msm@vger.kernel.org Link: https://lkml.kernel.org/r/1533199863-22748-1-git-send-email-gkohli@codeaurora.org Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- kernel/time/timer.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1609,6 +1609,22 @@ static inline void __run_timers(struct t raw_spin_lock_irq(&base->lock); + /* + * timer_base::must_forward_clk must be cleared before running + * timers so that any timer functions that call mod_timer() will + * not try to forward the base. Idle tracking / clock forwarding + * logic is only used with BASE_STD timers. + * + * The must_forward_clk flag is cleared unconditionally also for + * the deferrable base. The deferrable base is not affected by idle + * tracking and never forwarded, so clearing the flag is a NOOP. + * + * The fact that the deferrable base is never forwarded can cause + * large variations in granularity for deferrable timers, but they + * can be deferred for long periods due to idle anyway. + */ + base->must_forward_clk = false; + while (time_after_eq(jiffies, base->clk)) { levels = collect_expired_timers(base, heads); @@ -1628,19 +1644,6 @@ static __latent_entropy void run_timer_s { struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); - /* - * must_forward_clk must be cleared before running timers so that any - * timer functions that call mod_timer will not try to forward the - * base. idle trcking / clock forwarding logic is only used with - * BASE_STD timers. - * - * The deferrable base does not do idle tracking at all, so we do - * not forward it. This can result in very large variations in - * granularity for deferrable timers, but they can be deferred for - * long periods due to idle. - */ - base->must_forward_clk = false; - __run_timers(base); if (IS_ENABLED(CONFIG_NO_HZ_COMMON)) __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF]));