Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp3597105pxb; Mon, 24 Jan 2022 13:08:54 -0800 (PST) X-Google-Smtp-Source: ABdhPJy75v4fSz2zWQd6Y7PzbGpa6fPVc40LCe1R+678dfWhOlgV+3kEvgWZpXdGiqEMQRKcJ1Yt X-Received: by 2002:a17:902:d10a:b0:14b:4a73:8778 with SMTP id w10-20020a170902d10a00b0014b4a738778mr7202768plw.53.1643058534524; Mon, 24 Jan 2022 13:08:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643058534; cv=none; d=google.com; s=arc-20160816; b=gOWNlbYa5Glr4tW3RGwWbZBsStI24wevfcniW6QpqbjZzQLe7Z8wKsl/rRWcfeAcH9 kciWPS1FHsHI+yK0aw0uMjFLTigsGf232qvIN6QZlwIdk/chgLqC5B2KhEhULTmd5Zdy YZxS2+o3+VZ6bvq8uI/4j5A+5I53TnaYd6MfDWNQgQ4szJFBZ9ans94REKORiY90KBq7 epIZqQ6dLEL6iZFg6QaGEKJ78X7LweuoJyqFDIUKG9WElfGtl/zZKL93NPCf3rqprGPk AR5IVk+i//n/ZsxXA+dxm5Vj7om1OoAYq22GOxlu+AAvNTOb8jrmSkryUpnnLYJiYlQ1 coag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=e/xgYC17YEhNzX0dcoTyJ7yqD6yS1JKRtpkLFv0hi4c=; b=dt1JQfo2Umk5pYPT23KV6CJaOcFXIA5a4+BVp1WUTdLMKb5Fmwttbr5DG+ePs5Q4CA HlAMYSVDjbWK7i9a8a8YKAf3wZumm0hSDUq5YWO+biL27fuS4ac8DCFzJ4gZziNXvi4I YohV7be0/6TEiPgDwVGU/V1VypWsw49rCCkLGGoI5brHGmQM/CkqzLyma88pM0WId3RP jTVZqLEsUOE+Kui08O262YLy/4B/2uGHOfnq+cHSndNI67TNnz7bJDSNXetC6PrpTgSA FiT4WR24poz34z2JFvRJ7UrhtabbXU7grOOtkCYLVLS6kCfLLQerRZoiu6TyQIiXiutL vMdA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=u4r6HlSD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z3si2152376pfe.355.2022.01.24.13.08.33; Mon, 24 Jan 2022 13:08:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=u4r6HlSD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1385606AbiAXUdm (ORCPT + 99 others); Mon, 24 Jan 2022 15:33:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349334AbiAXUNj (ORCPT ); Mon, 24 Jan 2022 15:13:39 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C5B0C061765; Mon, 24 Jan 2022 11:35:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0BFB7614FC; Mon, 24 Jan 2022 19:35:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E3356C340E5; Mon, 24 Jan 2022 19:35:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643052956; bh=fqghv2tM9KQdZtwnpamw7ZoE6favq2oByT6WYmfaJKk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u4r6HlSDzXweTuTb2eNTILEfjgfGJ8oyVtGra3tkhSXsGLC8LjgIRcOMz6h2ZleiW LRGQY4JHBlJEnuhjMzAz840sYAtzOqt72h0laZf1eeYzrl9g5eFIHXIygXFG9uUIr2 GlIUVcGNlxLSBurDZNUUh+lFvkpwpEMs14/2AYX8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Nicholas Piggin , Laurent Dufour , Michael Ellerman , Sasha Levin Subject: [PATCH 5.4 228/320] powerpc/watchdog: Fix missed watchdog reset due to memory ordering race Date: Mon, 24 Jan 2022 19:43:32 +0100 Message-Id: <20220124184001.741509727@linuxfoundation.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220124183953.750177707@linuxfoundation.org> References: <20220124183953.750177707@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Nicholas Piggin [ Upstream commit 5dad4ba68a2483fc80d70b9dc90bbe16e1f27263 ] It is possible for all CPUs to miss the pending cpumask becoming clear, and then nobody resetting it, which will cause the lockup detector to stop working. It will eventually expire, but watchdog_smp_panic will avoid doing anything if the pending mask is clear and it will never be reset. Order the cpumask clear vs the subsequent test to close this race. Add an extra check for an empty pending mask when the watchdog fires and finds its bit still clear, to try to catch any other possible races or bugs here and keep the watchdog working. The extra test in arch_touch_nmi_watchdog is required to prevent the new warning from firing off. Signed-off-by: Nicholas Piggin Reviewed-by: Laurent Dufour Debugged-by: Laurent Dufour Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211110025056.2084347-2-npiggin@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/watchdog.c | 41 +++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c index af3c15a1d41eb..75b2a6c4db5a5 100644 --- a/arch/powerpc/kernel/watchdog.c +++ b/arch/powerpc/kernel/watchdog.c @@ -132,6 +132,10 @@ static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb) { cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask); cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask); + /* + * See wd_smp_clear_cpu_pending() + */ + smp_mb(); if (cpumask_empty(&wd_smp_cpus_pending)) { wd_smp_last_reset_tb = tb; cpumask_andnot(&wd_smp_cpus_pending, @@ -217,13 +221,44 @@ static void wd_smp_clear_cpu_pending(int cpu, u64 tb) cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck); wd_smp_unlock(&flags); + } else { + /* + * The last CPU to clear pending should have reset the + * watchdog so we generally should not find it empty + * here if our CPU was clear. However it could happen + * due to a rare race with another CPU taking the + * last CPU out of the mask concurrently. + * + * We can't add a warning for it. But just in case + * there is a problem with the watchdog that is causing + * the mask to not be reset, try to kick it along here. + */ + if (unlikely(cpumask_empty(&wd_smp_cpus_pending))) + goto none_pending; } return; } + cpumask_clear_cpu(cpu, &wd_smp_cpus_pending); + + /* + * Order the store to clear pending with the load(s) to check all + * words in the pending mask to check they are all empty. This orders + * with the same barrier on another CPU. This prevents two CPUs + * clearing the last 2 pending bits, but neither seeing the other's + * store when checking if the mask is empty, and missing an empty + * mask, which ends with a false positive. + */ + smp_mb(); if (cpumask_empty(&wd_smp_cpus_pending)) { unsigned long flags; +none_pending: + /* + * Double check under lock because more than one CPU could see + * a clear mask with the lockless check after clearing their + * pending bits. + */ wd_smp_lock(&flags); if (cpumask_empty(&wd_smp_cpus_pending)) { wd_smp_last_reset_tb = tb; @@ -314,8 +349,12 @@ void arch_touch_nmi_watchdog(void) { unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000; int cpu = smp_processor_id(); - u64 tb = get_tb(); + u64 tb; + if (!cpumask_test_cpu(cpu, &watchdog_cpumask)) + return; + + tb = get_tb(); if (tb - per_cpu(wd_timer_tb, cpu) >= ticks) { per_cpu(wd_timer_tb, cpu) = tb; wd_smp_clear_cpu_pending(cpu, tb); -- 2.34.1