Browse Source

qcacmn: Memory leakage with WiFi traffic

The buffer was not being freed after invalid peer handler.
Error are handled and returned but buffer free was not taken care.

Change-Id: I100cdc27e6ca1af3dde7ce6561f5dfb83b87127f
syed touqeer pasha 7 years ago
parent
commit
4ffe1c5a1b
2 changed files with 14 additions and 13 deletions
  1. 14 5
      dp/wifi3.0/dp_rx.c
  2. 0 8
      dp/wifi3.0/dp_rx_err.c

+ 14 - 5
dp/wifi3.0/dp_rx.c

@@ -651,6 +651,7 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu)
 	struct ieee80211_frame *wh;
 	uint8_t i;
 	uint8_t *rx_pkt_hdr;
+	qdf_nbuf_t curr_nbuf, next_nbuf;
 
 	rx_pkt_hdr = hal_rx_pkt_hdr_get(qdf_nbuf_data(mpdu));
 	wh = (struct ieee80211_frame *)rx_pkt_hdr;
@@ -658,13 +659,13 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu)
 	if (!DP_FRAME_IS_DATA(wh)) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 				"NAWDS valid only for data frames");
-		return 1;
+		goto free;
 	}
 
 	if (qdf_nbuf_len(mpdu) < sizeof(struct ieee80211_frame)) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 				"Invalid nbuf length");
-		return 1;
+		goto free;
 	}
 
 
@@ -697,7 +698,7 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu)
 	if (!vdev) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 				"VDEV not found");
-		return 1;
+		goto free;
 	}
 
 out:
@@ -706,8 +707,16 @@ out:
 	msg.nbuf = mpdu;
 	msg.vdev_id = vdev->vdev_id;
 	if (pdev->soc->cdp_soc.ol_ops->rx_invalid_peer)
-		return pdev->soc->cdp_soc.ol_ops->rx_invalid_peer(
-				pdev->osif_pdev, &msg);
+		pdev->soc->cdp_soc.ol_ops->rx_invalid_peer(pdev->osif_pdev, &msg);
+
+free:
+	/* Drop and free packet */
+	curr_nbuf = mpdu;
+	while (curr_nbuf) {
+		next_nbuf = qdf_nbuf_next(curr_nbuf);
+		qdf_nbuf_free(curr_nbuf);
+		curr_nbuf = next_nbuf;
+	}
 
 	return 0;
 }

+ 0 - 8
dp/wifi3.0/dp_rx_err.c

@@ -394,7 +394,6 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr,
 								uint8_t mac_id)
 {
 	bool mpdu_done = false;
-	qdf_nbuf_t curr_nbuf, next_nbuf;
 
 	/* TODO: Currently only single radio is supported, hence
 	 * pdev hard coded to '0' index
@@ -404,13 +403,6 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr,
 	if (hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr)) {
 		qdf_nbuf_set_rx_chfrag_start(nbuf, 1);
 
-		curr_nbuf = dp_pdev->invalid_peer_head_msdu;
-		while (curr_nbuf) {
-			next_nbuf = qdf_nbuf_next(curr_nbuf);
-			qdf_nbuf_free(curr_nbuf);
-			curr_nbuf = next_nbuf;
-		}
-
 		dp_pdev->invalid_peer_head_msdu = NULL;
 		dp_pdev->invalid_peer_tail_msdu = NULL;