소스 검색

qcacmn: Fix a double free issue for tx descriptor

Tx descriptors that belong to a particular vdev are released in
vdev detach path. Since DP soc is not detached yet, interrupts
are not disabled, so it is possible that host gets completions
for same tx descriptor and it tries to process it again.

Add a check for vdev in tx completion path to avoid duplicate
processing of tx descriptors

Change-Id: I5a62ef4d981dbfd0a5ca7483acf4270145d016be
Pamidipati, Vijay 6 년 전
부모
커밋
12e8f33fc6
2개의 변경된 파일17개의 추가작업 그리고 0개의 파일을 삭제
  1. 15 0
      dp/wifi3.0/dp_tx.c
  2. 2 0
      dp/wifi3.0/dp_tx_desc.h

+ 15 - 0
dp/wifi3.0/dp_tx.c

@@ -3128,6 +3128,21 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota)
 				(tx_desc_id & DP_TX_DESC_ID_OFFSET_MASK) >>
 				DP_TX_DESC_ID_OFFSET_OS);
 
+		/*
+		 * If the descriptor is already freed in vdev_detach,
+		 * continue to next descriptor
+		 */
+		if (!tx_desc->vdev) {
+			QDF_TRACE(QDF_MODULE_ID_DP,
+				  QDF_TRACE_LEVEL_INFO,
+				  "Descriptor freed in vdev_detach %d",
+				  tx_desc_id);
+
+			num_processed += !(count & DP_TX_NAPI_BUDGET_DIV_MASK);
+			count++;
+			continue;
+		}
+
 		/*
 		 * If the release source is FW, process the HTT status
 		 */

+ 2 - 0
dp/wifi3.0/dp_tx_desc.h

@@ -605,6 +605,8 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc,
 {
 	TX_DESC_LOCK_LOCK(&soc->tx_desc[desc_pool_id].lock);
 
+	tx_desc->vdev = NULL;
+	tx_desc->nbuf = NULL;
 	tx_desc->flags = 0;
 	tx_desc->next = soc->tx_desc[desc_pool_id].freelist;
 	soc->tx_desc[desc_pool_id].freelist = tx_desc;