Ver Fonte

qcacld-3.0: Refactor cp status callback handlers

Duplicate stats buffer in the callback so that all
allocations get freed by its owner, this will avoid
memory leak issue because of race condition between
umac and upper layer.

Change-Id: Id18d75eb9adc46a6147634eb5b1e0babe32c7c37
CRs-Fixed: 2292038
Arif Hussain há 6 anos atrás
pai
commit
8b54a03f96
2 ficheiros alterados com 59 adições e 59 exclusões
  1. 16 16
      core/hdd/src/wlan_hdd_hostapd_wext.c
  2. 43 43
      core/hdd/src/wlan_hdd_stats.c

+ 16 - 16
core/hdd/src/wlan_hdd_hostapd_wext.c

@@ -2415,7 +2415,7 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
 {
 	int ret, i;
 	struct hdd_context *hddctx;
-	struct stats_event rssi_info;
+	struct stats_event *rssi_info;
 	char macaddrarray[MAC_ADDRESS_STR_LEN];
 	struct hdd_adapter *adapter = netdev_priv(dev);
 	struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT;
@@ -2448,27 +2448,27 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
 			hdd_err("String to Hex conversion Failed");
 	}
 
-	ret = wlan_cfg80211_mc_cp_stats_get_peer_rssi(adapter->hdd_vdev,
-						      macaddress.bytes,
-						      &rssi_info);
-	if (ret) {
-		hdd_err("Unable to retrieve peer rssi: %d", ret);
-		wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info);
+	rssi_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(adapter->hdd_vdev,
+							    macaddress.bytes,
+							    &ret);
+	if (ret || !rssi_info) {
+		wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
 		return ret;
 	}
 
 	wrqu->data.length = scnprintf(extra, IW_PRIV_SIZE_MASK, "\n");
-	for (i = 0; i < rssi_info.num_peer_stats; i++) {
-		wrqu->data.length += scnprintf(extra + wrqu->data.length,
-					IW_PRIV_SIZE_MASK - wrqu->data.length,
-					"[%pM] [%d]\n",
-					rssi_info.peer_stats[i].peer_macaddr,
-					rssi_info.peer_stats[i].peer_rssi);
-	}
-	wrqu->data.length++;
-	wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info);
+	for (i = 0; i < rssi_info->num_peer_stats; i++)
+		wrqu->data.length +=
+			scnprintf(extra + wrqu->data.length,
+				  IW_PRIV_SIZE_MASK - wrqu->data.length,
+				  "[%pM] [%d]\n",
+				  rssi_info->peer_stats[i].peer_macaddr,
+				  rssi_info->peer_stats[i].peer_rssi);
 
+	wrqu->data.length++;
+	wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
 	hdd_exit();
+
 	return 0;
 }
 #else

+ 43 - 43
core/hdd/src/wlan_hdd_stats.c

@@ -5020,9 +5020,9 @@ int wlan_hdd_get_rcpi(struct hdd_adapter *adapter, uint8_t *mac,
 #ifdef QCA_SUPPORT_CP_STATS
 QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value)
 {
-	int ret, i;
+	int ret = 0, i;
 	struct hdd_station_ctx *sta_ctx;
-	struct stats_event rssi_info;
+	struct stats_event *rssi_info;
 
 	if (NULL == adapter) {
 		hdd_err("Invalid context, adapter");
@@ -5051,27 +5051,27 @@ QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value)
 		return QDF_STATUS_SUCCESS;
 	}
 
-	ret = wlan_cfg80211_mc_cp_stats_get_peer_rssi(adapter->hdd_vdev,
-						sta_ctx->conn_info.bssId.bytes,
-						&rssi_info);
-	if (ret) {
-		hdd_err("Unable to retrieve peer rssi: %d", ret);
-		wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info);
+	rssi_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(
+			adapter->hdd_vdev,
+			sta_ctx->conn_info.bssId.bytes,
+			&ret);
+	if (ret || !rssi_info) {
+		wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
 		return ret;
 	}
 
-	for (i = 0; i < rssi_info.num_peer_stats; i++) {
-		if (!qdf_mem_cmp(rssi_info.peer_stats[i].peer_macaddr,
+	for (i = 0; i < rssi_info->num_peer_stats; i++) {
+		if (!qdf_mem_cmp(rssi_info->peer_stats[i].peer_macaddr,
 				 sta_ctx->conn_info.bssId.bytes,
 				 WLAN_MACADDR_LEN)) {
-			*rssi_value = rssi_info.peer_stats[i].peer_rssi;
+			*rssi_value = rssi_info->peer_stats[i].peer_rssi;
 			hdd_debug("RSSI = %d", *rssi_value);
-			wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info);
+			wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
 			return QDF_STATUS_SUCCESS;
 		}
 	}
 
-	wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info);
+	wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
 	hdd_err("bss peer not present in returned result");
 	return QDF_STATUS_E_FAULT;
 }
@@ -5752,68 +5752,68 @@ return_cached_results:
 #ifdef QCA_SUPPORT_CP_STATS
 int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
 {
-	int ret;
+	int ret = 0;
 	uint8_t mcs_rate_flags;
-	struct stats_event stats = {0};
-
-	ret =  wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->hdd_vdev,
-							   &stats);
+	struct stats_event *stats;
 
-	if (!stats.vdev_summary_stats || !stats.vdev_chain_rssi) {
-		hdd_err("summary_stats: %pK, chain_rssi: %pK",
-			stats.vdev_summary_stats, stats.vdev_chain_rssi);
-		return -EINVAL;
+	stats = wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->hdd_vdev,
+							    &ret);
+	if (ret || !stats) {
+		wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
+		return ret;
 	}
 
 	/* save summary stats to legacy location */
 	qdf_mem_copy(adapter->hdd_stats.summary_stat.retry_cnt,
-		stats.vdev_summary_stats[0].stats.retry_cnt,
+		stats->vdev_summary_stats[0].stats.retry_cnt,
 		sizeof(adapter->hdd_stats.summary_stat.retry_cnt));
 	qdf_mem_copy(adapter->hdd_stats.summary_stat.multiple_retry_cnt,
-		stats.vdev_summary_stats[0].stats.multiple_retry_cnt,
+		stats->vdev_summary_stats[0].stats.multiple_retry_cnt,
 		sizeof(adapter->hdd_stats.summary_stat.multiple_retry_cnt));
 	qdf_mem_copy(adapter->hdd_stats.summary_stat.tx_frm_cnt,
-		stats.vdev_summary_stats[0].stats.tx_frm_cnt,
+		stats->vdev_summary_stats[0].stats.tx_frm_cnt,
 		sizeof(adapter->hdd_stats.summary_stat.tx_frm_cnt));
 	qdf_mem_copy(adapter->hdd_stats.summary_stat.fail_cnt,
-		stats.vdev_summary_stats[0].stats.fail_cnt,
+		stats->vdev_summary_stats[0].stats.fail_cnt,
 		sizeof(adapter->hdd_stats.summary_stat.fail_cnt));
 	adapter->hdd_stats.summary_stat.snr =
-		stats.vdev_summary_stats[0].stats.snr;
+		stats->vdev_summary_stats[0].stats.snr;
 	adapter->hdd_stats.summary_stat.rssi =
-		stats.vdev_summary_stats[0].stats.rssi;
+		stats->vdev_summary_stats[0].stats.rssi;
 	adapter->hdd_stats.summary_stat.rx_frm_cnt =
-		stats.vdev_summary_stats[0].stats.rx_frm_cnt;
+		stats->vdev_summary_stats[0].stats.rx_frm_cnt;
 	adapter->hdd_stats.summary_stat.frm_dup_cnt =
-		stats.vdev_summary_stats[0].stats.frm_dup_cnt;
+		stats->vdev_summary_stats[0].stats.frm_dup_cnt;
 	adapter->hdd_stats.summary_stat.rts_fail_cnt =
-		stats.vdev_summary_stats[0].stats.rts_fail_cnt;
+		stats->vdev_summary_stats[0].stats.rts_fail_cnt;
 	adapter->hdd_stats.summary_stat.ack_fail_cnt =
-		stats.vdev_summary_stats[0].stats.ack_fail_cnt;
+		stats->vdev_summary_stats[0].stats.ack_fail_cnt;
 	adapter->hdd_stats.summary_stat.rts_succ_cnt =
-		stats.vdev_summary_stats[0].stats.rts_succ_cnt;
+		stats->vdev_summary_stats[0].stats.rts_succ_cnt;
 	adapter->hdd_stats.summary_stat.rx_discard_cnt =
-		stats.vdev_summary_stats[0].stats.rx_discard_cnt;
+		stats->vdev_summary_stats[0].stats.rx_discard_cnt;
 	adapter->hdd_stats.summary_stat.rx_error_cnt =
-		stats.vdev_summary_stats[0].stats.rx_error_cnt;
+		stats->vdev_summary_stats[0].stats.rx_error_cnt;
 
 	/* save class a stats to legacy location */
 	adapter->hdd_stats.class_a_stat.nss =
 		wlan_vdev_mlme_get_nss(adapter->hdd_vdev);
-	adapter->hdd_stats.class_a_stat.tx_rate = stats.tx_rate;
-	adapter->hdd_stats.class_a_stat.tx_rate_flags = stats.tx_rate_flags;
+	adapter->hdd_stats.class_a_stat.tx_rate = stats->tx_rate;
+	adapter->hdd_stats.class_a_stat.tx_rate_flags = stats->tx_rate_flags;
 	adapter->hdd_stats.class_a_stat.mcs_index =
-		sme_get_mcs_idx(stats.tx_rate * 5, stats.tx_rate_flags,
-			&adapter->hdd_stats.class_a_stat.nss, &mcs_rate_flags);
+		sme_get_mcs_idx(stats->tx_rate * 5,
+				stats->tx_rate_flags,
+				&adapter->hdd_stats.class_a_stat.nss,
+				&mcs_rate_flags);
 	adapter->hdd_stats.class_a_stat.mcs_rate_flags = mcs_rate_flags;
 
 	/* save per chain rssi to legacy location */
 	qdf_mem_copy(adapter->hdd_stats.per_chain_rssi_stats.rssi,
-		     stats.vdev_chain_rssi[0].chain_rssi,
-		     sizeof(stats.vdev_chain_rssi[0].chain_rssi));
+		     stats->vdev_chain_rssi[0].chain_rssi,
+		     sizeof(stats->vdev_chain_rssi[0].chain_rssi));
+	wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
 
-	wlan_cfg80211_mc_cp_stats_put_station_stats(&stats);
-	return ret;
+	return 0;
 }
 #else /* QCA_SUPPORT_CP_STATS */
 struct station_stats {