Skip to content

Commit 9228207

Browse files
Karthik Mjeff-t-johnson
authored andcommitted
wifi: ath12k: free skb during idr cleanup callback
ath12k just like ath11k [1] did not handle skb cleanup during idr cleanup callback. Both ath12k_mac_vif_txmgmt_idr_remove() and ath12k_mac_tx_mgmt_pending_free() performed idr cleanup and DMA unmapping for skb but only ath12k_mac_tx_mgmt_pending_free() freed skb. As a result, during vdev deletion a memory leak occurs. Refactor all clean up steps into a new function. New function ath12k_mac_tx_mgmt_free() creates a centralized area where idr cleanup, DMA unmapping for skb and freeing skb is performed. Utilize skb pointer given by idr_remove(), instead of passed as a function argument because IDR will be protected by locking. This will prevent concurrent modification of the same IDR. Now ath12k_mac_tx_mgmt_pending_free() and ath12k_mac_vif_txmgmt_idr_remove() call ath12k_mac_tx_mgmt_free(). Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Link: https://lore.kernel.org/r/1637832614-13831-1-git-send-email-quic_srirrama@quicinc.com > # [1] Fixes: d889913 ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Signed-off-by: Karthik M <quic_karm@quicinc.com> Signed-off-by: Muna Sinada <muna.sinada@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Link: https://patch.msgid.link/20250923220316.1595758-1-muna.sinada@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
1 parent 0eb002c commit 9228207

1 file changed

Lines changed: 18 additions & 16 deletions

File tree

  • drivers/net/wireless/ath/ath12k

drivers/net/wireless/ath/ath12k/mac.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8304,23 +8304,32 @@ static void ath12k_mgmt_over_wmi_tx_drop(struct ath12k *ar, struct sk_buff *skb)
83048304
wake_up(&ar->txmgmt_empty_waitq);
83058305
}
83068306

8307-
int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
8307+
static void ath12k_mac_tx_mgmt_free(struct ath12k *ar, int buf_id)
83088308
{
8309-
struct sk_buff *msdu = skb;
8309+
struct sk_buff *msdu;
83108310
struct ieee80211_tx_info *info;
8311-
struct ath12k *ar = ctx;
8312-
struct ath12k_base *ab = ar->ab;
83138311

83148312
spin_lock_bh(&ar->txmgmt_idr_lock);
8315-
idr_remove(&ar->txmgmt_idr, buf_id);
8313+
msdu = idr_remove(&ar->txmgmt_idr, buf_id);
83168314
spin_unlock_bh(&ar->txmgmt_idr_lock);
8317-
dma_unmap_single(ab->dev, ATH12K_SKB_CB(msdu)->paddr, msdu->len,
8315+
8316+
if (!msdu)
8317+
return;
8318+
8319+
dma_unmap_single(ar->ab->dev, ATH12K_SKB_CB(msdu)->paddr, msdu->len,
83188320
DMA_TO_DEVICE);
83198321

83208322
info = IEEE80211_SKB_CB(msdu);
83218323
memset(&info->status, 0, sizeof(info->status));
83228324

8323-
ath12k_mgmt_over_wmi_tx_drop(ar, skb);
8325+
ath12k_mgmt_over_wmi_tx_drop(ar, msdu);
8326+
}
8327+
8328+
int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
8329+
{
8330+
struct ath12k *ar = ctx;
8331+
8332+
ath12k_mac_tx_mgmt_free(ar, buf_id);
83248333

83258334
return 0;
83268335
}
@@ -8329,17 +8338,10 @@ static int ath12k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx)
83298338
{
83308339
struct ieee80211_vif *vif = ctx;
83318340
struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
8332-
struct sk_buff *msdu = skb;
83338341
struct ath12k *ar = skb_cb->ar;
8334-
struct ath12k_base *ab = ar->ab;
83358342

8336-
if (skb_cb->vif == vif) {
8337-
spin_lock_bh(&ar->txmgmt_idr_lock);
8338-
idr_remove(&ar->txmgmt_idr, buf_id);
8339-
spin_unlock_bh(&ar->txmgmt_idr_lock);
8340-
dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len,
8341-
DMA_TO_DEVICE);
8342-
}
8343+
if (skb_cb->vif == vif)
8344+
ath12k_mac_tx_mgmt_free(ar, buf_id);
83438345

83448346
return 0;
83458347
}

0 commit comments

Comments
 (0)