Forráskód Böngészése

qcacmn: Take reference for peer before adding ast

Add reference for peer before adding ast entry
Reference is taken to avoid any synchronization
issue wrt to peer when adding ast entry.

Change-Id: Id3116daed84ad15eba515fedddb1146845542742
CRs-Fixed: 2335943
Ruchi, Agrawal 6 éve
szülő
commit
93bcf1292f
1 módosított fájl, 29 hozzáadás és 1 törlés
  1. 29 1
      dp/wifi3.0/dp_peer.c

+ 29 - 1
dp/wifi3.0/dp_peer.c

@@ -505,15 +505,32 @@ int dp_peer_add_ast(struct dp_soc *soc,
 			uint32_t flags)
 {
 	struct dp_ast_entry *ast_entry;
-	struct dp_vdev *vdev = peer->vdev;
+	struct dp_vdev *vdev = NULL;
 	struct dp_pdev *pdev = NULL;
 	uint8_t next_node_mac[6];
+	bool peer_ref_cnt = false;
 	int  ret = -1;
 
+	if (peer->delete_in_progress)
+		return 0;
+
+	if (type != CDP_TXRX_AST_TYPE_STATIC &&
+	    type != CDP_TXRX_AST_TYPE_SELF) {
+		peer_ref_cnt =  true;
+		qdf_spin_lock_bh(&soc->peer_ref_mutex);
+		qdf_atomic_inc(&peer->ref_cnt);
+		qdf_spin_unlock_bh(&soc->peer_ref_mutex);
+	}
+
+	vdev = peer->vdev;
 	if (!vdev) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			FL("Peers vdev is NULL"));
 		QDF_ASSERT(0);
+		/*Handling case when assert is disabled*/
+		if (peer_ref_cnt)
+			dp_peer_unref_delete(peer);
+
 		return ret;
 	}
 
@@ -545,6 +562,8 @@ int dp_peer_add_ast(struct dp_soc *soc,
 							    pdev->pdev_id);
 		if (ast_entry) {
 			qdf_spin_unlock_bh(&soc->ast_lock);
+			if (peer_ref_cnt)
+				dp_peer_unref_delete(peer);
 			return 0;
 		}
 	} else {
@@ -565,6 +584,8 @@ int dp_peer_add_ast(struct dp_soc *soc,
 				dp_peer_del_ast(soc, ast_entry);
 			}
 			qdf_spin_unlock_bh(&soc->ast_lock);
+			if (peer_ref_cnt)
+				dp_peer_unref_delete(peer);
 			return 0;
 		}
 	}
@@ -575,6 +596,8 @@ add_ast_entry:
 
 	if (!ast_entry) {
 		qdf_spin_unlock_bh(&soc->ast_lock);
+		if (peer_ref_cnt)
+			dp_peer_unref_delete(peer);
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			FL("fail to allocate ast_entry"));
 		QDF_ASSERT(0);
@@ -647,9 +670,14 @@ add_ast_entry:
 				mac_addr,
 				next_node_mac,
 				flags))
+			if (peer_ref_cnt)
+				dp_peer_unref_delete(peer);
 			return 0;
 	}
 
+	if (peer_ref_cnt)
+		dp_peer_unref_delete(peer);
+
 	return ret;
 }