diff mbox series

[ath-next,1/2] wifi: ath12k: Reorder and relocate the release of resources in ath12k_core_deinit()

Message ID 20250423055650.16230-2-quic_yintang@quicinc.com
State New
Headers show
Series wifi: ath12k: Fix asymmetry between ath12k_core_init() and ath12k_core_deinit() | expand

Commit Message

Yingying Tang April 23, 2025, 5:56 a.m. UTC
Ath12k panic notifier is registered in driver loading process. But it is not
unregistered if ATH12K_FLAG_QMI_FAIL is set(e.g. load BDF failed) and unload
driver. It causes a dirty node in panic notifier list since ath12k panic
notifier is not unregistered from list but the buffer of this node is freed
in driver unloading process. If load driver again there will be a page fault
error due to this dirty node in panic notifier list.

This issue is caused by asymmetry between ath12k_core_init() and
ath12k_core_deinit(). Reorder and relocate the release of resources in
ath12k_core_deinit() to avoid this asymmetry issue.

Call Trace:
<TASK>
? show_regs+0x67/0x70
? __die_body+0x20/0x70
? __die+0x2b/0x40
? page_fault_oops+0x15d/0x500
? search_bpf_extables+0x63/0x90
? notifier_chain_register+0x21/0xe0
? search_exception_tables+0x5f/0x70
? kernelmode_fixup_or_oops.isra.0+0x61/0x80
? __bad_area_nosemaphore+0x179/0x240
? bad_area_nosemaphore+0x16/0x20
? do_user_addr_fault+0x312/0x7f0
? prb_read_valid+0x1c/0x30
? exc_page_fault+0x78/0x180
? asm_exc_page_fault+0x27/0x30
? notifier_chain_register+0x21/0xe0
? notifier_chain_register+0x55/0xe0
atomic_notifier_chain_register+0x2c/0x50
ath12k_core_init+0x7e/0x110 [ath12k]
ath12k_pci_probe+0xaba/0xba0 [ath12k]

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0-02903-QCAHKSWPL_SILICONZ-1
Tested-on: QCN8750 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Fixes: 809055628bce8 ("wifi: ath12k: add panic handler")
Signed-off-by: Yingying Tang <quic_yintang@quicinc.com>
---
 drivers/net/wireless/ath/ath12k/core.c | 5 ++---
 drivers/net/wireless/ath/ath12k/core.h | 1 +
 drivers/net/wireless/ath/ath12k/pci.c  | 5 ++---
 3 files changed, 5 insertions(+), 6 deletions(-)

Comments

Raj Kumar Bhagat April 29, 2025, 12:41 p.m. UTC | #1
On 4/23/2025 11:26 AM, Yingying Tang wrote:
> Ath12k panic notifier is registered in driver loading process. But it is not
> unregistered if ATH12K_FLAG_QMI_FAIL is set(e.g. load BDF failed) and unload
> driver. It causes a dirty node in panic notifier list since ath12k panic
> notifier is not unregistered from list but the buffer of this node is freed
> in driver unloading process. If load driver again there will be a page fault
> error due to this dirty node in panic notifier list.
> 
> This issue is caused by asymmetry between ath12k_core_init() and
> ath12k_core_deinit(). Reorder and relocate the release of resources in
> ath12k_core_deinit() to avoid this asymmetry issue.
> 
> Call Trace:
> <TASK>
> ? show_regs+0x67/0x70
> ? __die_body+0x20/0x70
> ? __die+0x2b/0x40
> ? page_fault_oops+0x15d/0x500
> ? search_bpf_extables+0x63/0x90
> ? notifier_chain_register+0x21/0xe0
> ? search_exception_tables+0x5f/0x70
> ? kernelmode_fixup_or_oops.isra.0+0x61/0x80
> ? __bad_area_nosemaphore+0x179/0x240
> ? bad_area_nosemaphore+0x16/0x20
> ? do_user_addr_fault+0x312/0x7f0
> ? prb_read_valid+0x1c/0x30
> ? exc_page_fault+0x78/0x180
> ? asm_exc_page_fault+0x27/0x30
> ? notifier_chain_register+0x21/0xe0
> ? notifier_chain_register+0x55/0xe0
> atomic_notifier_chain_register+0x2c/0x50
> ath12k_core_init+0x7e/0x110 [ath12k]
> ath12k_pci_probe+0xaba/0xba0 [ath12k]
> 
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0-02903-QCAHKSWPL_SILICONZ-1
> Tested-on: QCN8750 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

I guess this Tested-on tag should be
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Not sure if this can be taken care while merging in pending branch? or re-spin is
required?
Jeff Johnson April 29, 2025, 5:05 p.m. UTC | #2
On 4/29/2025 5:41 AM, Raj Kumar Bhagat wrote:
> On 4/23/2025 11:26 AM, Yingying Tang wrote:
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0-02903-QCAHKSWPL_SILICONZ-1
>> Tested-on: QCN8750 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> 
> I guess this Tested-on tag should be
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> 
> Not sure if this can be taken care while merging in pending branch? or re-spin is
> required?

I'll fix this in the 'pending' branch
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 0e71935b2720..ef8a2b993560 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1890,7 +1890,7 @@  static void ath12k_core_hw_group_destroy(struct ath12k_hw_group *ag)
 	}
 }
 
-static void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
+void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
 {
 	struct ath12k_base *ab;
 	int i;
@@ -2038,10 +2038,9 @@  int ath12k_core_init(struct ath12k_base *ab)
 
 void ath12k_core_deinit(struct ath12k_base *ab)
 {
-	ath12k_core_panic_notifier_unregister(ab);
-	ath12k_core_hw_group_cleanup(ab->ag);
 	ath12k_core_hw_group_destroy(ab->ag);
 	ath12k_core_hw_group_unassign(ab);
+	ath12k_core_panic_notifier_unregister(ab);
 }
 
 void ath12k_core_free(struct ath12k_base *ab)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index e8d2a0c859f6..93625610b6cf 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -1219,6 +1219,7 @@  struct ath12k_fw_stats_pdev {
 };
 
 int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab);
+void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag);
 int ath12k_core_pre_init(struct ath12k_base *ab);
 int ath12k_core_init(struct ath12k_base *ath12k);
 void ath12k_core_deinit(struct ath12k_base *ath12k);
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 7f1bb150f326..75ea6ef425f0 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -1730,8 +1730,6 @@  static void ath12k_pci_remove(struct pci_dev *pdev)
 
 	if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
 		ath12k_pci_power_down(ab, false);
-		ath12k_qmi_deinit_service(ab);
-		ath12k_core_hw_group_unassign(ab);
 		goto qmi_fail;
 	}
 
@@ -1739,9 +1737,10 @@  static void ath12k_pci_remove(struct pci_dev *pdev)
 
 	cancel_work_sync(&ab->reset_work);
 	cancel_work_sync(&ab->dump_work);
-	ath12k_core_deinit(ab);
+	ath12k_core_hw_group_cleanup(ab->ag);
 
 qmi_fail:
+	ath12k_core_deinit(ab);
 	ath12k_fw_unmap(ab);
 	ath12k_mhi_unregister(ab_pci);