Jelajahi Sumber

qcacld-3.0: Use qdf_timer_sync_cancel to stop peer_unmap_timer

Peer may get deleted between the time peer_unmap_timer fires and
the handler gets executed in mc thread context, causing memory
access error. Use qdf_timer_sync_cancel() to wait for the handler
to finish its job before freeing the peer object.

CRs-Fixed: 2026393
Change-Id: Ie60b5c300be529d529f7e836adc0e3be917fe2e8
Deepak Dhamdhere 8 tahun lalu
induk
melakukan
2b283c6543
2 mengubah file dengan 9 tambahan dan 7 penghapusan
  1. 8 6
      core/dp/txrx/ol_txrx.c
  2. 1 1
      core/dp/txrx/ol_txrx_types.h

+ 8 - 6
core/dp/txrx/ol_txrx.c

@@ -2459,8 +2459,8 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
 	qdf_atomic_inc(&peer->ref_cnt);
 
 	peer->valid = 1;
-	qdf_mc_timer_init(&peer->peer_unmap_timer, QDF_TIMER_TYPE_SW,
-			  peer_unmap_timer_handler, peer);
+	qdf_timer_init(pdev->osdev, &peer->peer_unmap_timer,
+		       peer_unmap_timer_handler, peer, QDF_TIMER_TYPE_SW);
 
 	ol_txrx_peer_find_hash_add(pdev, peer);
 
@@ -3149,7 +3149,8 @@ int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
 			vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID;
 		}
 
-		qdf_mc_timer_destroy(&peer->peer_unmap_timer);
+		qdf_timer_sync_cancel(&peer->peer_unmap_timer);
+		qdf_timer_free(&peer->peer_unmap_timer);
 
 		/* check whether the parent vdev has no peers left */
 		if (TAILQ_EMPTY(&vdev->peer_list)) {
@@ -3365,9 +3366,10 @@ static void ol_txrx_peer_detach(void *ppeer)
 	 * Create a timer to track unmap events when the sta peer gets deleted.
 	 */
 	if (vdev->opmode == wlan_op_mode_sta) {
-		qdf_mc_timer_start(&peer->peer_unmap_timer,
-				   OL_TXRX_PEER_UNMAP_TIMEOUT);
-		ol_txrx_info("started peer_unmap_timer for peer %p", peer);
+		qdf_timer_start(&peer->peer_unmap_timer,
+				OL_TXRX_PEER_UNMAP_TIMEOUT);
+		ol_txrx_info("%s: started peer_unmap_timer for peer %p",
+			     __func__, peer);
 	}
 
 	/*

+ 1 - 1
core/dp/txrx/ol_txrx_types.h

@@ -1229,7 +1229,7 @@ struct ol_txrx_peer_t {
 	qdf_time_t last_disassoc_rcvd;
 	qdf_time_t last_deauth_rcvd;
 	qdf_atomic_t fw_create_pending;
-	qdf_mc_timer_t peer_unmap_timer;
+	qdf_timer_t peer_unmap_timer;
 };
 
 struct ol_rx_remote_data {