diff mbox series

[3/3] wifi: ath11k: fix leaking station RX/TX stats in reset scenario

Message ID 20240826014942.87783-4-quic_bqiang@quicinc.com
State New
Headers show
Series wifi: ath11k: fix memory leak in reset scenario | expand

Commit Message

Baochen Qiang Aug. 26, 2024, 1:49 a.m. UTC
Currently ath12k_sta::rx_stats/tx_stats would only get freed when the station
transit from NONE to NOTEXIST state within ath11k_mac_op_sta_state(). However
in reset scenario, there is no chance for it to go through such transition.
Further, after reset, when a new connection to AP starts, ath12k_sta is zerod
in NOTEXIST to NONE transition, making rx_stats/tx_stats leaked:

Kmemleak reports:
unreferenced object 0xffff9a3cd0a23400 (size 1024):
  backtrace (crc 21ee4c52):
    kmalloc_trace_noprof+0x2ba/0x360
    ath11k_mac_op_sta_state+0x1b6/0xca0 [ath11k]
    drv_sta_state+0x11e/0x9c0 [mac80211]
    sta_info_insert_rcu+0x469/0x880 [mac80211]
    sta_info_insert+0x10/0x80 [mac80211]
    ieee80211_prep_connection+0x295/0x950 [mac80211]
    ieee80211_mgd_auth+0x230/0x5a0 [mac80211]
    cfg80211_mlme_auth+0xeb/0x2a0 [cfg80211]

Add a new function which frees them, and call it during reset to fix this issue.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30

Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
---
 drivers/net/wireless/ath/ath11k/core.c |  1 +
 drivers/net/wireless/ath/ath11k/mac.c  | 27 +++++++++++++++++++++-----
 drivers/net/wireless/ath/ath11k/mac.h  |  3 ++-
 3 files changed, 25 insertions(+), 6 deletions(-)

Comments

Jeff Johnson Aug. 27, 2024, 9:23 p.m. UTC | #1
On 8/25/2024 6:49 PM, Baochen Qiang wrote:
> Currently ath12k_sta::rx_stats/tx_stats would only get freed when the station
> transit from NONE to NOTEXIST state within ath11k_mac_op_sta_state(). However
> in reset scenario, there is no chance for it to go through such transition.
> Further, after reset, when a new connection to AP starts, ath12k_sta is zerod
> in NOTEXIST to NONE transition, making rx_stats/tx_stats leaked:
> 
> Kmemleak reports:
> unreferenced object 0xffff9a3cd0a23400 (size 1024):
>   backtrace (crc 21ee4c52):
>     kmalloc_trace_noprof+0x2ba/0x360
>     ath11k_mac_op_sta_state+0x1b6/0xca0 [ath11k]
>     drv_sta_state+0x11e/0x9c0 [mac80211]
>     sta_info_insert_rcu+0x469/0x880 [mac80211]
>     sta_info_insert+0x10/0x80 [mac80211]
>     ieee80211_prep_connection+0x295/0x950 [mac80211]
>     ieee80211_mgd_auth+0x230/0x5a0 [mac80211]
>     cfg80211_mlme_auth+0xeb/0x2a0 [cfg80211]
> 
> Add a new function which frees them, and call it during reset to fix this issue.
> 
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
> 
> Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 03187df26000..586217de9581 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -1972,6 +1972,7 @@  void ath11k_core_halt(struct ath11k *ar)
 	ar->allocated_vdev_map = 0;
 
 	ath11k_mac_scan_finish(ar);
+	ath11k_mac_station_cleanup_all(ar);
 	ath11k_mac_peer_cleanup_all(ar);
 	cancel_delayed_work_sync(&ar->scan.timeout);
 	cancel_work_sync(&ar->regd_update_work);
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index f21d37cefb65..a02fd07f8f1c 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -9512,6 +9512,15 @@  static int ath11k_mac_station_add(struct ath11k *ar,
 	return ret;
 }
 
+static void ath11k_mac_station_free_stats(struct ath11k_sta *arsta)
+{
+	kfree(arsta->tx_stats);
+	arsta->tx_stats = NULL;
+
+	kfree(arsta->rx_stats);
+	arsta->rx_stats = NULL;
+}
+
 static int ath11k_mac_station_remove(struct ath11k *ar,
 				     struct ieee80211_vif *vif,
 				     struct ieee80211_sta *sta)
@@ -9545,15 +9554,23 @@  static int ath11k_mac_station_remove(struct ath11k *ar,
 
 	ath11k_mac_dec_num_stations(arvif, sta);
 
-	kfree(arsta->tx_stats);
-	arsta->tx_stats = NULL;
-
-	kfree(arsta->rx_stats);
-	arsta->rx_stats = NULL;
+	ath11k_mac_station_free_stats(arsta);
 
 	return ret;
 }
 
+static void ath11k_mac_station_cleanup(void *data, struct ieee80211_sta *sta)
+{
+	ath11k_mac_station_free_stats(ath11k_sta_to_arsta(sta));
+}
+
+void ath11k_mac_station_cleanup_all(struct ath11k *ar)
+{
+	ieee80211_iterate_stations_atomic(ar->hw,
+					  ath11k_mac_station_cleanup,
+					  NULL);
+}
+
 static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
 				   struct ieee80211_vif *vif,
 				   struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h
index f5800fbecff8..17d0bbfc52bf 100644
--- a/drivers/net/wireless/ath/ath11k/mac.h
+++ b/drivers/net/wireless/ath/ath11k/mac.h
@@ -1,7 +1,7 @@ 
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH11K_MAC_H
@@ -179,4 +179,5 @@  int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif,
 void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar,
 				  struct ieee80211_vif *vif,
 				  struct ieee80211_chanctx_conf *ctx);
+void ath11k_mac_station_cleanup_all(struct ath11k *ar);
 #endif