From 8ee37c6ae7eef10253bae1f05442374787e04a7d Mon Sep 17 00:00:00 2001 From: Mohit Khanna Date: Mon, 7 Aug 2017 17:15:20 -0700 Subject: [PATCH] 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 --- core/dp/txrx/ol_txrx.c | 33 ++++++++++++++------------------ core/dp/txrx/ol_txrx_peer_find.c | 7 ------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index bd477a62c617..f1af545e4158 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/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); } diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c index de8292ac74ff..62521cc6e699 100644 --- a/core/dp/txrx/ol_txrx_peer_find.c +++ b/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);