From 935cd2dae8159edaa15e735b234c73858d13b717 Mon Sep 17 00:00:00 2001 From: Srinivas Pitla Date: Tue, 4 Apr 2017 11:09:25 +0530 Subject: [PATCH] qcacmn: Add new iterate PSOC API for all objects The current iterate object API does not invoke operation on logically deleted objects. The new API will invoke operation on all objects. Change-Id: I7821dccf3ccb0c5d209e3bf27489fcb4bf99aef5 CRs-Fixed: 2028529 --- .../obj_mgr/inc/wlan_objmgr_psoc_obj.h | 25 ++++++ .../obj_mgr/src/wlan_objmgr_psoc_obj.c | 85 ++++++++++++++++++- 2 files changed, 107 insertions(+), 3 deletions(-) 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 e4bee9d5265b..d676ceec2e1c 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 @@ -378,6 +378,7 @@ typedef void (*wlan_objmgr_op_handler)(struct wlan_objmgr_psoc *psoc, /** * wlan_objmgr_iterate_obj_list() - iterate through all psoc objects + * (CREATED state) * @psoc: PSOC object * @obj_type: PDEV_OP/VDEV_OP/PEER_OP * @handler: the handler will be called for each object of requested type @@ -400,6 +401,30 @@ QDF_STATUS wlan_objmgr_iterate_obj_list( void *arg, uint8_t lock_free_op, wlan_objmgr_ref_dbgid dbg_id); +/** + * wlan_objmgr_iterate_obj_list_all() - iterate through all psoc objects + * @psoc: PSOC object + * @obj_type: PDEV_OP/VDEV_OP/PEER_OP + * @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. + * @dbg_id: id of the caller + * + * API to be used for performing the operations on all PDEV/VDEV/PEER objects + * of psoc + * + * Return: SUCCESS/FAILURE + */ +QDF_STATUS wlan_objmgr_iterate_obj_list_all( + struct wlan_objmgr_psoc *psoc, + enum wlan_objmgr_obj_type obj_type, + wlan_objmgr_op_handler handler, + void *arg, uint8_t lock_free_op, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_objmgr_free_all_objects_per_psoc() - free all psoc objects * @psoc: PSOC object 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 16e73421194a..7a71ebd5c825 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 @@ -464,6 +464,85 @@ QDF_STATUS wlan_objmgr_iterate_obj_list( } EXPORT_SYMBOL(wlan_objmgr_iterate_obj_list); +QDF_STATUS wlan_objmgr_iterate_obj_list_all( + struct wlan_objmgr_psoc *psoc, + enum wlan_objmgr_obj_type obj_type, + wlan_objmgr_op_handler handler, + void *arg, uint8_t lock_free_op, + wlan_objmgr_ref_dbgid dbg_id) +{ + uint16_t obj_id; + 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; + + /* 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_get_ref(pdev, dbg_id); + handler(psoc, (void *)pdev, arg); + wlan_objmgr_pdev_release_ref(pdev, dbg_id); + } + } + break; + case WLAN_VDEV_OP: + /* Iterate through VDEV list, invoke handler for each vdev */ + for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) { + vdev = objmgr->wlan_vdev_list[obj_id]; + if (vdev != NULL) { + wlan_objmgr_vdev_get_ref(vdev, dbg_id); + handler(psoc, vdev, arg); + wlan_objmgr_vdev_release_ref(vdev, dbg_id); + } + } + break; + 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); + 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); + 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; +} +EXPORT_SYMBOL(wlan_objmgr_iterate_obj_list_all); + static void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc, void *obj, void *args) { @@ -1617,15 +1696,15 @@ QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc( struct wlan_objmgr_psoc *psoc) { qdf_print(" Ref counts of PEER\n"); - wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP, + wlan_objmgr_iterate_obj_list_all(psoc, WLAN_PEER_OP, wlan_objmgr_psoc_peer_ref_print, NULL, 1, WLAN_OBJMGR_ID); qdf_print(" Ref counts of VDEV\n"); - wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, + wlan_objmgr_iterate_obj_list_all(psoc, WLAN_VDEV_OP, wlan_objmgr_psoc_vdev_ref_print, NULL, 1, WLAN_OBJMGR_ID); qdf_print(" Ref counts of PDEV\n"); - wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, + wlan_objmgr_iterate_obj_list_all(psoc, WLAN_PDEV_OP, wlan_objmgr_psoc_pdev_ref_print, NULL, 1, WLAN_OBJMGR_ID);