Skip to content

Commit 5082b3e

Browse files
Baochen Qiangkvalo
authored andcommitted
wifi: ath11k: fix race due to setting ATH11K_FLAG_EXT_IRQ_ENABLED too early
We are seeing below error randomly in the case where only one MSI vector is configured: kernel: ath11k_pci 0000:03:00.0: wmi command 16387 timeout The reason is, currently, in ath11k_pcic_ext_irq_enable(), ATH11K_FLAG_EXT_IRQ_ENABLED is set before NAPI is enabled. This results in a race condition: after ATH11K_FLAG_EXT_IRQ_ENABLED is set but before NAPI enabled, CE interrupt breaks in. Since IRQ is shared by CE and data path, ath11k_pcic_ext_interrupt_handler() is also called where we call disable_irq_nosync() to disable IRQ. Then napi_schedule() is called but it does nothing because NAPI is not enabled at that time, meaning ath11k_pcic_ext_grp_napi_poll() will never run, so we have no chance to call enable_irq() to enable IRQ back. Finally we get above error. Fix it by setting ATH11K_FLAG_EXT_IRQ_ENABLED after all NAPI and IRQ work are done. With the fix, we are sure that by the time ATH11K_FLAG_EXT_IRQ_ENABLED is set, NAPI is enabled. Note that the fix above also introduce some side effects: if ath11k_pcic_ext_interrupt_handler() breaks in after NAPI enabled but before ATH11K_FLAG_EXT_IRQ_ENABLED set, nothing will be done by the handler this time, the work will be postponed till the next time the IRQ fires. Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 Signed-off-by: Baochen Qiang <[email protected]> Acked-by: Jeff Johnson <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f20eb4c commit 5082b3e

File tree

1 file changed

+2
-2
lines changed
  • drivers/net/wireless/ath/ath11k

1 file changed

+2
-2
lines changed

drivers/net/wireless/ath/ath11k/pcic.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,6 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab)
460460
{
461461
int i;
462462

463-
set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
464-
465463
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
466464
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
467465

@@ -471,6 +469,8 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab)
471469
}
472470
ath11k_pcic_ext_grp_enable(irq_grp);
473471
}
472+
473+
set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
474474
}
475475
EXPORT_SYMBOL(ath11k_pcic_ext_irq_enable);
476476

0 commit comments

Comments
 (0)