Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp160917imm; Tue, 31 Jul 2018 15:54:35 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdEQvXsT2Cz9WggRlMwyFAQXqEVFjN5IH3q+oD3EOdZazX0QPHAOiIjzbWDJ9q96oOtsGeN X-Received: by 2002:a17:902:778e:: with SMTP id o14-v6mr14123623pll.198.1533077675839; Tue, 31 Jul 2018 15:54:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533077675; cv=none; d=google.com; s=arc-20160816; b=Q/sFoVIyCvT/ELRvQyUpQcPRFbq6aE2ayBPlLL8d9nZqZRkA+6YWkxah2p6JbSte9d klt1FGg0dy950nrtuJjF0mCh19ZBl03HCOcmlpxuRAqiZbcNvqh+dOPhk2g9FYtqnUKp zu0cBGtRmCRumwIuwYGhDvDmNDEPZF0wpNTxbDXi4RwDi8rdQJ5cx+FJJAbrY2s13IbD 4AU91nIpy398Tibw9H8wKl/qZhcEkYdtw8EVXwJ/YlTdgu/VbAuaQ5wePoL/UVQiT4f0 WcBs0Qw7DvBt5TS1kt8ox+xKzzfxfKmxWeWG6LSgfbd2fJd2iqcBW9MOcS1z/wq20jHk iKgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=EzE5YJbjLFU4Gwn+xQATRO4/Zt+3iVUVMvYzmOYSoL0=; b=cItSHFLgerJ+IZItAJVQz/br3vfRomvAxZ0Vs7S8IOMHFUgb5Qi74VdFWucQW10x99 oheqIip2b/p/9ESBrCFtBydPPW/JIfCyL/ostXqD7NNGo2tAi649aLtlBBlEdH/Exj2y xVrNETQH48IZR3FP4WcRpf3g7FtunRed5Cw9LNBEggdTF9wRu3NiEDVtwwkL+4rjJfcY JoG1c2hX93ZpHb9b/DAgnYw42BOK/pR6BKhz54VT4gxOhty+c82TyHEkDHGKOdfUzJC3 Csc4cR8BFTB4MNrIKXz0hE/0JchmEsC9fa7MecUIO/5Fh3sdujerKpsWUM+6dmpuvEzV gvEw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=DMTnbAey; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 144-v6si14167185pge.406.2018.07.31.15.54.21; Tue, 31 Jul 2018 15:54:35 -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; dkim=pass header.i=@kernel.org header.s=default header.b=DMTnbAey; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732752AbeHAAfc (ORCPT + 99 others); Tue, 31 Jul 2018 20:35:32 -0400 Received: from mail.kernel.org ([198.145.29.99]:40544 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732726AbeHAAfc (ORCPT ); Tue, 31 Jul 2018 20:35:32 -0400 Received: from lerouge.suse.de (LFbn-NCY-1-241-207.w83-194.abo.wanadoo.fr [83.194.85.207]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 32BCC2083F; Tue, 31 Jul 2018 22:52:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1533077578; bh=ZHeUqo/pMRqtkBIfDJ6t955UFCTuaX94qZUvrx2j0x8=; h=From:To:Cc:Subject:Date:From; b=DMTnbAeyCrbnu9urwrl91xNw3X2OGW7ap3uscOumq1HpNX86aLYmaCSjVYoFU3H/k TUcb4rNfgwxdXMub1oeYgqLn9qAz5XcLLrlDfqMMsjgeqCTERB0njCzMuenMvO/7k1 AebREKisqar2d5mkoeYAwRycH5VJwpFRTcuv8df8= From: Frederic Weisbecker To: Thomas Gleixner Cc: LKML , Frederic Weisbecker , Ingo Molnar , Anna-Maria Gleixner Subject: [PATCH] nohz: Fix missing tick reprog while interrupting inline timer softirq Date: Wed, 1 Aug 2018 00:52:50 +0200 Message-Id: <1533077570-9169-1-git-send-email-frederic@kernel.org> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Before updating the full nohz tick or the idle time on IRQ exit, we check first if we are not in a nesting interrupt, whether the inner interrupt is a hard or a soft IRQ. There is a historical reason for that: the dyntick idle mode used to reprogram the tick on IRQ exit, after softirq processing, and there was no point in doing that job in the outer nesting interrupt because the tick update will be performed through the end of the inner interrupt eventually, with even potential new timer updates. One corner case could show up though: if an idle tick interrupts a softirq executing inline in the idle loop (through a call to local_bh_enable()) after we entered in dynticks mode, the IRQ won't reprogram the tick because it assumes the softirq executes on an inner IRQ-tail. As a result we might put the CPU in sleep mode with the tick completely stopped whereas a timer can still be enqueued. Indeed there is no tick reprogramming in local_bh_enable(). We probably asssumed there was no bh disabled section in idle, although there didn't seem to be debug code ensuring that. Nowadays the nesting interrupt optimization still stands but only concern full dynticks. The tick is stopped on IRQ exit in full dynticks mode and we want to wait for the end of the inner IRQ to reprogramm the tick. But in_interrupt() doesn't make a difference between softirqs executing on IRQ tail and those executing inline. What was to be considered a corner case in dynticks-idle mode now becomes a serious opportunity for a bug in full dynticks mode: if a tick interrupts a task executing softirq inline, the tick reprogramming will be ignored and we may exit to userspace after local_bh_enable() with an enqueued timer that will never fire. To fix this, simply keep reprogramming the tick if we are in a hardirq interrupting softirq. We can still figure out a way later to restore this optimization while excluding inline softirq processing. Reported-by: Anna-Maria Gleixner Signed-off-by: Frederic Weisbecker Cc: Thomas Gleixner Cc: Ingo Molnar --- kernel/softirq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/softirq.c b/kernel/softirq.c index 900dcfe..0980a81 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -386,7 +386,7 @@ static inline void tick_irq_exit(void) /* Make sure that timer wheel updates are propagated */ if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) { - if (!in_interrupt()) + if (!in_irq()) tick_nohz_irq_exit(); } #endif -- 2.7.4