Przeglądaj źródła

qcacld-3.0: Remove extra peer ref during attach

Currently during  peer initialization (ol_txrx_peer_attach), we are
initializing peer refcount to 2. This is done to prevent peer
deletion, in case some logic tries to delete a peer when the host has
not received peer map events.

The above logic fails to address the condition when there is roaming
failure, followed by peer deletion from userpace. In this case, host
tries to create a peer and initializes refcount to 2. However, since
roaming fails, firmware does not send out peer map events. In the
meanwhile, the framework tries to delete the existing peer. This
deletion following the peer creation and absence of peer map leads to an
incorrect peer refcount even after deletion and hence this peer does not
get deleted.

Initialize peer with refcount of 2 but 1 instead. In case a map or
unmap arrives after peer deletion, the existing logic will
try to find a peer in the peer hash bins or peer_id_obj_map and will
not find the peer.

Change-Id: Ia3ba6842122dba49281d7bd00303cbe7685ef91c
CRs-Fixed: 2087373
Mohit Khanna 7 lat temu
rodzic
commit
8ee37c6ae7
2 zmienionych plików z 14 dodań i 26 usunięć
  1. 14 19
      core/dp/txrx/ol_txrx.c
  2. 0 7
      core/dp/txrx/ol_txrx_peer_find.c

+ 14 - 19
core/dp/txrx/ol_txrx.c

@@ -2516,12 +2516,12 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
 		cmp_wait_mac = true;
 
 	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
-	/* check for duplicate exsisting peer */
+	/* check for duplicate existing peer */
 	TAILQ_FOREACH(temp_peer, &vdev->peer_list, peer_list_elem) {
 		if (!ol_txrx_peer_find_mac_addr_cmp(&temp_peer->mac_addr,
 			(union ol_txrx_align_mac_addr_t *)peer_mac_addr)) {
 			ol_txrx_info_high(
-				"vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) already exsist.\n",
+				"vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) already exists.\n",
 				vdev->vdev_id,
 				peer_mac_addr[0], peer_mac_addr[1],
 				peer_mac_addr[2], peer_mac_addr[3],
@@ -2540,7 +2540,7 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
 					&temp_peer->mac_addr,
 					&vdev->last_peer_mac_addr)) {
 			ol_txrx_info_high(
-				"vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) old peer exsist.\n",
+				"vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) old peer exists.\n",
 				vdev->vdev_id,
 				vdev->last_peer_mac_addr.raw[0],
 				vdev->last_peer_mac_addr.raw[1],
@@ -2569,7 +2569,7 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
 		rc = qdf_wait_single_event(&vdev->wait_delete_comp,
 					   PEER_DELETION_TIMEOUT);
 		if (QDF_STATUS_SUCCESS != rc) {
-			ol_txrx_err("error waiting for peer(%d) deletion, status %d\n",
+			ol_txrx_err("error waiting for peer_id(%d) deletion, status %d\n",
 				    vdev->wait_on_peer_id, (int) rc);
 			cds_trigger_recovery(PEER_DEL_TIMEOUT);
 			vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID;
@@ -2615,20 +2615,12 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
 	qdf_atomic_init(&peer->flush_in_progress);
 
 	qdf_atomic_init(&peer->ref_cnt);
-
 	/* keep one reference for attach */
 	OL_TXRX_PEER_INC_REF_CNT(peer);
 
-	/*
-	 * Set a flag to indicate peer create is pending in firmware and
-	 * increment ref_cnt so that peer will not get deleted while
-	 * peer create command is pending in firmware.
-	 * First peer_map event from firmware signifies successful
-	 * peer creation and it will be decremented in peer_map handling.
-	 */
+	/* Set a flag to indicate peer create is pending in firmware */
 	qdf_atomic_init(&peer->fw_create_pending);
 	qdf_atomic_set(&peer->fw_create_pending, 1);
-	OL_TXRX_PEER_INC_REF_CNT(peer);
 
 	peer->valid = 1;
 	qdf_timer_init(pdev->osdev, &peer->peer_unmap_timer,
@@ -3366,10 +3358,13 @@ int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer,
 			qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
 		}
 
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "%s: Deleting peer %pK (%pM) ref_cnt = %d",
-			  __func__, peer, peer->mac_addr.raw,
-			  qdf_atomic_read(&peer->ref_cnt));
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+			   "[%s][%d]: Deleting peer %p (%pM) peer->ref_cnt = %d %s",
+			   fname, line, peer, peer->mac_addr.raw,
+			   qdf_atomic_read(&peer->ref_cnt),
+			   qdf_atomic_read(&peer->fw_create_pending) == 1 ?
+			   "(No Maps received)" : "");
+
 		ol_txrx_peer_tx_queue_free(pdev, peer);
 
 		/* Remove mappings from peer_id to peer object */
@@ -3398,8 +3393,8 @@ int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer,
 		qdf_mem_free(peer);
 	} else {
 		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "[%s][%d]: ref delete peer %pK peer->ref_cnt = %d",
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+			  "[%s][%d]: ref delete peer %p peer->ref_cnt = %d",
 			  fname, line, peer, rc);
 	}
 

+ 0 - 7
core/dp/txrx/ol_txrx_peer_find.c

@@ -422,14 +422,7 @@ static inline void ol_txrx_peer_find_add_id(struct ol_txrx_pdev_t *pdev,
 	}
 
 	if (qdf_atomic_read(&peer->fw_create_pending) == 1) {
-		/*
-		 * First peer map event signifies successful peer
-		 * creation in firmware. Decrement the ref count
-		 * which was incremented when peer create command
-		 * was sent to firmware.
-		 */
 		qdf_atomic_set(&peer->fw_create_pending, 0);
-		OL_TXRX_PEER_UNREF_DELETE(peer);
 	}
 
 	qdf_spin_unlock(&pdev->peer_map_unmap_lock);