From 650f0ffd7d58cff6b96686bc1b29645d5e9cf912 Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Thu, 1 Oct 2020 16:36:20 +0530 Subject: [PATCH] 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 --- dp/wifi3.0/dp_main.c | 4 ++-- dp/wifi3.0/dp_peer.c | 15 +++++++++++---- dp/wifi3.0/dp_peer.h | 6 +++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 934934fb42..62857c0939 100644 --- a/dp/wifi3.0/dp_main.c +++ b/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); diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index c29225aac9..b75aaba357 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/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, diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 1a14d47d5e..451fe3e44d 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/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);