Received: by 10.223.185.111 with SMTP id b44csp901007wrg; Fri, 9 Mar 2018 16:23:38 -0800 (PST) X-Google-Smtp-Source: AG47ELs9Y/jtmbfRHyKicEgrqAk4tqZqCjcLY+IST3Gzjg/rKHlGnYFEkM0STzMCV2NqRDPiElqk X-Received: by 2002:a17:902:52a6:: with SMTP id a35-v6mr320608pli.179.1520641418280; Fri, 09 Mar 2018 16:23:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520641418; cv=none; d=google.com; s=arc-20160816; b=CkXQ08h1UZictJbe3FeICOhJU1ku3l6BM+VvObxDOjNIrasCYh4t3NJNjSVr3VQJqS r4ahoAk+oQGNEXIhzeSdXyTu2nE3mohl8mOEIWadv58zWLGsfnrbf8U5Y1nG5v0CtxUi AYJE3kR7+RHB07TTLqvXaNOz2mkZKieCe7l+WubxrLD4srNBzRU60SVObeYKuRa8sMF2 8pbVnQrzuvWDblBYtvydwW3I1XNF9bf1z/sWVKbtyXnspSm14+ZJfQ7jC71nk7R7ULdA zTcXnHdoOyRbKOFr5xsw6aNRsuuVvpFxkMlU0dClfg5rOO+lKYfjg4EI98Xlb6zZY3Fb V/1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=RYNECrt1jIGILlQjCQIVmDA3Cdehq3a7NLidrQqqOAg=; b=L30/qtI8uMmaoIv/evLfzRYXLPfN+n8tabEzZyl0HyzJ56DSALvl/+oHlByEEUm01G ODO+7KbXdjGdJqYG2EQXS/xAYJt+H2Yv6xNiwqcl5tXuylgZ1d+a3f5GdPQAMdGsHcgL A8p3HSViWuyIIxKqjKGohPzjAjQeVluM9gUBw5GP+i3+COdPAZo/eMHeEXl9j6g21JXM 1iZp6+osLPr5nQkftRlqKAaAo2KlfHUJqqCQDtsaDjRrSZ94Dek89ChHCR0pWZ8bw+Z4 r/WM8QPR1xJlCup6xTDZf0uPI7vSnar4Oja3Eer037M7XMje7IW9L8y6tXJ6wYjPjh1v W8pA== 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 c4si1462143pgu.355.2018.03.09.16.23.23; Fri, 09 Mar 2018 16:23:38 -0800 (PST) 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 S933593AbeCJAVE (ORCPT + 99 others); Fri, 9 Mar 2018 19:21:04 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:39368 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933544AbeCJAVA (ORCPT ); Fri, 9 Mar 2018 19:21:00 -0500 Received: from localhost (unknown [185.236.200.248]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 29F4BFD0; Sat, 10 Mar 2018 00:21:00 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Neeraj Upadhyay , Lingutla Chandrasekhar , Thomas Gleixner , Anna-Maria Gleixner , linux-arm-msm@vger.kernel.org Subject: [PATCH 4.9 11/65] timers: Forward timer base before migrating timers Date: Fri, 9 Mar 2018 16:18:11 -0800 Message-Id: <20180310001825.831610645@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180310001824.927996722@linuxfoundation.org> References: <20180310001824.927996722@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Lingutla Chandrasekhar commit c52232a49e203a65a6e1a670cd5262f59e9364a0 upstream. On CPU hotunplug the enqueued timers of the unplugged CPU are migrated to a live CPU. This happens from the control thread which initiated the unplug. If the CPU on which the control thread runs came out from a longer idle period then the base clock of that CPU might be stale because the control thread runs prior to any event which forwards the clock. In such a case the timers from the unplugged CPU are queued on the live CPU based on the stale clock which can cause large delays due to increased granularity of the outer timer wheels which are far away from base:;clock. But there is a worse problem than that. The following sequence of events illustrates it: - CPU0 timer1 is queued expires = 59969 and base->clk = 59131. The timer is queued at wheel level 2, with resulting expiry time = 60032 (due to level granularity). - CPU1 enters idle @60007, with next timer expiry @60020. - CPU0 is hotplugged at @60009 - CPU1 exits idle and runs the control thread which migrates the timers from CPU0 timer1 is now queued in level 0 for immediate handling in the next softirq because the requested expiry time 59969 is before CPU1 base->clk 60007 - CPU1 runs code which forwards the base clock which succeeds because the next expiring timer. which was collected at idle entry time is still set to 60020. So it forwards beyond 60007 and therefore misses to expire the migrated timer1. That timer gets expired when the wheel wraps around again, which takes between 63 and 630ms depending on the HZ setting. Address both problems by invoking forward_timer_base() for the control CPUs timer base. All other places, which might run into a similar problem (mod_timer()/add_timer_on()) already invoke forward_timer_base() to avoid that. [ tglx: Massaged comment and changelog ] Fixes: a683f390b93f ("timers: Forward the wheel clock whenever possible") Co-developed-by: Neeraj Upadhyay Signed-off-by: Neeraj Upadhyay Signed-off-by: Lingutla Chandrasekhar Signed-off-by: Thomas Gleixner Cc: Anna-Maria Gleixner Cc: linux-arm-msm@vger.kernel.org Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20180118115022.6368-1-clingutla@codeaurora.org Signed-off-by: Greg Kroah-Hartman --- kernel/time/timer.c | 6 ++++++ 1 file changed, 6 insertions(+) --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1884,6 +1884,12 @@ int timers_dead_cpu(unsigned int cpu) spin_lock_irq(&new_base->lock); spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); + /* + * The current CPUs base clock might be stale. Update it + * before moving the timers over. + */ + forward_timer_base(new_base); + BUG_ON(old_base->running_timer); for (i = 0; i < WHEEL_SIZE; i++)