Received: by 10.192.165.148 with SMTP id m20csp5028376imm; Tue, 24 Apr 2018 12:24:06 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/Hhs0OwCxQVolVCwfa0YQm9mSerE4LyqOfHTwTNqHsgot21IjhDbucSoPMhFNBbZophSy0 X-Received: by 10.99.127.3 with SMTP id a3mr21075220pgd.267.1524597846922; Tue, 24 Apr 2018 12:24:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524597846; cv=none; d=google.com; s=arc-20160816; b=mmQXgRez/Ro1EjZAh+Cd6rwIQjLN6xqR1HGm756GtNMSY0b10keH6Tg8JdoR+uJjtM RtIdebne/XYK6uNRUraDBy6tZStucDw7JixFHrZ40e+LpWMepZ7CwxVvXuoc/qCybsef vKYgmcdAY9Zc+H0cSMbKGiyb+8J0czKvq1XIdPd5lDXOnljYvSeRvKT+TSlfQ6mfwG1+ ho1s9uqh79QMeCxj9Upk6/770je7b4t9B2/4RzvyQTHbo0LFrIT0N+Cbwwjdyla+PNI1 4YgtH2dM98xSCMgCfDGRfCA+lJC3owawb35YaPvyHeMaGp9iYKLCAdxkEJGX8SxV6M1U pFQQ== 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:message-id :subject:cc:to:from:date:arc-authentication-results; bh=T/PapprMUw8J4UgePDnu3E1qpZozu7SCmMLiBB37vGo=; b=u5WK+0DZqcR5qrE4nxD8CeFY7r5nguj0wlo5HpKikH8d+RzVEWWUt8r9GYNcnezc2U d/hUOW44kmhdaVfosMCE2yxU/loeLnJkyU055Oj8tlVA8fuk9mIJ62GmWL2zSZo8NL9s SYFzlB0qvqCbDSMmDnkB/j7Yvdbl3W8gfZ0sCqG8gkmun1vfS0sKlrwPXcbPmQ45TccP 1TjYJ8NS0cC4IhkSMKfvqJi1FIL0M8orZsN/eYILcgp+czJ+Fj5jZ00X2qWxCv1IDWy1 sBk4oMd8BgGjikUwYMF/cNgcI6ULPD6QLcQ9B1O/n1Bc1Fhr/XJIuTTm8h4Vbm3lky4K Ru9Q== 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 x124si12298704pgb.651.2018.04.24.12.23.52; Tue, 24 Apr 2018 12:24:06 -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 S1751280AbeDXTWY (ORCPT + 99 others); Tue, 24 Apr 2018 15:22:24 -0400 Received: from Galois.linutronix.de ([146.0.238.70]:37722 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750735AbeDXTWX (ORCPT ); Tue, 24 Apr 2018 15:22:23 -0400 Received: from p5492e61e.dip0.t-ipconnect.de ([84.146.230.30] helo=nanos.glx-home) by Galois.linutronix.de with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1fB3W7-00014k-7q; Tue, 24 Apr 2018 21:22:19 +0200 Date: Tue, 24 Apr 2018 21:22:18 +0200 (CEST) From: Thomas Gleixner To: Frederic Weisbecker cc: "Wan, Kaike" , "Marciniszyn, Mike" , "Dalessandro, Dennis" , "Weiny, Ira" , "Fleck, John" , "linux-kernel@vger.kernel.org" , "linux-rdma@vger.kernel.org" , Peter Zijlstra , Anna-Maria Gleixner , Frederic Weisbecker , Ingo Molnar Subject: [PATCH] tick/sched: Do not mess with an enqueued hrtimer Message-ID: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Kaike reported that in tests rdma hrtimers occasionaly stopped working. He did great debugging, which provided enough context to decode the problem. CPU 3 CPU 2 idle start sched_timer expires = 712171000000 queue->next = sched_timer start rdmavt timer. expires = 712172915662 lock(baseof(CPU3)) tick_nohz_stop_tick() tick = 716767000000 timerqueue_add(tmr) hrtimer_set_expires(sched_timer, tick); sched_timer->expires = 716767000000 <---- FAIL if (tmr->expires < queue->next->expires) hrtimer_start(sched_timer) queue->next = tmr; lock(baseof(CPU3)) unlock(baseof(CPU3)) timerqueue_remove() timerqueue_add() ts->sched_timer is queued and queue->next is pointing to it, but then ts->sched_timer.expires is modified. This not only corrupts the ordering of the timerqueue RB tree, it also makes CPU2 see the new expiry time of timerqueue->next->expires when checking whether timerqueue->next needs to be updated. So CPU2 sees that the rdma timer is earlier than timerqueue->next and sets the rdma timer as new next. Depending on whether it had also seen the new time at RB tree enqueue, it might have queued the rdma timer at the wrong place and then after removing the sched_timer the RB tree is completely hosed. The problem was introduced with a commit which tried to solve inconsistency between the hrtimer in the tick_sched data and the underlying hardware clockevent. It split out hrtimer_set_expires() to store the new tick time in both the NOHZ and the NOHZ + HIGHRES case, but missed the fact that in the NOHZ + HIGHRES case the hrtimer might still be queued. Use hrtimer_start(timer, tick...) for the NOHZ + HIGHRES case which sets timer->expires after canceling the timer and move the hrtimer_set_expires() invocation into the NOHZ only code path which is not affected as it merily uses the hrtimer as next event storage so code pathes can be shared with the NOHZ + HIGHRES case. Fixes: d4af6d933ccf ("nohz: Fix spurious warning when hrtimer and clockevent get out of sync") Reported-by: "Wan Kaike" Signed-off-by: Thomas Gleixner Cc: "Marciniszyn Mike" Cc: Anna-Maria Gleixner Cc: linux-rdma@vger.kernel.org Cc: "Dalessandro Dennis" Cc: "Fleck John" Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: "Weiny Ira" Cc: "linux-rdma@vger.kernel.org" Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1804241637390.1679@nanos.tec.linutronix.de --- kernel/time/tick-sched.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -804,12 +804,12 @@ static void tick_nohz_stop_tick(struct t return; } - hrtimer_set_expires(&ts->sched_timer, tick); - - if (ts->nohz_mode == NOHZ_MODE_HIGHRES) - hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED); - else + if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { + hrtimer_start(&ts->sched_timer, tick, HRTIMER_MODE_ABS_PINNED); + } else { + hrtimer_set_expires(&ts->sched_timer, tick); tick_program_event(tick, 1); + } } static void tick_nohz_retain_tick(struct tick_sched *ts)