From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Tsuchiya Yuto <kitakar@gmail.com>,
Maximilian Luz <luzmaximilian@gmail.com>,
Kalle Valo <kvalo@codeaurora.org>,
Sasha Levin <sashal@kernel.org>,
linux-wireless@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH AUTOSEL 4.14 18/66] mwifiex: pcie: skip cancel_work_sync() on reset failure path
Date: Tue, 22 Dec 2020 21:22:04 -0500 [thread overview]
Message-ID: <20201223022253.2793452-18-sashal@kernel.org> (raw)
In-Reply-To: <20201223022253.2793452-1-sashal@kernel.org>
From: Tsuchiya Yuto <kitakar@gmail.com>
[ Upstream commit 4add4d988f95f47493500a7a19c623827061589b ]
If a reset is performed, but even the reset fails for some reasons (e.g.,
on Surface devices, the fw reset requires another quirks),
cancel_work_sync() hangs in mwifiex_cleanup_pcie().
# firmware went into a bad state
[...]
[ 1608.281690] mwifiex_pcie 0000:03:00.0: info: shutdown mwifiex...
[ 1608.282724] mwifiex_pcie 0000:03:00.0: rx_pending=0, tx_pending=1, cmd_pending=0
[ 1608.292400] mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
[ 1608.292405] mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed
# reset performed after firmware went into a bad state
[ 1609.394320] mwifiex_pcie 0000:03:00.0: WLAN FW already running! Skip FW dnld
[ 1609.394335] mwifiex_pcie 0000:03:00.0: WLAN FW is active
# but even the reset failed
[ 1619.499049] mwifiex_pcie 0000:03:00.0: mwifiex_cmd_timeout_func: Timeout cmd id = 0xfa, act = 0xe000
[ 1619.499094] mwifiex_pcie 0000:03:00.0: num_data_h2c_failure = 0
[ 1619.499103] mwifiex_pcie 0000:03:00.0: num_cmd_h2c_failure = 0
[ 1619.499110] mwifiex_pcie 0000:03:00.0: is_cmd_timedout = 1
[ 1619.499117] mwifiex_pcie 0000:03:00.0: num_tx_timeout = 0
[ 1619.499124] mwifiex_pcie 0000:03:00.0: last_cmd_index = 0
[ 1619.499133] mwifiex_pcie 0000:03:00.0: last_cmd_id: fa 00 07 01 07 01 07 01 07 01
[ 1619.499140] mwifiex_pcie 0000:03:00.0: last_cmd_act: 00 e0 00 00 00 00 00 00 00 00
[ 1619.499147] mwifiex_pcie 0000:03:00.0: last_cmd_resp_index = 3
[ 1619.499155] mwifiex_pcie 0000:03:00.0: last_cmd_resp_id: 07 81 07 81 07 81 07 81 07 81
[ 1619.499162] mwifiex_pcie 0000:03:00.0: last_event_index = 2
[ 1619.499169] mwifiex_pcie 0000:03:00.0: last_event: 58 00 58 00 58 00 58 00 58 00
[ 1619.499177] mwifiex_pcie 0000:03:00.0: data_sent=0 cmd_sent=1
[ 1619.499185] mwifiex_pcie 0000:03:00.0: ps_mode=0 ps_state=0
[ 1619.499215] mwifiex_pcie 0000:03:00.0: info: _mwifiex_fw_dpc: unregister device
# mwifiex_pcie_work hang happening
[ 1823.233923] INFO: task kworker/3:1:44 blocked for more than 122 seconds.
[ 1823.233932] Tainted: G WC OE 5.10.0-rc1-1-mainline #1
[ 1823.233935] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 1823.233940] task:kworker/3:1 state:D stack: 0 pid: 44 ppid: 2 flags:0x00004000
[ 1823.233960] Workqueue: events mwifiex_pcie_work [mwifiex_pcie]
[ 1823.233965] Call Trace:
[ 1823.233981] __schedule+0x292/0x820
[ 1823.233990] schedule+0x45/0xe0
[ 1823.233995] schedule_timeout+0x11c/0x160
[ 1823.234003] wait_for_completion+0x9e/0x100
[ 1823.234012] __flush_work.isra.0+0x156/0x210
[ 1823.234018] ? flush_workqueue_prep_pwqs+0x130/0x130
[ 1823.234026] __cancel_work_timer+0x11e/0x1a0
[ 1823.234035] mwifiex_cleanup_pcie+0x28/0xd0 [mwifiex_pcie]
[ 1823.234049] mwifiex_free_adapter+0x24/0xe0 [mwifiex]
[ 1823.234060] _mwifiex_fw_dpc+0x294/0x560 [mwifiex]
[ 1823.234074] mwifiex_reinit_sw+0x15d/0x300 [mwifiex]
[ 1823.234080] mwifiex_pcie_reset_done+0x50/0x80 [mwifiex_pcie]
[ 1823.234087] pci_try_reset_function+0x5c/0x90
[ 1823.234094] process_one_work+0x1d6/0x3a0
[ 1823.234100] worker_thread+0x4d/0x3d0
[ 1823.234107] ? rescuer_thread+0x410/0x410
[ 1823.234112] kthread+0x142/0x160
[ 1823.234117] ? __kthread_bind_mask+0x60/0x60
[ 1823.234124] ret_from_fork+0x22/0x30
[...]
This is a deadlock caused by calling cancel_work_sync() in
mwifiex_cleanup_pcie():
- Device resets are done via mwifiex_pcie_card_reset()
- which schedules card->work to call mwifiex_pcie_card_reset_work()
- which calls pci_try_reset_function().
- This leads to mwifiex_pcie_reset_done() be called on the same workqueue,
which in turn calls
- mwifiex_reinit_sw() and that calls
- _mwifiex_fw_dpc().
The problem is now that _mwifiex_fw_dpc() calls mwifiex_free_adapter()
in case firmware initialization fails. That ends up calling
mwifiex_cleanup_pcie().
Note that all those calls are still running on the workqueue. So when
mwifiex_cleanup_pcie() now calls cancel_work_sync(), it's really waiting
on itself to complete, causing a deadlock.
This commit fixes the deadlock by skipping cancel_work_sync() on a reset
failure path.
After this commit, when reset fails, the following output is
expected to be shown:
kernel: mwifiex_pcie 0000:03:00.0: info: _mwifiex_fw_dpc: unregister device
kernel: mwifiex: Failed to bring up adapter: -5
kernel: mwifiex_pcie 0000:03:00.0: reinit failed: -5
To reproduce this issue, for example, try putting the root port of wifi
into D3 (replace "00:1d.3" with your setup).
# put into D3 (root port)
sudo setpci -v -s 00:1d.3 CAP_PM+4.b=0b
Cc: Maximilian Luz <luzmaximilian@gmail.com>
Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20201028142346.18355-1-kitakar@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/marvell/mwifiex/pcie.c | 18 +++++++++++++++++-
drivers/net/wireless/marvell/mwifiex/pcie.h | 2 ++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 8ee9609ef9749..7f615ad98acaa 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -368,6 +368,8 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
+
+ card->pci_reset_ongoing = true;
}
/*
@@ -396,6 +398,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev)
dev_err(&pdev->dev, "reinit failed: %d\n", ret);
else
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
+
+ card->pci_reset_ongoing = false;
}
static const struct pci_error_handlers mwifiex_pcie_err_handler = {
@@ -2980,7 +2984,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
int ret;
u32 fw_status;
- cancel_work_sync(&card->work);
+ /* Perform the cancel_work_sync() only when we're not resetting
+ * the card. It's because that function never returns if we're
+ * in reset path. If we're here when resetting the card, it means
+ * that we failed to reset the card (reset failure path).
+ */
+ if (!card->pci_reset_ongoing) {
+ mwifiex_dbg(adapter, MSG, "performing cancel_work_sync()...\n");
+ cancel_work_sync(&card->work);
+ mwifiex_dbg(adapter, MSG, "cancel_work_sync() done\n");
+ } else {
+ mwifiex_dbg(adapter, MSG,
+ "skipped cancel_work_sync() because we're in card reset failure path\n");
+ }
ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
if (fw_status == FIRMWARE_READY_PCIE) {
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
index f7ce9b6db6b41..72d0c01ff3592 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.h
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.h
@@ -391,6 +391,8 @@ struct pcie_service_card {
struct mwifiex_msix_context share_irq_ctx;
struct work_struct work;
unsigned long work_flags;
+
+ bool pci_reset_ongoing;
};
static inline int
--
2.27.0
next prev parent reply other threads:[~2020-12-23 2:41 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-23 2:21 [PATCH AUTOSEL 4.14 01/66] locks: Fix UBSAN undefined behaviour in flock64_to_posix_lock Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 02/66] tomoyo: fix clang pointer arithmetic warning Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 03/66] crypto: omap-aes - fix the reference count leak of omap device Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 04/66] staging: wimax: depends on NET Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 05/66] scsi: pm80xx: Avoid busywait in FW ready check Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 06/66] scsi: pm80xx: Fix pm8001_mpi_get_nvmd_resp() race condition Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 07/66] staging: ks7010: fix missing destroy_workqueue() on error in ks7010_sdio_probe Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 08/66] staging: rtl8192u: fix wrong judgement in rtl8192_rx_isr Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 09/66] mips: ar7: add missing iounmap() on error in ar7_gpio_init Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 10/66] mips: cm: add missing iounmap() on error in mips_cm_probe() Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 11/66] locktorture: Prevent hangs for invalid arguments Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 12/66] rcutorture: " Sasha Levin
2020-12-23 2:21 ` [PATCH AUTOSEL 4.14 13/66] drm: panel: simple: add missing platform_driver_unregister() in panel_simple_init Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 14/66] drm/ast: Fixed 1920x1080 sync. polarity issue Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 15/66] s390/trng: set quality to 1024 Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 16/66] Bluetooth: hidp: use correct wait queue when removing ctrl_wait Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 17/66] net: skb_vlan_untag(): don't reset transport offset if set by GRO layer Sasha Levin
2020-12-23 2:22 ` Sasha Levin [this message]
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 19/66] MIPS: BMC47xx: fix kconfig dependency bug for BCM47XX_SSB Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 20/66] jfs: Fix memleak in dbAdjCtl Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 21/66] media: zr364xx: propagate errors from zr364xx_start_readpipe() Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 22/66] media: cec-core: first mark device unregistered, then wake up fhs Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 23/66] media: isif: reset global state Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 24/66] s390/dasd: Fix operational path inconsistency Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 25/66] media: usb: dvb-usb-v2: zd1301: fix missing platform_device_unregister() Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 26/66] media: dvbdev: Fix memleak in dvb_register_device Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 27/66] mmc: tmio: do not print real IOMEM pointer Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 28/66] ARM: OMAP2+: Fix memleak in omap2xxx_clkt_vps_init Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 29/66] MIPS: kvm: Use vm_get_page_prot to get protection bits Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 30/66] scsi: ufs: Atomic update for clkgating_enable Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 31/66] ALSA: usb-audio: Don't call usb_set_interface() at trigger callback Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 32/66] rxrpc: Don't leak the service-side session key to userspace Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 33/66] scsi: atari_scsi: Fix race condition between .queuecommand and EH Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 34/66] ARM: dts: hisilicon: fix errors detected by snps-dw-apb-uart.yaml Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 35/66] ARM: dts: hisilicon: fix errors detected by usb yaml Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 36/66] ARM: dts: hisilicon: fix errors detected by simple-bus.yaml Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 37/66] ARM: dts: hisilicon: fix errors detected by spi-pl022.yaml Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 38/66] selftests/x86/fsgsbase: Fix GS == 1, 2, and 3 tests Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 39/66] brcmsmac: ampdu: Check BA window size before checking block ack Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 40/66] hv_netvsc: Validate number of allocated sub-channels Sasha Levin
2020-12-23 2:47 ` Michael Kelley
2020-12-23 8:59 ` Andrea Parri
2020-12-23 14:14 ` Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 41/66] iommu/tegra-smmu: Expand mutex protection range Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 42/66] arm64: tegra: Fix GIC400 missing GICH/GICV register regions Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 43/66] crypto: qce - Fix SHA result buffer corruption issues Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 44/66] media: gp8psk: initialize stats at power control logic Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 45/66] net/lapb: fix t1 timer handling for LAPB_STATE_0 Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 46/66] x86/pci: Fix the function type for check_reserved_t Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 47/66] x86/mce: Panic for LMCE only if mca_cfg.tolerant < 3 Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 48/66] bridge: switchdev: Notify about VLAN protocol changes Sasha Levin
2020-12-23 15:31 ` Vladimir Oltean
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 49/66] MIPS: KASLR: Avoid endless loop in sync_icache if synci_step is zero Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 50/66] cpufreq: sti-cpufreq: fix mem leak in sti_cpufreq_set_opp_info() Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 51/66] cpufreq: mediatek: add missing platform_driver_unregister() on error in mtk_cpufreq_driver_init Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 52/66] clocksource/drivers/sh_cmt: Fix potential deadlock when calling runtime PM Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 53/66] mwifiex: Fix possible buffer overflows in mwifiex_cmd_802_11_ad_hoc_start Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 54/66] misc: vmw_vmci: fix kernel info-leak by initializing dbells in vmci_ctx_get_chkpt_doorbells() Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 55/66] iwlwifi: trans: consider firmware dead after errors Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 56/66] iwlwifi: add an extra firmware state in the transport Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 57/66] USB: typec: tcpm: Fix PR_SWAP error handling Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 58/66] USB: typec: tcpm: Add a 30ms room for tPSSourceOn in PR_SWAP Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 59/66] nl80211: always accept scan request with the duration set Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 60/66] cfg80211: Save the regulatory domain when setting custom regulatory Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 61/66] mac80211: disallow band-switch during CSA Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 62/66] mac80211: Fix calculation of minimal channel width Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 63/66] mac80211: don't filter out beacons once we start CSA Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 64/66] mac80211: Update rate control on channel change Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 65/66] ALSA: hda/hdmi: packet buffer index must be set before reading value Sasha Levin
2020-12-23 2:22 ` [PATCH AUTOSEL 4.14 66/66] PCI: Add function 1 DMA alias quirk for Marvell 9215 SATA controller Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201223022253.2793452-18-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=kitakar@gmail.com \
--cc=kvalo@codeaurora.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=luzmaximilian@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox