@@ -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)
@@ -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);
@@ -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);
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(-)