Jelajahi Sumber

qcacmn: avoid updating peer stats under SOC AST lock

In teardown API update logical delete state to peer
before deleting AST entries of peer. Also in delete
AST API use __dp_peer_get_ref_by_id to get the peer

Change-Id: I6db227a284cf3726cc241ebc98386230eca58fcf
Chaithanya Garrepalli 4 tahun lalu
induk
melakukan
650f0ffd7d
3 mengubah file dengan 16 tambahan dan 9 penghapusan
  1. 2 2
      dp/wifi3.0/dp_main.c
  2. 11 4
      dp/wifi3.0/dp_peer.c
  3. 3 3
      dp/wifi3.0/dp_peer.h

+ 2 - 2
dp/wifi3.0/dp_main.c

@@ -10179,10 +10179,10 @@ dp_peer_teardown_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	dp_peer_update_state(soc, peer, DP_PEER_STATE_LOGICAL_DELETE);
+
 	qdf_spin_lock_bh(&soc->ast_lock);
 	dp_peer_delete_ast_entries(soc, peer);
-
-	dp_peer_update_state(soc, peer, DP_PEER_STATE_LOGICAL_DELETE);
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
 	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);

+ 11 - 4
dp/wifi3.0/dp_peer.c

@@ -1248,8 +1248,12 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry)
 
 	ast_entry->delete_in_progress = true;
 
-	peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
-				     DP_MOD_ID_AST);
+	/* In teardown del ast is called after setting logical delete state
+	 * use __dp_peer_get_ref_by_id to get the reference irrespective of
+	 * state
+	 */
+	peer = __dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
+				       DP_MOD_ID_AST);
 
 	dp_peer_ast_send_wds_del(soc, ast_entry, peer);
 
@@ -1503,13 +1507,16 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc,
 		  ast_entry->next_hop, ast_entry->peer_id);
 
 	/*
-	 * If peer is NULL, the peer is about to get
+	 * If peer state is logical delete, the peer is about to get
 	 * teared down with a peer delete command to firmware,
 	 * which will cleanup all the wds ast entries.
 	 * So, no need to send explicit wds ast delete to firmware.
 	 */
 	if (ast_entry->next_hop) {
-		if (peer)
+		if (peer && dp_peer_state_cmp(peer,
+					      DP_PEER_STATE_LOGICAL_DELETE))
+			delete_in_fw = false;
+		else
 			delete_in_fw = true;
 
 		cdp_soc->ol_ops->peer_del_wds_entry(soc->ctrl_psoc,

+ 3 - 3
dp/wifi3.0/dp_peer.h

@@ -511,16 +511,16 @@ dp_peer_update_state(struct dp_soc *soc,
 		break;
 
 	default:
+		qdf_spin_unlock_bh(&peer->peer_state_lock);
 		dp_alert("Invalid peer state %u for peer "QDF_MAC_ADDR_FMT,
 			 state, QDF_MAC_ADDR_REF(peer->mac_addr.raw));
-		qdf_spin_unlock_bh(&peer->peer_state_lock);
 		return;
 	}
+	peer->peer_state = state;
+	qdf_spin_unlock_bh(&peer->peer_state_lock);
 	dp_info("Updating peer state from %u to %u mac "QDF_MAC_ADDR_FMT"\n",
 		peer_state, state,
 		QDF_MAC_ADDR_REF(peer->mac_addr.raw));
-	peer->peer_state = state;
-	qdf_spin_unlock_bh(&peer->peer_state_lock);
 }
 
 void dp_print_ast_stats(struct dp_soc *soc);