From b0d2ddad4ef0e0682deba959a152b9cb93a531ad Mon Sep 17 00:00:00 2001 From: Deepak Dhamdhere Date: Mon, 3 Apr 2017 01:01:50 -0700 Subject: [PATCH] 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 --- core/dp/txrx/ol_txrx.c | 3 +++ core/dp/txrx/ol_txrx_peer_find.c | 29 +++++++++++++++++++++++++++++ core/dp/txrx/ol_txrx_peer_find.h | 2 ++ 3 files changed, 34 insertions(+) diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 47c8b38c566b..a80d57c0a251 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/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 diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c index 924c7aa04fc7..0c95883664ea 100644 --- a/core/dp/txrx/ol_txrx_peer_find.c +++ b/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 diff --git a/core/dp/txrx/ol_txrx_peer_find.h b/core/dp/txrx/ol_txrx_peer_find.h index b11926422ac5..69ed091deb8b 100644 --- a/core/dp/txrx/ol_txrx_peer_find.h +++ b/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