From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB581C77B7D for ; Wed, 10 May 2023 20:52:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236985AbjEJUwH (ORCPT ); Wed, 10 May 2023 16:52:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41688 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236961AbjEJUve (ORCPT ); Wed, 10 May 2023 16:51:34 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D1EE9EDC; Wed, 10 May 2023 13:51:01 -0700 (PDT) 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 3AE0D63FF5; Wed, 10 May 2023 20:50:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81EFDC4339B; Wed, 10 May 2023 20:50:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1683751807; bh=NmeAihU+l9US5FZym48z2oc5TV/w6wDH93dkXnSsAy8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Xp3vGro2kOVtbOP/WkV71B3oFjx8IWJcYwul401wAK0ZVv/ZX4s/Z5h0mJwuabfoB OiOQiwcS+FAKkETZytdopicOtMnWL6OjsG1yJR5JgP9h7UGv+98RZri2WGtohz1tRo rg9nNAeAPEN6HXXSRSaflSlJsMfEKttT2rTFU5oxlbqXIsaGfZsWwsYtVLQnyINwQ9 ezB3XoOUxsHZSsYBz07auotRisjwR3fYHzcYZfSi5Q+FIFNzVnx7pvcsH5MTWqmq/s LAtTbeQghldP9CXqEsTnATIOC8xnO3CqIT2wVMYxNp4mhpF6gc8dJ1hhWwpGkxphDb 7CQdnjm0h20+Q== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: "Guilherme G. Piccoli" , "James E.J. Bottomley" , Jeroen Roovers , Helge Deller , Sasha Levin , linux-parisc@vger.kernel.org Subject: [PATCH AUTOSEL 6.1 8/8] parisc: Replace regular spinlock with spin_trylock on panic path Date: Wed, 10 May 2023 16:49:49 -0400 Message-Id: <20230510204950.104873-8-sashal@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230510204950.104873-1-sashal@kernel.org> References: <20230510204950.104873-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Guilherme G. Piccoli" [ Upstream commit 829632dae8321787525ee37dc4828bbe6edafdae ] The panic notifiers' callbacks execute in an atomic context, with interrupts/preemption disabled, and all CPUs not running the panic function are off, so it's very dangerous to wait on a regular spinlock, there's a risk of deadlock. Refactor the panic notifier of parisc/power driver to make use of spin_trylock - for that, we've added a second version of the soft-power function. Also, some comments were reorganized and trailing white spaces, useless header inclusion and blank lines were removed. Cc: "James E.J. Bottomley" Cc: Jeroen Roovers Acked-by: Helge Deller # parisc Signed-off-by: Guilherme G. Piccoli Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- arch/parisc/include/asm/pdc.h | 1 + arch/parisc/kernel/firmware.c | 27 +++++++++++++++++++++++---- drivers/parisc/power.c | 16 ++++++++++------ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index fcbcf9a96c111..77622558bf651 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -80,6 +80,7 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap); int pdc_do_reset(void); int pdc_soft_power_info(unsigned long *power_reg); int pdc_soft_power_button(int sw_control); +int pdc_soft_power_button_panic(int sw_control); void pdc_io_reset(void); void pdc_io_reset_devices(void); int pdc_iodc_getc(void); diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index bd325f2b5349e..3e051a973e9b2 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -1232,15 +1232,18 @@ int __init pdc_soft_power_info(unsigned long *power_reg) } /* - * pdc_soft_power_button - Control the soft power button behaviour - * @sw_control: 0 for hardware control, 1 for software control + * pdc_soft_power_button{_panic} - Control the soft power button behaviour + * @sw_control: 0 for hardware control, 1 for software control * * * This PDC function places the soft power button under software or * hardware control. - * Under software control the OS may control to when to allow to shut - * down the system. Under hardware control pressing the power button + * Under software control the OS may control to when to allow to shut + * down the system. Under hardware control pressing the power button * powers off the system immediately. + * + * The _panic version relies on spin_trylock to prevent deadlock + * on panic path. */ int pdc_soft_power_button(int sw_control) { @@ -1254,6 +1257,22 @@ int pdc_soft_power_button(int sw_control) return retval; } +int pdc_soft_power_button_panic(int sw_control) +{ + int retval; + unsigned long flags; + + if (!spin_trylock_irqsave(&pdc_lock, flags)) { + pr_emerg("Couldn't enable soft power button\n"); + return -EBUSY; /* ignored by the panic notifier */ + } + + retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control); + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + /* * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices. * Primarily a problem on T600 (which parisc-linux doesn't support) but diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c index 456776bd8ee66..6f5e5f0230d39 100644 --- a/drivers/parisc/power.c +++ b/drivers/parisc/power.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -175,16 +174,21 @@ static void powerfail_interrupt(int code, void *x) -/* parisc_panic_event() is called by the panic handler. - * As soon as a panic occurs, our tasklets above will not be - * executed any longer. This function then re-enables the - * soft-power switch and allows the user to switch off the system +/* + * parisc_panic_event() is called by the panic handler. + * + * As soon as a panic occurs, our tasklets above will not + * be executed any longer. This function then re-enables + * the soft-power switch and allows the user to switch off + * the system. We rely in pdc_soft_power_button_panic() + * since this version spin_trylocks (instead of regular + * spinlock), preventing deadlocks on panic path. */ static int parisc_panic_event(struct notifier_block *this, unsigned long event, void *ptr) { /* re-enable the soft-power switch */ - pdc_soft_power_button(0); + pdc_soft_power_button_panic(0); return NOTIFY_DONE; } -- 2.39.2