浏览代码

qca-wifi: Avoid processing of PPDU USER multiple times in Tx capture

Currently, same user can be processed multiple times, which leads to
release ref count wrongly, with this, some of the users in PPDU
desc are never processed and can possibly cause memory leak.

Added a flag in PPDU user to indicate that the user is already
processed.

CRs-Fixed: 2718150
Change-Id: Ia00e0ad12999578157e9f8a6df0ad4763f828c88
Srinivas Pitla 5 年之前
父节点
当前提交
aa3e76eb38
共有 1 个文件被更改,包括 12 次插入4 次删除
  1. 12 4
      dp/wifi3.0/dp_tx_capture.c

+ 12 - 4
dp/wifi3.0/dp_tx_capture.c

@@ -3098,7 +3098,8 @@ check_subseq_ppdu_to_pending_q(struct dp_tx_cap_nbuf_list nbuf_ppdu_list[],
 							      peer_id);
 							      peer_id);
 		next_user = &next_ppdu->user[cur_usr_idx];
 		next_user = &next_ppdu->user[cur_usr_idx];
 
 
-		if ((next_user->skip == 1) || (peer_id != next_user->peer_id))
+		if ((next_user->skip == 1) || (peer_id != next_user->peer_id) ||
+		    (next_user->mon_procd == 1))
 			continue;
 			continue;
 
 
 		if (last_pend_ppdu) {
 		if (last_pend_ppdu) {
@@ -3129,6 +3130,8 @@ check_subseq_ppdu_to_pending_q(struct dp_tx_cap_nbuf_list nbuf_ppdu_list[],
 
 
 			/* decrement reference */
 			/* decrement reference */
 			dp_tx_cap_nbuf_list_dec_ref(ptr_nbuf_list);
 			dp_tx_cap_nbuf_list_dec_ref(ptr_nbuf_list);
+
+			next_user->mon_procd = 1;
 		}
 		}
 
 
 		if (next_user->last_enq_seq > cur_last_seq)
 		if (next_user->last_enq_seq > cur_last_seq)
@@ -3177,7 +3180,7 @@ dp_tx_mon_proc_pending_ppdus(struct dp_pdev *pdev, struct dp_tx_tid *tx_tid,
 			user = &ppdu_desc->user[cur_usr_idx];
 			user = &ppdu_desc->user[cur_usr_idx];
 
 
 			if ((user->skip == 1) || (peer_id != user->peer_id) ||
 			if ((user->skip == 1) || (peer_id != user->peer_id) ||
-			    (tx_tid->tid != user->tid))
+			    (tx_tid->tid != user->tid) || (user->mon_procd == 1))
 				continue;
 				continue;
 
 
 			if ((user->pending_retries == 0) &&
 			if ((user->pending_retries == 0) &&
@@ -3185,6 +3188,7 @@ dp_tx_mon_proc_pending_ppdus(struct dp_pdev *pdev, struct dp_tx_tid *tx_tid,
 			    qdf_nbuf_is_queue_empty(head_ppdu)) {
 			    qdf_nbuf_is_queue_empty(head_ppdu)) {
 				dp_send_data_to_stack(pdev, ppdu_desc,
 				dp_send_data_to_stack(pdev, ppdu_desc,
 						      cur_usr_idx);
 						      cur_usr_idx);
+				user->mon_procd = 1;
 				/* free ppd_desc from list */
 				/* free ppd_desc from list */
 				dp_ppdu_desc_free(ptr_nbuf_list, cur_usr_idx);
 				dp_ppdu_desc_free(ptr_nbuf_list, cur_usr_idx);
 			} else {
 			} else {
@@ -3218,6 +3222,7 @@ dp_tx_mon_proc_pending_ppdus(struct dp_pdev *pdev, struct dp_tx_tid *tx_tid,
 				qdf_nbuf_queue_add(head_ppdu, tmp_pend_nbuf);
 				qdf_nbuf_queue_add(head_ppdu, tmp_pend_nbuf);
 				/* decrement reference */
 				/* decrement reference */
 				dp_tx_cap_nbuf_list_dec_ref(ptr_nbuf_list);
 				dp_tx_cap_nbuf_list_dec_ref(ptr_nbuf_list);
+				user->mon_procd = 1;
 			}
 			}
 		}
 		}
 		return;
 		return;
@@ -3244,7 +3249,8 @@ dp_tx_mon_proc_pending_ppdus(struct dp_pdev *pdev, struct dp_tx_tid *tx_tid,
 
 
 			cur_user = &cur_ppdu_desc->user[cur_usr_idx];
 			cur_user = &cur_ppdu_desc->user[cur_usr_idx];
 
 
-			if (cur_user->skip == 1)
+			if ((cur_user->skip == 1) ||
+			    (cur_user->mon_procd == 1))
 				continue;
 				continue;
 
 
 			/* to handle last ppdu case we need to decrement */
 			/* to handle last ppdu case we need to decrement */
@@ -3293,6 +3299,7 @@ dp_tx_mon_proc_pending_ppdus(struct dp_pdev *pdev, struct dp_tx_tid *tx_tid,
 			qdf_nbuf_queue_add(head_ppdu, tmp_pend_nbuf);
 			qdf_nbuf_queue_add(head_ppdu, tmp_pend_nbuf);
 			/* decrement reference */
 			/* decrement reference */
 			dp_tx_cap_nbuf_list_dec_ref(ptr_nbuf_list);
 			dp_tx_cap_nbuf_list_dec_ref(ptr_nbuf_list);
+			cur_user->mon_procd = 1;
 		}
 		}
 		cur_index = 0;
 		cur_index = 0;
 		cur_start_seq = cur_user->start_seq;
 		cur_start_seq = cur_user->start_seq;
@@ -4433,8 +4440,9 @@ dp_check_ppdu_and_deliver(struct dp_pdev *pdev,
 				continue;
 				continue;
 
 
 			cur_user = &cur_ppdu_desc->user[usr_idx];
 			cur_user = &cur_ppdu_desc->user[usr_idx];
+
 			if ((cur_user->delayed_ba == 1) ||
 			if ((cur_user->delayed_ba == 1) ||
-			    (cur_user->skip == 1))
+			    (cur_user->skip == 1) || (cur_user->mon_procd == 1))
 				continue;
 				continue;
 
 
 			peer_id = cur_ppdu_desc->user[usr_idx].peer_id;
 			peer_id = cur_ppdu_desc->user[usr_idx].peer_id;