Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp1247603rdb; Wed, 6 Dec 2023 12:52:39 -0800 (PST) X-Google-Smtp-Source: AGHT+IEpcmBEhTCi7XvAaDSNYywzh6G46kzFr85tqiySP2Y3pEZzHbTPyCw9iI8T0EmDbPxLJSbI X-Received: by 2002:a17:906:12:b0:a01:a193:1d56 with SMTP id 18-20020a170906001200b00a01a1931d56mr908268eja.14.1701895959544; Wed, 06 Dec 2023 12:52:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701895959; cv=none; d=google.com; s=arc-20160816; b=iAHWMUv3rog2Eq8kSiWsXJuq4VMa3fobqDJhizQZtnWoMsxRmDXz919zR5JApoDdHt eXRIqd3y70tLfAAGpw4JRbGsf+NigC+4+eGwnJF3kbvTjRg4F/q9H5SHNAywQb7Bz0Zl IZHXdEF9bs9V++YQ+exqnmBAHVuvcUSA2TnVx0TUouflv0VVnDeH8PSu2ZFCBgFo5x/q 1xjQtxONm+395YpaRbCbKH+xHOBTS+m2mXlZiveJUZAPLqHOgcJ9OTybLOZJbqGeYIUz vp2/mZqyptiYCh//oyb72JsW/72vas/LnJltNm+2F7Ka3p03Y+4pjzOggc1bWnaxk1SJ 0cog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=WceqjfMGEMiBB3nOBuWFcIs8l2PO3jnf+DRjfRyxayk=; fh=FjHZolXDLPlr1unCl28EzZfKnBWHEsMIwTi7Y980T9U=; b=wH0HK0Pi1XYCAJKeOarZ1MWnmzSfHuojTwcdMI3AZqr6NusL5xadkpk+hExuQr2reh j0ySIci3zVLph3FgYNHtwSV/oKwMdgGMEA0Ul+JTI+CxM928r2V8qiFxmgNUNT0NCH2u fbWWGf8Wm7YjyB66CrOaO4tWC03VP7eH3ZPcg8QAKMePVxS6bzCsWnQxETKWcrjFbsRR mI9Ubq7b9eXGZO0fZDPPSQjG9iV8FVksBZ9uSPjg7PJg3OGjV1ApW9VwmUrnAB0Zoz51 YIt6uS/HIuinHUKBjXt/vg1+5NeKI+BzoTc6WF+++TSUL/A0/WAsUaccQEdkH8MhBHt4 5wpA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=p6N0g2Ss; spf=pass (google.com: domain of linux-wireless+bounces-508-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-wireless+bounces-508-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id v18-20020a170906565200b00a1dc5aa248dsi259263ejr.657.2023.12.06.12.52.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Dec 2023 12:52:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-wireless+bounces-508-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=p6N0g2Ss; spf=pass (google.com: domain of linux-wireless+bounces-508-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-wireless+bounces-508-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 3C5241F218D4 for ; Wed, 6 Dec 2023 20:52:39 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EC1DA41859; Wed, 6 Dec 2023 20:52:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sipsolutions.net header.i=@sipsolutions.net header.b="p6N0g2Ss" X-Original-To: linux-wireless@vger.kernel.org Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76963D47 for ; Wed, 6 Dec 2023 12:52:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To: Resent-Cc:Resent-Message-ID; bh=WceqjfMGEMiBB3nOBuWFcIs8l2PO3jnf+DRjfRyxayk=; t=1701895948; x=1703105548; b=p6N0g2Ss6e8BE9s8RXgB9Z0DElQpKvDmNYrE64Vem7uAB1L ZiZoeUq/YGDKkbCSTqE+7iGkvpKGVB46bKd+fDf/mR8Fq4QObNwOfh/XtsIRh3sxv9asd0bfsfxBk asH+MxZr6mf8ruffXDDCMaIMuM1uYseV9/4IVSWIXmQYuHMtokPU+zNTao4zEkg2m6MCba2kCt2jS 6DkvykhlSQ2g0aB8Q3CKX/azZYcTkvMK5E+OvcBLw5asm6+whIeTK87DBJWX9goNCv3izgELK6xwb 59WLXNxrKpLN76/V58mABSq8B+XsNTrERXxcSKBE7kt53iBDL/tF1CaQ5BHMaO4A==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1rAysa-00000000HmL-39Bq; Wed, 06 Dec 2023 21:52:24 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: regressions@lists.linux.dev, Linus Lotz , Darrell Enns , Johannes Berg Subject: [RFC PATCH] wifi: iwlwifi: pcie: don't synchronize IRQs from IRQ Date: Wed, 6 Dec 2023 21:52:07 +0100 Message-ID: <20231206215211.95907305c9b2.Iadfe154d6248e7f9dfd69522e5429dbbd72925d7@changeid> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Johannes Berg On older devices (before unified image!) we can end up calling stop_device from an rfkill interrupt. However, in stop_device we attempt to synchronize IRQs, which then of course deadlocks. Avoid this by checking the context, if running from the IRQ thread then don't synchronize. This wouldn't be correct on a new device since RSS is supported, but older devices only have a single interrupt/queue. Fixes: 37fb29bd1f90 ("wifi: iwlwifi: pcie: synchronize IRQs before NAPI") Signed-off-by: Johannes Berg --- .../net/wireless/intel/iwlwifi/pcie/internal.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 8 ++++---- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 17 +++++++++-------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 56def20374f3..7805a42948af 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -770,7 +770,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) } } -void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans); +void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq); static inline bool iwl_is_rfkill_set(struct iwl_trans *trans) { @@ -817,7 +817,7 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans) return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans)); } -void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state); +void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq); void iwl_trans_pcie_dump_regs(struct iwl_trans *trans); #ifdef CONFIG_IWLWIFI_DEBUGFS diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 146bc7bd14fb..a0d10df0c11a 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1783,7 +1783,7 @@ static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans) return inta; } -void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans) +void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct isr_statistics *isr_stats = &trans_pcie->isr_stats; @@ -1807,7 +1807,7 @@ void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans) isr_stats->rfkill++; if (prev != report) - iwl_trans_pcie_rf_kill(trans, report); + iwl_trans_pcie_rf_kill(trans, report, from_irq); mutex_unlock(&trans_pcie->mutex); if (hw_rfkill) { @@ -1947,7 +1947,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { - iwl_pcie_handle_rfkill_irq(trans); + iwl_pcie_handle_rfkill_irq(trans, true); handled |= CSR_INT_BIT_RF_KILL; } @@ -2370,7 +2370,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) /* HW RF KILL switch toggled */ if (inta_hw & MSIX_HW_INT_CAUSES_REG_RF_KILL) - iwl_pcie_handle_rfkill_irq(trans); + iwl_pcie_handle_rfkill_irq(trans, true); if (inta_hw & MSIX_HW_INT_CAUSES_REG_HW_ERR) { IWL_ERR(trans, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index a468e5efeecd..f43a8923af9e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1082,7 +1082,7 @@ bool iwl_pcie_check_hw_rf_kill(struct iwl_trans *trans) report = test_bit(STATUS_RFKILL_OPMODE, &trans->status); if (prev != report) - iwl_trans_pcie_rf_kill(trans, report); + iwl_trans_pcie_rf_kill(trans, report, false); return hw_rfkill; } @@ -1237,7 +1237,7 @@ static void iwl_pcie_init_msix(struct iwl_trans_pcie *trans_pcie) trans_pcie->hw_mask = trans_pcie->hw_init_mask; } -static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) +static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool from_irq) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1264,7 +1264,8 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { IWL_DEBUG_INFO(trans, "DEVICE_ENABLED bit was set and is now cleared\n"); - iwl_pcie_synchronize_irqs(trans); + if (!from_irq) + iwl_pcie_synchronize_irqs(trans); iwl_pcie_rx_napi_sync(trans); iwl_pcie_tx_stop(trans); iwl_pcie_rx_stop(trans); @@ -1454,7 +1455,7 @@ void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans, clear_bit(STATUS_RFKILL_OPMODE, &trans->status); } if (hw_rfkill != was_in_rfkill) - iwl_trans_pcie_rf_kill(trans, hw_rfkill); + iwl_trans_pcie_rf_kill(trans, hw_rfkill, false); } static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) @@ -1469,12 +1470,12 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) mutex_lock(&trans_pcie->mutex); trans_pcie->opmode_down = true; was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status); - _iwl_trans_pcie_stop_device(trans); + _iwl_trans_pcie_stop_device(trans, false); iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill); mutex_unlock(&trans_pcie->mutex); } -void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) +void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq) { struct iwl_trans_pcie __maybe_unused *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1487,7 +1488,7 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) if (trans->trans_cfg->gen2) _iwl_trans_pcie_gen2_stop_device(trans); else - _iwl_trans_pcie_stop_device(trans); + _iwl_trans_pcie_stop_device(trans, from_irq); } } @@ -2887,7 +2888,7 @@ static ssize_t iwl_dbgfs_rfkill_write(struct file *file, IWL_WARN(trans, "changing debug rfkill %d->%d\n", trans_pcie->debug_rfkill, new_value); trans_pcie->debug_rfkill = new_value; - iwl_pcie_handle_rfkill_irq(trans); + iwl_pcie_handle_rfkill_irq(trans, false); return count; } -- 2.43.0