From a889ffa967b063b179093b752c355ae31c751847 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Wed, 3 Jul 2019 19:29:52 +0530 Subject: [PATCH] qcacld-3.0: cdp: Convergence of cdp_flowctl_ops Currently the cdp apis are given pdev/vdev/peer handle as its arguments, which is directly accessed in those APIs. This can cause a race-condition in access of the respective handles if it has been deleted in parallel. Hence as a part of cdp convergence, pass only the pdev/vdev id or peer mac address, which will be used to get the respective handles, and hence avoiding the unwanted access of the handles if it has been deleted. Converged flowctl_ops - flow_pool_map_handler - flow_pool_unmap_handler - dump_flow_pool_info - tx_desc_thresh_reached CRs-Fixed: 2539738 Change-Id: I9b11e66d8c2644f16e0f2464c323798a4cba007a --- components/ipa/core/src/wlan_ipa_core.c | 8 +------- core/dp/ol/inc/ol_defines.h | 4 +++- core/dp/ol/inc/ol_txrx_ctrl_api.h | 7 +++---- core/dp/txrx/ol_rx_fwd.c | 3 +-- core/dp/txrx/ol_tx_hl.c | 6 ++++-- core/dp/txrx/ol_txrx.c | 11 +++++++---- core/dp/txrx/ol_txrx.h | 20 ++++++++++++++------ core/dp/txrx/ol_txrx_flow_control.c | 22 +++++++++++++++------- core/hdd/src/wlan_hdd_main.c | 4 ++-- 9 files changed, 50 insertions(+), 35 deletions(-) diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index a85c1eb0a3fc..5a93342256d2 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -425,15 +425,9 @@ static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward( { int ret = WLAN_IPA_FORWARD_PKT_NONE; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); if ((desc & FW_RX_DESC_FORWARD_M)) { - void *vdev = cdp_get_vdev_from_vdev_id(soc, pdev, - iface_ctx->session_id); - if (!vdev) - goto drop_pkt; - - if (cdp_tx_desc_thresh_reached(soc, vdev)) { + if (cdp_tx_desc_thresh_reached(soc, iface_ctx->session_id)) { /* Drop the packet*/ ipa_ctx->stats.num_tx_fwd_err++; goto drop_pkt; diff --git a/core/dp/ol/inc/ol_defines.h b/core/dp/ol/inc/ol_defines.h index 3e73310b62a8..d08838b3888a 100644 --- a/core/dp/ol/inc/ol_defines.h +++ b/core/dp/ol/inc/ol_defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016, 2018-2019 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 @@ -22,6 +22,8 @@ #ifndef _DEV_OL_DEFINES_H #define _DEV_OL_DEFINES_H +#define OL_TXRX_PDEV_ID 0 + /** * ol_txrx_pdev_handle - opaque handle for txrx physical device * object diff --git a/core/dp/ol/inc/ol_txrx_ctrl_api.h b/core/dp/ol/inc/ol_txrx_ctrl_api.h index 66cb6ffaa464..0d6ef8452f8e 100644 --- a/core/dp/ol/inc/ol_txrx_ctrl_api.h +++ b/core/dp/ol/inc/ol_txrx_ctrl_api.h @@ -510,7 +510,7 @@ static inline void ol_tx_flow_pool_resize_handler(uint8_t flow_pool_id, void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev); void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev); -void ol_tx_dump_flow_pool_info(void *pdev); +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl); void ol_tx_dump_flow_pool_info_compact(void *pdev); void ol_tx_clear_flow_pool_stats(void); void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type, @@ -557,11 +557,10 @@ static inline void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) } #if defined(CONFIG_HL_SUPPORT) && defined(QCA_HL_NETDEV_FLOW_CONTROL) -void ol_tx_dump_flow_pool_info(void *pdev); +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl); void ol_tx_dump_flow_pool_info_compact(void *pdev); #else -static inline -void ol_tx_dump_flow_pool_info(void *ctx) +static inline void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl) { } diff --git a/core/dp/txrx/ol_rx_fwd.c b/core/dp/txrx/ol_rx_fwd.c index d692a21999c8..777a6743d512 100644 --- a/core/dp/txrx/ol_rx_fwd.c +++ b/core/dp/txrx/ol_rx_fwd.c @@ -190,8 +190,7 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, QDF_NBUF_TX_EXT_TID_INVALID); } - if (!ol_txrx_fwd_desc_thresh_check( - (struct cdp_vdev *)vdev)) { + if (!ol_txrx_fwd_desc_thresh_check(vdev)) { /* Drop the packet*/ htt_rx_msdu_desc_free(pdev->htt_pdev, msdu); TXRX_STATS_MSDU_LIST_INCR( diff --git a/core/dp/txrx/ol_tx_hl.c b/core/dp/txrx/ol_tx_hl.c index b568f79b3a65..a9bb29a765f2 100644 --- a/core/dp/txrx/ol_tx_hl.c +++ b/core/dp/txrx/ol_tx_hl.c @@ -2064,11 +2064,13 @@ void ol_tx_dump_flow_pool_info_compact(void *ctx) qdf_mem_free(comb_log_str); } -void ol_tx_dump_flow_pool_info(void *ctx) +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; struct ol_txrx_vdev_t *vdev; + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return; diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 12a0e960d4f8..b2b30f4c00c5 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -1533,7 +1533,7 @@ static void ol_txrx_pdev_pre_detach(struct cdp_pdev *ppdev, int force) } /* to get flow pool status before freeing descs */ - ol_tx_dump_flow_pool_info((void *)pdev); + ol_tx_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC)); ol_tx_free_descs_inuse(pdev); ol_tx_deregister_flow_control(pdev); @@ -4480,7 +4480,7 @@ ol_txrx_display_stats(void *soc, uint16_t value, if (verb_level == QDF_STATS_VERBOSITY_LEVEL_LOW) ol_tx_dump_flow_pool_info_compact((void *)pdev); else - ol_tx_dump_flow_pool_info((void *)pdev); + ol_tx_dump_flow_pool_info(soc); break; case CDP_TXRX_DESC_STATS: qdf_nbuf_tx_desc_count_display(); @@ -4984,15 +4984,18 @@ exit: /** * ol_txrx_register_pause_cb() - register pause callback + * @soc_hdl: Datapath soc handle * @pause_cb: pause callback * * Return: QDF status */ -static QDF_STATUS ol_txrx_register_pause_cb(struct cdp_soc_t *soc, +static QDF_STATUS ol_txrx_register_pause_cb(struct cdp_soc_t *soc_hdl, tx_pause_callback pause_cb) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev || !pause_cb) { ol_txrx_err("pdev or pause_cb is NULL"); return QDF_STATUS_E_INVAL; diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h index ef005974209c..aa45d4a6a34f 100644 --- a/core/dp/txrx/ol_txrx.h +++ b/core/dp/txrx/ol_txrx.h @@ -27,8 +27,6 @@ #include #include -#define OL_TXRX_PDEV_ID 0 - /* * Pool of tx descriptors reserved for * high-priority traffic, such as ARP/EAPOL etc @@ -449,16 +447,26 @@ uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev); * Return: true ; forward the packet, i.e., below threshold * false; not enough descriptors, drop the packet */ -bool ol_txrx_fwd_desc_thresh_check(struct cdp_vdev *vdev); +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *txrx_vdev); /** * ol_tx_desc_thresh_reached() - is tx desc threshold reached - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * * Return: true if tx desc available reached threshold or false otherwise */ -static inline bool ol_tx_desc_thresh_reached(struct cdp_vdev *vdev) +static inline bool ol_tx_desc_thresh_reached(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id) { + struct ol_txrx_vdev_t *vdev; + + vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + if (!vdev) { + dp_err("vdev is NULL"); + return false; + } + return !(ol_txrx_fwd_desc_thresh_check(vdev)); } @@ -476,7 +484,7 @@ uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev) } static inline -bool ol_txrx_fwd_desc_thresh_check(struct cdp_vdev *vdev) +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *txrx_vdev) { return true; } diff --git a/core/dp/txrx/ol_txrx_flow_control.c b/core/dp/txrx/ol_txrx_flow_control.c index ceee48bc1b57..ce88b039669c 100644 --- a/core/dp/txrx/ol_txrx_flow_control.c +++ b/core/dp/txrx/ol_txrx_flow_control.c @@ -83,9 +83,8 @@ ol_tx_deregister_global_mgmt_pool(struct ol_txrx_pdev_t *pdev) } #endif -bool ol_txrx_fwd_desc_thresh_check(struct cdp_vdev *vdev) +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *txrx_vdev) { - struct ol_txrx_vdev_t *txrx_vdev = (struct ol_txrx_vdev_t *)vdev; struct ol_tx_flow_pool_t *pool; bool enough_desc_flag; @@ -181,10 +180,13 @@ void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) { int i = 0; struct ol_tx_flow_pool_t *pool = NULL; + struct cdp_soc_t *soc; if (!ol_tx_get_is_mgmt_over_wmi_enabled()) ol_tx_deregister_global_mgmt_pool(pdev); + soc = cds_get_context(QDF_MODULE_ID_SOC); + qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); while (!TAILQ_EMPTY(&pdev->tx_desc.flow_pool_list)) { pool = TAILQ_FIRST(&pdev->tx_desc.flow_pool_list); @@ -194,7 +196,7 @@ void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) ol_txrx_info("flow pool list is not empty %d!!!\n", i++); if (i == 1) - ol_tx_dump_flow_pool_info((void *)pdev); + ol_tx_dump_flow_pool_info(soc); ol_tx_dec_pool_ref(pool, true); qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); @@ -410,18 +412,24 @@ void ol_tx_dump_flow_pool_info_compact(void *ctx) /** * ol_tx_dump_flow_pool_info() - dump global_pool and flow_pool info - * @ctx: cdp_soc context, required only in lithium_dp flow control. - * Remove void * while cleaning up cds_get_context. + * @soc_hdl: cdp_soc context, required only in lithium_dp flow control. * * Return: none */ -void ol_tx_dump_flow_pool_info(void *ctx) +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *pool = NULL, *pool_prev = NULL; struct ol_tx_flow_pool_t tmp_pool; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + QDF_ASSERT(0); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("ERROR: pdev NULL"); QDF_ASSERT(0); /* traceback */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index bc2d7943ba3d..f65475817c68 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -11726,7 +11726,7 @@ static void hdd_v2_flow_pool_map(int vdev_id) QDF_STATUS status; status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), + OL_TXRX_PDEV_ID, vdev_id); /* * For Adrastea flow control v2 is based on FW MAP events, @@ -11749,7 +11749,7 @@ static void hdd_v2_flow_pool_map(int vdev_id) static void hdd_v2_flow_pool_unmap(int vdev_id) { cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), vdev_id); + OL_TXRX_PDEV_ID, vdev_id); } /**