ath11k: Increment pending_mgmt_tx count before tx send invoke
authorP Praneesh <quic_ppranees@quicinc.com>
Mon, 25 Oct 2021 13:24:42 +0000 (18:54 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 15 Nov 2021 09:25:52 +0000 (11:25 +0200)
There is a race condition whereby the tx completion handler can be invoked
before the 'num_pending_mgmt_tx" count is incremented. If that occurs, we
could get warning trace indicating that 'num_pending_mgmt_tx' is 0 (because
it was not yet incremented). Ideally, this trace should be seen only if
mgmt tx has not happened but tx completion is received, and it is not
expected in this race condition.

Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01386-QCAHKSWPL_SILICONZ-1

Co-developed-by: Lavanya Suresh <lavaks@codeaurora.org>
Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1635168282-8845-1-git-send-email-quic_ppranees@quicinc.com
drivers/net/wireless/ath/ath11k/mac.c

index 5bc82be25316d723c741ad8326f6afba08ecb326..1320c8634d310e6d967310adf2fdee72775cad1c 100644 (file)
@@ -5202,13 +5202,15 @@ static void ath11k_mgmt_over_wmi_tx_work(struct work_struct *work)
                arvif = ath11k_vif_to_arvif(skb_cb->vif);
                if (ar->allocated_vdev_map & (1LL << arvif->vdev_id) &&
                    arvif->is_started) {
+                       atomic_inc(&ar->num_pending_mgmt_tx);
                        ret = ath11k_mac_mgmt_tx_wmi(ar, arvif, skb);
                        if (ret) {
+                               if (atomic_dec_if_positive(&ar->num_pending_mgmt_tx) < 0)
+                                       WARN_ON_ONCE(1);
+
                                ath11k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n",
                                            arvif->vdev_id, ret);
                                ieee80211_free_txskb(ar->hw, skb);
-                       } else {
-                               atomic_inc(&ar->num_pending_mgmt_tx);
                        }
                } else {
                        ath11k_warn(ar->ab,