Message ID | 20240429114841.413901-2-quic_kathirve@quicinc.com |
---|---|
State | Superseded |
Headers | show |
Series | wifi: ath12k: drop failed transmitted frames from metric calculation | expand |
On Monday, 29 April 2024 13:48:39 CEST Karthikeyan Kathirvel wrote: > From: Sven Eckelmann <sven@narfation.org> > > When a station idles for a long time, hostapd will try to send > a QoS Null frame to the station as "poll". NL80211_CMD_PROBE_CLIENT > is used for this purpose. > And the skb will be added to ack_status_frame - waiting for a > completion via ieee80211_report_ack_skb(). > > But when the peer was already removed before the tx_complete arrives, > the peer will be missing. And when using dev_kfree_skb_any (instead > of going through mac80211), the entry will stay inside > ack_status_frames thus not clean up related information in its > internal data structures. This IDR will therefore run full after > 8K request were generated for such clients. > At this point, the access point will then just stall and not allow > any new clients because idr_alloc() for ack_status_frame will fail. > > ieee80211_free_txskb() on the other hand will (when required) call > ieee80211_report_ack_skb() and make sure that (when required) remove > the entry from the ack_status_frame and clean up related > information in its internal data structures. > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Thanks for porting and testing both patches on ath12k. Kind regards, Sven
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index 9b6d7d72f57c..6a387f1f9567 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -448,6 +448,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, struct hal_tx_status *ts) { struct ath12k_base *ab = ar->ab; + struct ath12k_hw *ah = ar->ah; struct ieee80211_tx_info *info; struct ath12k_skb_cb *skb_cb; @@ -466,12 +467,12 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, rcu_read_lock(); if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) { - dev_kfree_skb_any(msdu); + ieee80211_free_txskb(ah->hw, msdu); goto exit; } if (!skb_cb->vif) { - dev_kfree_skb_any(msdu); + ieee80211_free_txskb(ah->hw, msdu); goto exit; }