diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h index 84d3ef0a137d..3dcdf1753794 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h @@ -279,9 +279,7 @@ typedef void (*wlan_objmgr_pdev_op_handler)(struct wlan_objmgr_pdev *pdev, * @handler: the handler will be called for each object of requested type * the handler should be implemented to perform required operation * @arg: agruments passed by caller - * @lock_free_op: This gives provision to run this API with out lock protected - * It would be useful, for operations like Obj Delete, where - * lock should not be taken by caller. + * @lock_free_op: its obsolete * @dbg_id: id of the caller * * API to be used for performing the operations on all VDEV/PEER objects diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h index 153e5dba12a6..97f2ff87d5b5 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h @@ -432,6 +432,39 @@ static inline struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head( return peer; } +/** + * wlan_psoc_peer_list_peek_active_head() - get active head of psoc peer list + * @peer_list: wlan_peer_list + * @hash_index: peer list hash index + * @dbg_id: Ref count debug module id + * + * API to get the head peer of given peer (of psoc's peer list) + * + * Return: + * @peer: head peer + */ +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + wlan_objmgr_ref_dbgid dbg_id); + +/** + * wlan_psoc_peer_list_peek_head_lock_ref() - get head of psoc peer list + * with ref and lock protected + * @peer_list: wlan_peer_list + * @hash_index: peer list hash index + * @dbg_id: Ref count debug module id + * + * API to get the head peer of given peer (of psoc's peer list) + * + * Return: + * @peer: head peer + */ +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_vdev_peer_list_peek_head() - get head of vdev peer list * @peer_list: qdf_list_t @@ -457,6 +490,22 @@ static inline struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_head( return peer; } +/** + * wlan_vdev_peer_list_peek_active_head() - get active head of vdev peer list + * @vdev: VDEV object + * @peer_list: qdf_list_t + * @dbg_id: Ref count debug module id + * + * API to get the active head peer of given peer (of vdev's peer list) + * + * Return: + * @peer: active head peer + */ +struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_peer_get_next_peer_of_vdev() - get next peer of vdev list * @peer: PEER object @@ -489,6 +538,24 @@ static inline struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_vdev( return peer_next; } +/** + * wlan_peer_get_next_active_peer_of_vdev() - get next active_peer of vdev list + * @vdev: VDEV object + * @peer_list: Peer object list + * @peer: PEER object + * @dbg_id: Ref count debug module id + * + * API to get the next active peer of given peer (of vdev's peer list) + * + * Return: + * @next_peer: PEER object + */ +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_peer_set_next_peer_of_vdev() - add peer to vdev peer list * @peer: PEER object @@ -511,6 +578,7 @@ static inline void wlan_peer_set_next_peer_of_vdev(qdf_list_t *peer_list, /** * wlan_peer_get_next_peer_of_psoc() - get next peer to psoc peer list + * @peer_list: Peer list * @peer: PEER object * * API to get the next peer of given peer (of psoc's peer list) @@ -541,6 +609,45 @@ static inline struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc( return peer_next; } +/** + * wlan_peer_get_next_active_peer_of_psoc() - get next active peer to psoc peer + * list + * @peer_list: Peer list + * @hash_index: peer list hash index + * @peer: PEER object + * @dbg_id: Ref count debug module id + * + * API to get the next peer of given peer (of psoc's peer list) + * + * Return: + * @next_peer: PEER object + */ +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id); + + +/** + * wlan_peer_get_next_peer_of_psoc_ref() - get next peer to psoc peer list + * with lock and ref taken + * @peer_list: Peer list + * @hash_index: peer list hash index + * @peer: PEER object + * @dbg_id: Ref count debug module id + * + * API to get the next peer of given peer (of psoc's peer list) + * + * Return: + * @next_peer: PEER object + */ +struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_peer_set_next_peer_of_psoc() - add peer to psoc peer list * @peer: PEER object diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h index 7b44bb674e1f..38c2484d8f55 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h @@ -442,9 +442,7 @@ typedef void (*wlan_objmgr_op_handler)(struct wlan_objmgr_psoc *psoc, * @handler: the handler will be called for each object of requested type * the handler should be implemented to perform required operation * @arg: agruments passed by caller - * @lock_free_op: This gives provision to run this API with out lock protected - * It would be useful, for operations like Obj Delete, where - * lock should not be taken by caller. + * @lock_free_op: its obsolete * @dbg_id: id of the caller * * API to be used for performing the operations on all PDEV/VDEV/PEER objects @@ -466,11 +464,7 @@ QDF_STATUS wlan_objmgr_iterate_obj_list( * @handler: the handler will be called for each object of requested type * the handler should be implemented to perform required operation * @arg: agruments passed by caller - * @lock_free_op: This gives provision to run this API with out lock protected - * It would be useful, for operations like Obj Delete, where - * lock should not be taken by caller. - * Please be cautious, when you do lock_free_op, it would cause - * issues in SMP scenarios + * @lock_free_op: its obsolete * @dbg_id: id of the caller * * API to be used for performing the operations on all PDEV/VDEV/PEER objects diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h index a10cd7603c2f..d8dad81b0645 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h @@ -495,8 +495,8 @@ QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_creation( enum wlan_umac_comp_id id); /** - * wlan_objmgr_trigger_vdev_comp_priv_object_deletion() - vdev - * comp object deletion + * wlan_objmgr_trigger_vdev_comp_priv_object_deletion() - vdev comp + * object deletion * @vdev: VDEV object * @id: Component id * @@ -544,7 +544,7 @@ static inline struct wlan_objmgr_pdev *wlan_vdev_get_pdev( * wlan_pdev_vdev_list_peek_head() - get first vdev from pdev list * @peer_list: qdf_list_t * - * API to get the head vdev of given peer (of pdev's vdev list) + * API to get the head vdev of given vdev (of pdev's vdev list) * * Caller need to acquire lock with wlan_vdev_obj_lock() * @@ -565,6 +565,22 @@ static inline struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_head( return vdev; } +/** + * wlan_pdev_vdev_list_peek_active_head() - get first active vdev from pdev list + * @vdev: VDEV object + * @vdev_list: qdf_list_t + * @dbg_id: id of the caller + * + * API to get the head active vdev of given vdev (of pdev's vdev list) + * + * Return: + * @peer: head peer + */ +struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_vdev_get_next_vdev_of_pdev() - get next vdev * @vdev: VDEV object @@ -597,6 +613,25 @@ static inline struct wlan_objmgr_vdev *wlan_vdev_get_next_vdev_of_pdev( return vdev_next; } +/** + * wlan_vdev_get_next_active_vdev_of_pdev() - get next active vdev + * @pdev: PDEV object + * @vdev_list: qdf_list_t + * @vdev: VDEV object + * @dbg_id: id of the caller + * + * API to get next active vdev object pointer of vdev + * + * Return: + * @vdev_next: VDEV object + */ +struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid dbg_id); + + /** * wlan_vdev_set_pdev() - set pdev * @vdev: VDEV object diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c index 9e1f555da363..ba1e25c61856 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c @@ -411,29 +411,21 @@ static void wlan_objmgr_pdev_vdev_iterate_peers(struct wlan_objmgr_pdev *pdev, /* Iterating through vdev's peer list, so lock is needed */ - if (!lock_free_op) - wlan_vdev_obj_lock(vdev); /* Get peer list of the vdev */ peer_list = &vdev->vdev_objmgr.wlan_peer_list; if (peer_list != NULL) { - peer = wlan_vdev_peer_list_peek_head(peer_list); + peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list, + dbg_id); while (peer != NULL) { - /* Get next peer pointer */ - peer_next = wlan_peer_get_next_peer_of_vdev(peer_list, - peer); - /* Increment ref count, to hold the - peer pointer */ - if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == - QDF_STATUS_SUCCESS) { - /* Invoke the handler */ - handler(pdev, (void *)peer, arg); - wlan_objmgr_peer_release_ref(peer, dbg_id); - } + /* Invoke the handler */ + handler(pdev, (void *)peer, arg); + /* Get next peer pointer, increments the ref count */ + peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev, + peer_list, peer, dbg_id); + wlan_objmgr_peer_release_ref(peer, dbg_id); peer = peer_next; } } - if (!lock_free_op) - wlan_vdev_obj_unlock(vdev); } QDF_STATUS wlan_objmgr_pdev_iterate_obj_list( @@ -448,54 +440,40 @@ QDF_STATUS wlan_objmgr_pdev_iterate_obj_list( struct wlan_objmgr_vdev *vdev = NULL; struct wlan_objmgr_vdev *vdev_next = NULL; - /* If caller requests for lock free opeation, do not acquire - handler will handle the synchronization*/ - if (!lock_free_op) - wlan_pdev_obj_lock(pdev); /* VDEV list */ vdev_list = &objmgr->wlan_vdev_list; + switch (obj_type) { case WLAN_VDEV_OP: /* Iterate through all VDEV object, and invoke handler for each VDEV object */ - vdev = wlan_pdev_vdev_list_peek_head(vdev_list); + vdev = wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list, + dbg_id); while (vdev != NULL) { - /* - * Get next vdev (handler can be invoked for - * vdev deletion also - */ - vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, - vdev); - if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == - QDF_STATUS_SUCCESS) { - handler(pdev, (void *)vdev, arg); - wlan_objmgr_vdev_release_ref(vdev, dbg_id); - } + handler(pdev, (void *)vdev, arg); + /* Get next vdev, it increments ref of next vdev */ + vdev_next = wlan_vdev_get_next_active_vdev_of_pdev( + pdev, vdev_list, vdev, dbg_id); + wlan_objmgr_vdev_release_ref(vdev, dbg_id); vdev = vdev_next; } break; case WLAN_PEER_OP: - vdev = wlan_pdev_vdev_list_peek_head(vdev_list); - while (vdev != NULL) { - /* Get Next VDEV */ - vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, - vdev); - if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == - QDF_STATUS_SUCCESS) { - wlan_objmgr_pdev_vdev_iterate_peers(pdev, vdev, - handler, arg, - lock_free_op, + vdev = wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list, dbg_id); - wlan_objmgr_vdev_release_ref(vdev, dbg_id); - } + while (vdev != NULL) { + wlan_objmgr_pdev_vdev_iterate_peers(pdev, vdev, handler, + arg, lock_free_op, dbg_id); + /* Get next vdev, it increments ref of next vdev */ + vdev_next = wlan_vdev_get_next_active_vdev_of_pdev( + pdev, vdev_list, vdev, dbg_id); + wlan_objmgr_vdev_release_ref(vdev, dbg_id); vdev = vdev_next; } break; default: break; } - if (!lock_free_op) - wlan_pdev_obj_unlock(pdev); return QDF_STATUS_SUCCESS; } diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c index ce56d2bd1535..00db5e30e1bc 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c @@ -672,3 +672,193 @@ void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer, return; } qdf_export_symbol(wlan_objmgr_peer_release_ref); + +struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer; + qdf_list_node_t *vdev_node = NULL; + qdf_list_node_t *prev_vdev_node = NULL; + + wlan_vdev_obj_lock(vdev); + + if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) { + wlan_vdev_obj_unlock(vdev); + return NULL; + } + + do { + peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer, + vdev_peer); + + if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == + QDF_STATUS_SUCCESS) { + wlan_vdev_obj_unlock(vdev); + return peer; + } + + prev_vdev_node = vdev_node; + } while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == + QDF_STATUS_SUCCESS); + + wlan_vdev_obj_unlock(vdev); + + return NULL; +} + +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer_next; + qdf_list_node_t *vdev_node = NULL; + qdf_list_node_t *prev_vdev_node = NULL; + + if (peer == NULL) + return NULL; + + wlan_vdev_obj_lock(vdev); + + prev_vdev_node = &peer->vdev_peer; + while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == + QDF_STATUS_SUCCESS) { + peer_next = qdf_container_of(vdev_node, struct wlan_objmgr_peer, + vdev_peer); + + if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) == + QDF_STATUS_SUCCESS) { + wlan_vdev_obj_unlock(vdev); + return peer_next; + } + + prev_vdev_node = vdev_node; + } + + wlan_vdev_obj_unlock(vdev); + + return NULL; +} + +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer_next = NULL; + qdf_list_node_t *psoc_node = NULL; + qdf_list_node_t *prev_psoc_node = NULL; + qdf_list_t *obj_list; + + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + prev_psoc_node = &peer->psoc_peer; + while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == + QDF_STATUS_SUCCESS) { + peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer, + psoc_peer); + + if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) == + QDF_STATUS_SUCCESS) { + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + return peer_next; + } + + prev_psoc_node = psoc_node; + } + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + + return NULL; +} + +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer; + qdf_list_node_t *psoc_node = NULL; + qdf_list_node_t *prev_psoc_node = NULL; + qdf_list_t *obj_list; + + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + if (qdf_list_peek_front(obj_list, &psoc_node) != QDF_STATUS_SUCCESS) { + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + return NULL; + } + + do { + peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer, + psoc_peer); + if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == + QDF_STATUS_SUCCESS) { + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + return peer; + } + + prev_psoc_node = psoc_node; + } while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == + QDF_STATUS_SUCCESS); + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + return NULL; +} + +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer; + qdf_list_t *obj_list; + + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + peer = wlan_psoc_peer_list_peek_head(obj_list); + + /** + * This API is invoked by caller, only when caller need to access the + * peer object, though object is not in active state, this API should be + * used carefully, where multiple object frees are not triggered + */ + if (peer) + wlan_objmgr_peer_get_ref(peer, dbg_id); + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + + return peer; +} + +struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( + struct wlan_peer_list *peer_list, uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id) +{ + qdf_list_t *obj_list; + struct wlan_objmgr_peer *peer_next; + + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + peer_next = wlan_peer_get_next_peer_of_psoc(obj_list, peer); + /** + * This API is invoked by caller, only when caller need to access the + * peer object, though object is not in active state, this API should be + * used carefully, where multiple free on object are not triggered + */ + if (peer_next) + wlan_objmgr_peer_get_ref(peer_next, dbg_id); + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + + return peer_next; +} diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c index 65f08638d462..c5845f0927bf 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c @@ -416,27 +416,18 @@ QDF_STATUS wlan_objmgr_iterate_obj_list( uint8_t i; struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; struct wlan_peer_list *peer_list; - qdf_list_t *obj_list; struct wlan_objmgr_pdev *pdev; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_peer *peer; struct wlan_objmgr_peer *peer_next; uint16_t max_vdev_cnt; - /* If caller requests for lock free opeation, do not acquire, - * handler will handle the synchronization - */ - if (!lock_free_op) - wlan_psoc_obj_lock(psoc); - switch (obj_type) { case WLAN_PDEV_OP: /* Iterate through PDEV list, invoke handler for each pdev */ for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { - pdev = objmgr->wlan_pdev_list[obj_id]; - if ((pdev != NULL) && - (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) == - QDF_STATUS_SUCCESS)) { + pdev = wlan_objmgr_get_pdev_by_id(psoc, obj_id, dbg_id); + if (pdev != NULL) { handler(psoc, (void *)pdev, arg); wlan_objmgr_pdev_release_ref(pdev, dbg_id); } @@ -446,10 +437,9 @@ QDF_STATUS wlan_objmgr_iterate_obj_list( /* Iterate through VDEV list, invoke handler for each vdev */ max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { - vdev = objmgr->wlan_vdev_list[obj_id]; - if ((vdev != NULL) && - (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == - QDF_STATUS_SUCCESS)) { + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + obj_id, dbg_id); + if (vdev != NULL) { handler(psoc, vdev, arg); wlan_objmgr_vdev_release_ref(vdev, dbg_id); } @@ -458,34 +448,24 @@ QDF_STATUS wlan_objmgr_iterate_obj_list( case WLAN_PEER_OP: /* Iterate through PEER list, invoke handler for each peer */ peer_list = &objmgr->peer_list; - /* psoc lock should be taken before list lock */ - if (!lock_free_op) - qdf_spin_lock_bh(&peer_list->peer_list_lock); /* Since peer list has sublist, iterate through sublists */ for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { - obj_list = &peer_list->peer_hash[i]; - peer = wlan_psoc_peer_list_peek_head(obj_list); + peer = wlan_psoc_peer_list_peek_active_head(peer_list, + i, dbg_id); while (peer) { + handler(psoc, (void *)peer, arg); /* Get next peer */ - peer_next = wlan_peer_get_next_peer_of_psoc( - obj_list, peer); - if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) - == QDF_STATUS_SUCCESS) { - handler(psoc, (void *)peer, arg); - wlan_objmgr_peer_release_ref(peer, - dbg_id); - } + peer_next = + wlan_peer_get_next_active_peer_of_psoc( + peer_list, i, peer, dbg_id); + wlan_objmgr_peer_release_ref(peer, dbg_id); peer = peer_next; } } - if (!lock_free_op) - qdf_spin_unlock_bh(&peer_list->peer_list_lock); break; default: break; } - if (!lock_free_op) - wlan_psoc_obj_unlock(psoc); return QDF_STATUS_SUCCESS; } @@ -502,7 +482,6 @@ QDF_STATUS wlan_objmgr_iterate_obj_list_all( uint8_t i; struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; struct wlan_peer_list *peer_list; - qdf_list_t *obj_list; struct wlan_objmgr_pdev *pdev; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_peer *peer; @@ -512,16 +491,14 @@ QDF_STATUS wlan_objmgr_iterate_obj_list_all( /* If caller requests for lock free opeation, do not acquire, * handler will handle the synchronization */ - if (!lock_free_op) - wlan_psoc_obj_lock(psoc); switch (obj_type) { case WLAN_PDEV_OP: /* Iterate through PDEV list, invoke handler for each pdev */ for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { - pdev = objmgr->wlan_pdev_list[obj_id]; + pdev = wlan_objmgr_get_pdev_by_id_no_state(psoc, + obj_id, dbg_id); if (pdev != NULL) { - wlan_objmgr_pdev_get_ref(pdev, dbg_id); handler(psoc, (void *)pdev, arg); wlan_objmgr_pdev_release_ref(pdev, dbg_id); } @@ -531,9 +508,9 @@ QDF_STATUS wlan_objmgr_iterate_obj_list_all( /* Iterate through VDEV list, invoke handler for each vdev */ max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { - vdev = objmgr->wlan_vdev_list[obj_id]; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc_no_state( + psoc, obj_id, dbg_id); if (vdev != NULL) { - wlan_objmgr_vdev_get_ref(vdev, dbg_id); handler(psoc, vdev, arg); wlan_objmgr_vdev_release_ref(vdev, dbg_id); } @@ -542,31 +519,25 @@ QDF_STATUS wlan_objmgr_iterate_obj_list_all( case WLAN_PEER_OP: /* Iterate through PEER list, invoke handler for each peer */ peer_list = &objmgr->peer_list; - /* psoc lock should be taken before list lock */ - if (!lock_free_op) - qdf_spin_lock_bh(&peer_list->peer_list_lock); /* Since peer list has sublist, iterate through sublists */ for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { - obj_list = &peer_list->peer_hash[i]; - peer = wlan_psoc_peer_list_peek_head(obj_list); + peer = wlan_psoc_peer_list_peek_head_ref(peer_list, i, + dbg_id); + while (peer) { - /* Get next peer */ - peer_next = wlan_peer_get_next_peer_of_psoc( - obj_list, peer); - wlan_objmgr_peer_get_ref(peer, dbg_id); handler(psoc, (void *)peer, arg); + /* Get next peer */ + peer_next = wlan_peer_get_next_peer_of_psoc_ref( + peer_list, i, + peer, dbg_id); wlan_objmgr_peer_release_ref(peer, dbg_id); peer = peer_next; } } - if (!lock_free_op) - qdf_spin_unlock_bh(&peer_list->peer_list_lock); break; default: break; } - if (!lock_free_op) - wlan_psoc_obj_unlock(psoc); return QDF_STATUS_SUCCESS; } diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c index 359ac4849c0f..9efdc82f399e 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c @@ -898,3 +898,69 @@ bool wlan_vdev_is_connected(struct wlan_objmgr_vdev *vdev) return true; } qdf_export_symbol(wlan_vdev_is_connected); + +struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_vdev *vdev; + qdf_list_node_t *node = NULL; + qdf_list_node_t *prev_node = NULL; + + wlan_pdev_obj_lock(pdev); + + if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return NULL; + } + + do { + vdev = qdf_container_of(node, struct wlan_objmgr_vdev, + vdev_node); + if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == + QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return vdev; + } + + prev_node = node; + } while (qdf_list_peek_next(vdev_list, prev_node, &node) == + QDF_STATUS_SUCCESS); + + wlan_pdev_obj_unlock(pdev); + + return NULL; +} + +struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_vdev *vdev_next; + qdf_list_node_t *node = &vdev->vdev_node; + qdf_list_node_t *prev_node = NULL; + + if (node == NULL) + return NULL; + + wlan_pdev_obj_lock(pdev); + prev_node = node; + while (qdf_list_peek_next(vdev_list, prev_node, &node) == + QDF_STATUS_SUCCESS) { + vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev, + vdev_node); + if (wlan_objmgr_vdev_try_get_ref(vdev_next, dbg_id) == + QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return vdev_next; + } + + prev_node = node; + } + wlan_pdev_obj_unlock(pdev); + + return NULL; +} +