Message ID | 20230419095758.19998-1-quic_rgnanase@quicinc.com (mailing list archive) |
---|---|
State | Accepted |
Commit | e995f3f602a3fd9c8e0f97f59b37002d4ab5ec83 |
Delegated to: | Kalle Valo |
Headers | show |
Series | [v2] wifi: ath12k: fix potential wmi_mgmt_tx_queue race condition | expand |
Ramya Gnanasekar <quic_rgnanase@quicinc.com> wrote: > During stress test with maximum VAPs and peer connected, below warning > is seen: > > [ 1079.110967] ath12k_pci 0004:01:00.0: mgmt tx queue is full > [ 1079.117708] ath12k_pci 0004:01:00.0: failed to queue management frame -28 > [ 1079.123191] ath12k_pci 0004:01:00.0: mgmt tx queue is full > [ 1079.129960] ath12k_pci 0004:01:00.0: failed to queue management frame -28 > [ 1079.135641] ath12k_pci 0004:01:00.0: mgmt tx queue is full > > This is caused by potential race condition while accessing skb_queue_len(). > When ath12k_mgmt_over_wmi_tx_work() and ath12k_mac_mgmt_tx() is called concurrently, > then skb_queue_len() might fetch list length which is modified by skb_queue_tail() > or skb_dequeue(). > > Replace skb_queue_len() with skb_queue_len_lockless() which will > prevent concurrent modified access using READ_ONCE(). And also use '>=', > in case we queue a few SKBs simultaneously. > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 > > Signed-off-by: Karthik M <quic_karm@quicinc.com> > Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com> > Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Patch applied to ath-next branch of ath.git, thanks. e995f3f602a3 wifi: ath12k: fix potential wmi_mgmt_tx_queue race condition
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 0e5cc477ba56..cc458fed5e78 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4489,7 +4489,7 @@ static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, return -ENOSPC; } - if (skb_queue_len(q) == ATH12K_TX_MGMT_NUM_PENDING_MAX) { + if (skb_queue_len_lockless(q) >= ATH12K_TX_MGMT_NUM_PENDING_MAX) { ath12k_warn(ar->ab, "mgmt tx queue is full\n"); return -ENOSPC; }