Browse Source

component_dev: Fix memleak issue on Rx enhanced capture

Fix memleak on Rx enhanced capture mode. Adding frag list on the
cloned buffer causing the memory leak. Allocate a MPDU control
block. The MPDU header(128 bytes) and mdsu headers(128 bytes)
link list is attached to MPDU control block frag list. The MPDU
control block is sent to osif layer to send to network stack.

Change-Id: If6c81b9d1027dfbb12277574fe9598f6fb8c5eca
Kai Chen 6 years ago
parent
commit
1cc9fe7b53
2 changed files with 50 additions and 37 deletions
  1. 7 13
      dp/inc/cdp_txrx_extd_struct.h
  2. 43 24
      dp/wifi3.0/dp_rx_mon_feature.c

+ 7 - 13
dp/inc/cdp_txrx_extd_struct.h

@@ -22,14 +22,15 @@
 #define CDP_MAX_RX_CHAINS 8
 
 #ifdef WLAN_RX_PKT_CAPTURE_ENH
+
+#define RX_ENH_CB_BUF_SIZE 0
+#define RX_ENH_CB_BUF_RESERVATION 256
+#define RX_ENH_CB_BUF_ALIGNMENT 4
+
 /**
  * struct cdp_rx_indication_mpdu_info - Rx MPDU info
  * @ppdu_id: PPDU Id
  * @duration: PPDU duration
- * @first_data_seq_ctrl: Sequence control field of first data frame
- * @ltf_size: ltf_size
- * @stbc: When set, STBC rate was used
- * @he_re: he_re (range extension)
  * @bw: Bandwidth
  *       <enum 0 bw_20_MHz>
  *       <enum 1 bw_40_MHz>
@@ -42,7 +43,6 @@
  *       <enum 1     0_4_us_sgi > Legacy short GI
  *       <enum 2     1_6_us_sgi > HE related GI
  *       <enum 3     3_2_us_sgi > HE
- * @dcm: dcm
  * @ldpc: ldpc
  * @fcs_err: FCS error
  * @ppdu_type: SU/MU_MIMO/MU_OFDMA/MU_MIMO_OFDMA/UL_TRIG/BURST_BCN/UL_BSR_RESP/
@@ -58,11 +58,7 @@
 struct cdp_rx_indication_mpdu_info {
 	uint32_t ppdu_id;
 	uint16_t duration;
-	uint16_t first_data_seq_ctrl;
-	uint64_t ltf_size:2,
-		 stbc:1,
-		 he_re:1,
-		 bw:4,
+	uint64_t bw:4,
 		 ofdma_info_valid:1,
 		 ofdma_ru_start_index:7,
 		 ofdma_ru_width:7,
@@ -70,7 +66,6 @@ struct cdp_rx_indication_mpdu_info {
 		 mcs:4,
 		 preamble:4,
 		 gi:4,
-		 dcm:1,
 		 ldpc:1,
 		 fcs_err:1,
 		 ppdu_type:5,
@@ -87,8 +82,7 @@ struct cdp_rx_indication_mpdu_info {
 /**
  * struct cdp_rx_indication_mpdu- Rx MPDU plus MPDU info
  * @mpdu_info: defined in cdp_rx_indication_mpdu_info
- * @data: skb chain of a MPDU. The first of 128 Byte of MPDU
- *        chained with first of 128 Byte of MSDUs.
+ * @nbuf: nbuf of mpdu control block
  */
 struct cdp_rx_indication_mpdu {
 	struct cdp_rx_indication_mpdu_info mpdu_info;

+ 43 - 24
dp/wifi3.0/dp_rx_mon_feature.c

@@ -29,6 +29,7 @@
 #include "qdf_mem.h"   /* qdf_mem_malloc,free */
 
 #ifdef WLAN_RX_PKT_CAPTURE_ENH
+
 static inline void
 dp_rx_free_msdu_list(struct msdu_list *msdu_list)
 {
@@ -46,8 +47,9 @@ dp_rx_free_msdu_list(struct msdu_list *msdu_list)
  *
  * Return: none
  */
-static inline void dp_nbuf_set_data_and_len(qdf_nbuf_t buf, unsigned char *data
-					    , int len)
+static inline void
+dp_nbuf_set_data_and_len(qdf_nbuf_t buf, unsigned char *data,
+			 int len)
 {
 	qdf_nbuf_set_data_pointer(buf, data);
 	qdf_nbuf_set_len(buf, len);
@@ -88,7 +90,6 @@ dp_rx_populate_cdp_indication_mpdu_info(
 	cdp_mpdu_info->ppdu_type = ppdu_info->rx_status.reception_type;
 	cdp_mpdu_info->rssi_comb = ppdu_info->rx_status.rssi_comb;
 	cdp_mpdu_info->nf = ppdu_info->rx_status.chan_noise_floor;
-	cdp_mpdu_info->timestamp = ppdu_info->rx_status.tsft;
 
 	if (ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_OFDMA) {
 		cdp_mpdu_info->nss = ppdu_info->rx_user_status[user].nss;
@@ -113,7 +114,7 @@ QDF_STATUS
 dp_rx_handle_enh_capture(struct dp_soc *soc, struct dp_pdev *pdev,
 			 struct hal_rx_ppdu_info *ppdu_info)
 {
-	qdf_nbuf_t  nbuf;
+	qdf_nbuf_t  mpdu_head;
 	uint32_t user;
 	qdf_nbuf_queue_t *mpdu_q;
 	struct cdp_rx_indication_mpdu *mpdu_ind;
@@ -132,10 +133,12 @@ dp_rx_handle_enh_capture(struct dp_soc *soc, struct dp_pdev *pdev,
 		dp_rx_populate_cdp_indication_mpdu_info(
 			pdev, &pdev->ppdu_info, mpdu_info, user);
 
-		while (!qdf_nbuf_is_queue_empty(mpdu_q)) {
-			nbuf = qdf_nbuf_queue_remove(mpdu_q);
-			mpdu_ind->nbuf = nbuf;
-			mpdu_info->fcs_err = QDF_NBUF_CB_RX_FCS_ERR(nbuf);
+		while ((mpdu_head = qdf_nbuf_queue_remove(mpdu_q))) {
+
+			mpdu_ind->nbuf = mpdu_head;
+			mpdu_info->fcs_err =
+				QDF_NBUF_CB_RX_FCS_ERR(mpdu_head);
+
 			dp_wdi_event_handler(WDI_EVENT_RX_MPDU,
 					     soc, mpdu_ind, HTT_INVALID_PEER,
 					     WDI_NO_VAL, pdev->pdev_id);
@@ -168,6 +171,8 @@ dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status,
 	qdf_nbuf_t nbuf;
 	struct msdu_list *msdu_list;
 	uint32_t user_id;
+	struct dp_soc *soc;
+	qdf_nbuf_t mpdu_head;
 
 	if (rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_DISABLED)
 		return;
@@ -178,6 +183,7 @@ dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status,
 	    (rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU_MSDU) ||
 	    ((rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) &&
 	    pdev->is_mpdu_hdr[user_id]))) {
+
 		if (*nbuf_used) {
 			nbuf = qdf_nbuf_clone(status_nbuf);
 		} else {
@@ -185,40 +191,53 @@ dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status,
 			nbuf = status_nbuf;
 		}
 
-		dp_nbuf_set_data_and_len(nbuf, ppdu_info->data,
-					  ppdu_info->hdr_len - 4);
+		if (!nbuf)
+			return;
 
+		dp_nbuf_set_data_and_len(nbuf, ppdu_info->data,
+					 ppdu_info->hdr_len
+					 - 4);
 		if (pdev->is_mpdu_hdr[user_id]) {
+			soc = pdev->soc;
+			mpdu_head = qdf_nbuf_alloc(soc->osdev,
+				RX_ENH_CB_BUF_SIZE + RX_ENH_CB_BUF_RESERVATION,
+				RX_ENH_CB_BUF_RESERVATION,
+				RX_ENH_CB_BUF_ALIGNMENT,
+				FALSE);
+
+			if (mpdu_head == NULL)
+				return;
+
 			qdf_nbuf_queue_add(&pdev->mpdu_q[user_id],
-					   nbuf);
+					   mpdu_head);
 			pdev->is_mpdu_hdr[user_id] = false;
-		} else {
-			msdu_list = &pdev->msdu_list[user_id];
-			if (!msdu_list->head)
-				msdu_list->head = nbuf;
-			else
-				msdu_list->tail->next = nbuf;
-			msdu_list->tail = nbuf;
-			msdu_list->sum_len += qdf_nbuf_len(nbuf);
 		}
+		msdu_list = &pdev->msdu_list[user_id];
+		if (!msdu_list->head)
+			msdu_list->head = nbuf;
+		else
+			msdu_list->tail->next = nbuf;
+		msdu_list->tail = nbuf;
+		msdu_list->sum_len += qdf_nbuf_len(nbuf);
 	}
 
 	if (tlv_status == HAL_TLV_STATUS_MPDU_END) {
 		msdu_list = &pdev->msdu_list[user_id];
-		nbuf = qdf_nbuf_queue_last(&pdev->mpdu_q[user_id]);
+		mpdu_head = qdf_nbuf_queue_last(&pdev->mpdu_q[user_id]);
 
-		if (nbuf) {
-			qdf_nbuf_append_ext_list(nbuf,
+		if (mpdu_head) {
+			qdf_nbuf_append_ext_list(mpdu_head,
 						 msdu_list->head,
 						 msdu_list->sum_len);
 			msdu_list->head = NULL;
 			msdu_list->tail = NULL;
 			msdu_list->sum_len = 0;
-			QDF_NBUF_CB_RX_FCS_ERR(nbuf) =  ppdu_info->fcs_err;
-			pdev->is_mpdu_hdr[user_id] = true;
+			QDF_NBUF_CB_RX_FCS_ERR(mpdu_head)
+					       =  ppdu_info->fcs_err;
 		} else {
 			dp_rx_free_msdu_list(msdu_list);
 		}
+		pdev->is_mpdu_hdr[user_id] = true;
 	}
 }