Ver código fonte

qcacld-3.0: Remove peer from peer_id_to_obj map before delete

Run through the entire peer_id_to_obj_map array and if any peer_id's
peer entry points to a particular peer, change it to NULL. Calling
this routine before deleting the peer ensures that subsequent peer_unmap
events will not access a peer object that is deleted.

CRs-Fixed: 2027846
Change-Id: I05089bece20ea070694f243feb06d222f8e50ac6
Deepak Dhamdhere 8 anos atrás
pai
commit
b0d2ddad4e

+ 3 - 0
core/dp/txrx/ol_txrx.c

@@ -3311,6 +3311,9 @@ int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer,
 			  qdf_atomic_read(&peer->ref_cnt));
 		ol_txrx_peer_tx_queue_free(pdev, peer);
 
+		/* Remove mappings from peer_id to peer object */
+		ol_txrx_peer_clear_map_peer(pdev, peer);
+
 		/*
 		 * 'array' is allocated in addba handler and is supposed to be
 		 * freed in delba handler. There is the case (for example, in

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

@@ -326,6 +326,34 @@ static void ol_txrx_peer_find_map_detach(struct ol_txrx_pdev_t *pdev)
 	qdf_mem_free(pdev->peer_id_to_obj_map);
 }
 
+/**
+ * ol_txrx_peer_clear_map_peer() - Remove map entries that refer to a peer.
+ * @pdev: pdev handle
+ * @peer: peer for removing obj map entries
+ *
+ * Run through the entire peer_id_to_obj map and nullify all the entries
+ * that map to a particular peer. Called before deleting the peer object.
+ *
+ * Return: None
+ */
+void ol_txrx_peer_clear_map_peer(ol_txrx_pdev_handle pdev,
+				 struct ol_txrx_peer_t *peer)
+{
+	int max_peers;
+	int i;
+
+	max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1;
+
+	qdf_spin_lock_bh(&pdev->peer_map_unmap_lock);
+	for (i = 0; i < max_peers; i++) {
+		if (pdev->peer_id_to_obj_map[i].peer == peer) {
+			/* Found a map entry for this peer, clear it. */
+			pdev->peer_id_to_obj_map[i].peer = NULL;
+		}
+	}
+	qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
+}
+
 /*
  * ol_txrx_peer_find_add_id() - Add peer_id entry to peer
  *
@@ -685,6 +713,7 @@ struct ol_txrx_peer_t *ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev)
 	return peer;
 }
 
+
 /*=== function definitions for debug ========================================*/
 
 #if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5

+ 2 - 0
core/dp/txrx/ol_txrx_peer_find.h

@@ -119,6 +119,8 @@ void ol_txrx_peer_find_hash_erase(struct ol_txrx_pdev_t *pdev);
 struct ol_txrx_peer_t *ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev);
 void ol_txrx_peer_remove_obj_map_entries(ol_txrx_pdev_handle pdev,
 					struct ol_txrx_peer_t *peer);
+void ol_txrx_peer_clear_map_peer(ol_txrx_pdev_handle pdev,
+				 struct ol_txrx_peer_t *peer);
 #if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5
 void ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent);
 #else