From 2d39710f9b3b44c36c3fbf1f6eb28d110c077aef Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Fri, 4 May 2018 17:05:20 -0700 Subject: [PATCH] qcacmn: Protect wifi_pos global psoc object Protect wifi_pos global psoc object with spinlock. Change-Id: I5a250061b482fd2699bebb34c7eac3bd649831f7 CRs-Fixed: 2235825 --- os_if/linux/wifi_pos/src/os_if_wifi_pos.c | 8 +-- target_if/wifi_pos/src/target_if_wifi_pos.c | 10 ++-- .../obj_mgr/inc/wlan_objmgr_cmn.h | 14 +++-- umac/wifi_pos/src/wifi_pos_api.c | 7 ++- umac/wifi_pos/src/wifi_pos_main.c | 12 ++--- umac/wifi_pos/src/wifi_pos_utils.c | 53 ++++++++++++++++--- umac/wifi_pos/src/wifi_pos_utils_i.h | 16 ++++++ 7 files changed, 92 insertions(+), 28 deletions(-) diff --git a/os_if/linux/wifi_pos/src/os_if_wifi_pos.c b/os_if/linux/wifi_pos/src/os_if_wifi_pos.c index 592a848084ce..17ea6744f1c0 100644 --- a/os_if/linux/wifi_pos/src/os_if_wifi_pos.c +++ b/os_if/linux/wifi_pos/src/os_if_wifi_pos.c @@ -170,7 +170,7 @@ static void os_if_wifi_pos_callback(const void *data, int data_len, return; } - wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_OSIF_ID); err = wifi_pos_parse_req(data, data_len, pid, &req); if (err) { os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc), @@ -185,7 +185,7 @@ static void os_if_wifi_pos_callback(const void *data, int data_len, status); release_psoc_ref: - wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_OSIF_ID); } #else static int os_if_wifi_pos_callback(struct sk_buff *skb) @@ -201,7 +201,7 @@ static int os_if_wifi_pos_callback(struct sk_buff *skb) return -EINVAL; } - wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_OSIF_ID); err = wifi_pos_parse_req(skb, &req); if (err) { os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc), @@ -216,7 +216,7 @@ static int os_if_wifi_pos_callback(struct sk_buff *skb) status); release_psoc_ref: - wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_OSIF_ID); return qdf_status_to_os_return(status); } diff --git a/target_if/wifi_pos/src/target_if_wifi_pos.c b/target_if/wifi_pos/src/target_if_wifi_pos.c index 90270c02079f..f9592196e578 100644 --- a/target_if/wifi_pos/src/target_if_wifi_pos.c +++ b/target_if/wifi_pos/src/target_if_wifi_pos.c @@ -164,18 +164,18 @@ static int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn, return QDF_STATUS_NOT_INITIALIZED; } - wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID); priv_obj = wifi_pos_get_psoc_priv_obj(psoc); if (!priv_obj) { target_if_err("priv_obj is null"); - wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID); return QDF_STATUS_NOT_INITIALIZED; } wifi_pos_rx_ops = target_if_wifi_pos_get_rxops(psoc); if (!wifi_pos_rx_ops || !wifi_pos_rx_ops->oem_rsp_event_rx) { - wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID); target_if_err("lmac callbacks not registered"); return QDF_STATUS_NOT_INITIALIZED; } @@ -193,7 +193,7 @@ static int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn, &oem_rsp, &cookie); if (QDF_IS_STATUS_ERROR(status)) { target_if_err("get indirect data failed status: %d", status); - wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID); return QDF_STATUS_E_INVAL; } @@ -207,7 +207,7 @@ static int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn, ret = QDF_STATUS_E_FAILURE; } - wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID); + wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID); return ret; } diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index f5c638dd1ee4..9a5edcc966be 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -191,7 +191,7 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_PMO_ID: power manager offload (PMO) ID * @WLAN_LEGACY_SME_ID: Legacy SME operations * @WLAN_SCAN_ID: scan operations - * @WLAN_WIFI_POS_ID: wifi positioning + * @WLAN_WIFI_POS_CORE_ID: wifi positioning (CORE) * @WLAN_DFS_ID: DFS operations * @WLAN_P2P_ID: P2P operations * @WLAN_TDLS_SB_ID: TDLS Southbound operations @@ -217,6 +217,8 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_IPA_ID: IPA operations * @WLAN_CP_STATS_ID: Control Plane Statistics Module * @WLAN_GREEN_AP_ID: Green AP operations + * @WLAN_WIFI_POS_OSIF_ID: wifi positioning (OSID) + * @WLAN_WIFI_POS_TGT_IF_ID: wifi positioning (Target IF) * @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array */ /* New value added to the enum must also be reflected in function @@ -236,7 +238,7 @@ typedef enum { WLAN_PMO_ID = 10, WLAN_LEGACY_SME_ID = 11, WLAN_SCAN_ID = 12, - WLAN_WIFI_POS_ID = 13, + WLAN_WIFI_POS_CORE_ID = 13, WLAN_DFS_ID = 14, WLAN_P2P_ID = 15, WLAN_TDLS_SB_ID = 16, @@ -263,6 +265,8 @@ typedef enum { WLAN_IPA_ID = 37, WLAN_CP_STATS_ID = 38, WLAN_GREEN_AP_ID = 39, + WLAN_WIFI_POS_OSIF_ID = 40, + WLAN_WIFI_POS_TGT_IF_ID = 41, WLAN_REF_ID_MAX, } wlan_objmgr_ref_dbgid; @@ -289,7 +293,7 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "WLAN_PMO_ID", "WLAN_LEGACY_SME_ID", "WLAN_SCAN_ID", - "WLAN_WIFI_POS_ID", + "WLAN_WIFI_POS_CORE_ID", "WLAN_DFS_ID", "WLAN_P2P_ID", "WLAN_TDLS_SB_ID", @@ -316,7 +320,9 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "WLAN_IPA_ID", "WLAN_CP_STATS_ID", "WLAN_GREEN_AP_ID", - "WLAN_REF_ID_MAX" }; + "WLAN_WIFI_POS_OSIF_ID", + "WLAN_WIFI_POS_TGT_IF_ID", + "WLAN_REF_ID_MAX"}; return (char *)strings[id]; } diff --git a/umac/wifi_pos/src/wifi_pos_api.c b/umac/wifi_pos/src/wifi_pos_api.c index f3e5bcef2a4b..0ec581c1edb5 100644 --- a/umac/wifi_pos/src/wifi_pos_api.c +++ b/umac/wifi_pos/src/wifi_pos_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,6 +33,8 @@ QDF_STATUS wifi_pos_init(void) { QDF_STATUS status; + wifi_pos_lock_init(); + /* register psoc create handler functions. */ status = wlan_objmgr_register_psoc_create_handler( WLAN_UMAC_COMP_WIFI_POS, @@ -81,6 +83,9 @@ QDF_STATUS wifi_pos_deinit(void) wifi_pos_err("unregister_psoc_destroy_handler failed, status: %d", status); } + + wifi_pos_lock_deinit(); + return QDF_STATUS_SUCCESS; } diff --git a/umac/wifi_pos/src/wifi_pos_main.c b/umac/wifi_pos/src/wifi_pos_main.c index 963a1a4b98df..addb6cb8083f 100644 --- a/umac/wifi_pos/src/wifi_pos_main.c +++ b/umac/wifi_pos/src/wifi_pos_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -200,7 +200,7 @@ static QDF_STATUS wifi_pos_process_ch_info_req(struct wlan_objmgr_psoc *psoc, req->pid, req->buf_len); /* get first pdev since we need that only for freq and dfs state */ - pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_WIFI_POS_ID); + pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_WIFI_POS_CORE_ID); if (!pdev) { wifi_pos_err("pdev get API failed"); return QDF_STATUS_E_INVAL; @@ -210,7 +210,7 @@ static QDF_STATUS wifi_pos_process_ch_info_req(struct wlan_objmgr_psoc *psoc, buf = qdf_mem_malloc(len); if (!buf) { wifi_pos_alert("malloc failed"); - wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_ID); + wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_CORE_ID); return QDF_STATUS_E_NOMEM; } @@ -235,7 +235,7 @@ static QDF_STATUS wifi_pos_process_ch_info_req(struct wlan_objmgr_psoc *psoc, ANI_MSG_CHANNEL_INFO_RSP, len, buf); qdf_mem_free(buf); - wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_ID); + wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_CORE_ID); return QDF_STATUS_SUCCESS; } @@ -284,7 +284,7 @@ static QDF_STATUS wifi_pos_process_app_reg_req(struct wlan_objmgr_psoc *psoc, vdev_idx = 0; wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, wifi_pos_vdev_iterator, - vdevs_info, true, WLAN_WIFI_POS_ID); + vdevs_info, true, WLAN_WIFI_POS_CORE_ID); rsp_len = (sizeof(struct app_reg_rsp_vdev_info) * vdev_idx) + sizeof(uint8_t); app_reg_rsp = qdf_mem_malloc(rsp_len); @@ -531,7 +531,7 @@ static void wifi_pos_get_ch_info(struct wlan_objmgr_psoc *psoc, wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, wifi_pos_pdev_iterator, - ch_lst, true, WLAN_WIFI_POS_ID); + ch_lst, true, WLAN_WIFI_POS_CORE_ID); for (i = 0; i < NUM_CHANNELS && num_ch < OEM_CAP_MAX_NUM_CHANNELS; i++) { diff --git a/umac/wifi_pos/src/wifi_pos_utils.c b/umac/wifi_pos/src/wifi_pos_utils.c index 2f19b3db8292..1a7ac0ff583d 100644 --- a/umac/wifi_pos/src/wifi_pos_utils.c +++ b/umac/wifi_pos/src/wifi_pos_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,6 +26,9 @@ #include "wlan_objmgr_psoc_obj.h" #include "wifi_pos_utils_i.h" +/* lock to protect use of psoc global pointer variable */ +static qdf_spinlock_t psoc_ptr_lock; + /* * WIFI pos command are not associated with any pdev/psoc/vdev, so the callback * registered with GENL socket does not receive any pdev/pdev/vdev object. @@ -35,25 +38,59 @@ */ static struct wlan_objmgr_psoc *wifi_pos_psoc_obj; +void wifi_pos_lock_init(void) +{ + qdf_spinlock_create(&psoc_ptr_lock); +} + +void wifi_pos_lock_deinit(void) +{ + qdf_spinlock_destroy(&psoc_ptr_lock); +} + struct wlan_objmgr_psoc *wifi_pos_get_psoc(void) { - return wifi_pos_psoc_obj; + struct wlan_objmgr_psoc *tmp; + + qdf_spin_lock_bh(&psoc_ptr_lock); + tmp = wifi_pos_psoc_obj; + qdf_spin_unlock_bh(&psoc_ptr_lock); + + return tmp; } void wifi_pos_set_psoc(struct wlan_objmgr_psoc *psoc) { - if (wifi_pos_psoc_obj) - wifi_pos_warn("global psoc obj already set"); - else + struct wlan_objmgr_psoc *tmp; + + qdf_spin_lock_bh(&psoc_ptr_lock); + tmp = wifi_pos_psoc_obj; + if (!wifi_pos_psoc_obj) { wifi_pos_psoc_obj = psoc; + wlan_objmgr_psoc_get_ref(wifi_pos_psoc_obj, + WLAN_WIFI_POS_CORE_ID); + } + qdf_spin_unlock_bh(&psoc_ptr_lock); + + if (tmp) + wifi_pos_warn("global psoc obj already set"); } void wifi_pos_clear_psoc(void) { - if (!wifi_pos_psoc_obj) - wifi_pos_warn("global psoc obj already cleared"); - else + struct wlan_objmgr_psoc *tmp; + + qdf_spin_lock_bh(&psoc_ptr_lock); + tmp = wifi_pos_psoc_obj; + if (wifi_pos_psoc_obj) { + wlan_objmgr_psoc_release_ref(wifi_pos_psoc_obj, + WLAN_WIFI_POS_CORE_ID); wifi_pos_psoc_obj = NULL; + } + qdf_spin_unlock_bh(&psoc_ptr_lock); + + if (!tmp) + wifi_pos_warn("global psoc obj already cleared"); } /** diff --git a/umac/wifi_pos/src/wifi_pos_utils_i.h b/umac/wifi_pos/src/wifi_pos_utils_i.h index 467573eb69a7..c74d6e3ff730 100644 --- a/umac/wifi_pos/src/wifi_pos_utils_i.h +++ b/umac/wifi_pos/src/wifi_pos_utils_i.h @@ -309,6 +309,22 @@ struct wifi_pos_psoc_priv_obj { struct wifi_pos_psoc_priv_obj *wifi_pos_get_psoc_priv_obj( struct wlan_objmgr_psoc *psoc); +/** + * wifi_pos_lock_init: API to init lock used protect use of psoc global pointer + * variable + * + * Return: none. + */ +void wifi_pos_lock_init(void); + +/** + * wifi_pos_lock_deinit: API to deinit lock used protect use of psoc global + * pointer variable + * + * Return: none. + */ +void wifi_pos_lock_deinit(void); + /** * wifi_pos_set_psoc: API to set global PSOC object * @psoc: pointer to psoc object