From d8334769f4fe535474b87f3c411bf13eee406f9a Mon Sep 17 00:00:00 2001 From: Ruben Columbus Date: Mon, 22 May 2023 16:42:02 -0700 Subject: [PATCH] qcacmn: qref debug memory tracker add multiple history array to keep track of mem allocation and deallocation for qref table. Change-Id: I9fa97fbe5a5c36509cbb5a458851a152200318a5 CRs-Fixed: 3475981 --- dp/wifi3.0/dp_main.c | 42 +++++++++++++++++++++++ dp/wifi3.0/dp_peer.c | 27 ++++++++++++++- dp/wifi3.0/dp_peer.h | 78 ++++++++++++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_rx_tid.c | 33 ++++++++++++++++++ dp/wifi3.0/dp_types.h | 27 +++++++++++++++ wlan_cfg/cfg_dp.h | 13 +++++++ wlan_cfg/wlan_cfg.c | 7 ++++ wlan_cfg/wlan_cfg.h | 10 ++++++ 8 files changed, 236 insertions(+), 1 deletion(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index c3728a389e..3660a6ad07 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -170,6 +170,7 @@ QDF_COMPILE_TIME_ASSERT(wlan_cfg_num_int_ctxs, WLAN_CFG_INT_NUM_CONTEXTS_MAX >= WLAN_CFG_INT_NUM_CONTEXTS); +static void dp_soc_unset_qref_debug_list(struct dp_soc *soc); static QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl); static QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl); @@ -2993,6 +2994,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc) dp_runtime_deinit(); + dp_soc_unset_qref_debug_list(soc); dp_sysfs_deinitialize_stats(soc); dp_soc_swlm_detach(soc); dp_soc_tx_desc_sw_pools_free(soc); @@ -12062,6 +12064,7 @@ static void dp_soc_txrx_ops_attach(struct dp_soc *soc) #if defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \ defined(QCA_WIFI_QCA5018) || defined(QCA_WIFI_QCA9574) || \ defined(QCA_WIFI_QCA5332) + /** * dp_soc_attach_wifi3() - Attach txrx SOC * @ctrl_psoc: Opaque SOC handle from control plane @@ -12091,6 +12094,44 @@ static inline void dp_soc_set_def_pdev(struct dp_soc *soc) } } +static void dp_soc_unset_qref_debug_list(struct dp_soc *soc) +{ + uint32_t max_list_size = soc->wlan_cfg_ctx->qref_control_size; + + if (max_list_size == 0) + return; + + qdf_mem_free(soc->list_shared_qaddr_del); + qdf_mem_free(soc->reo_write_list); + qdf_mem_free(soc->list_qdesc_addr_free); + qdf_mem_free(soc->list_qdesc_addr_alloc); +} + +static void dp_soc_set_qref_debug_list(struct dp_soc *soc) +{ + uint32_t max_list_size = soc->wlan_cfg_ctx->qref_control_size; + + if (max_list_size == 0) + return; + + soc->list_shared_qaddr_del = + (struct test_qaddr_del *) + qdf_mem_malloc(sizeof(struct test_qaddr_del) * + max_list_size); + soc->reo_write_list = + (struct test_qaddr_del *) + qdf_mem_malloc(sizeof(struct test_qaddr_del) * + max_list_size); + soc->list_qdesc_addr_free = + (struct test_mem_free *) + qdf_mem_malloc(sizeof(struct test_mem_free) * + max_list_size); + soc->list_qdesc_addr_alloc = + (struct test_mem_free *) + qdf_mem_malloc(sizeof(struct test_mem_free) * + max_list_size); +} + static uint32_t dp_get_link_desc_id_start(uint16_t arch_id) { @@ -12250,6 +12291,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, dp_soc_swlm_attach(soc); dp_soc_set_interrupt_mode(soc); dp_soc_set_def_pdev(soc); + dp_soc_set_qref_debug_list(soc); dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u", qdf_dma_mem_stats_read(), diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 1bf2f197c2..03a1f2f022 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -2488,6 +2488,9 @@ void dp_peer_rx_reo_shared_qaddr_delete(struct dp_soc *soc, { uint8_t tid; uint16_t peer_id; + uint32_t max_list_size; + + max_list_size = soc->wlan_cfg_ctx->qref_control_size; peer_id = peer->peer_id; @@ -2495,10 +2498,30 @@ void dp_peer_rx_reo_shared_qaddr_delete(struct dp_soc *soc, return; if (IS_MLO_DP_LINK_PEER(peer)) return; + + if (max_list_size) { + unsigned long curr_ts = qdf_get_system_timestamp(); + struct dp_peer *primary_peer = peer; + uint16_t chip_id = 0xFFFF; + uint32_t qref_index; + + qref_index = soc->shared_qaddr_del_idx; + + soc->list_shared_qaddr_del[qref_index].peer_id = + primary_peer->peer_id; + soc->list_shared_qaddr_del[qref_index].ts_qaddr_del = curr_ts; + soc->list_shared_qaddr_del[qref_index].chip_id = chip_id; + soc->shared_qaddr_del_idx++; + + if (soc->shared_qaddr_del_idx == max_list_size) + soc->shared_qaddr_del_idx = 0; + } + if (hal_reo_shared_qaddr_is_enable(soc->hal_soc)) { - for (tid = 0; tid < DP_MAX_TIDS; tid++) + for (tid = 0; tid < DP_MAX_TIDS; tid++) { hal_reo_shared_qaddr_write(soc->hal_soc, peer_id, tid, 0); + } } } #endif @@ -2838,10 +2861,12 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, if (hal_reo_shared_qaddr_is_enable(soc->hal_soc) && peer->rx_tid[0].hw_qdesc_vaddr_unaligned && !IS_MLO_DP_LINK_PEER(peer)) { + add_entry_write_list(soc, peer, 0); hal_reo_shared_qaddr_write(soc->hal_soc, peer_id, 0, peer->rx_tid[0].hw_qdesc_paddr); + add_entry_write_list(soc, peer, DP_NON_QOS_TID); hal_reo_shared_qaddr_write(soc->hal_soc, peer_id, DP_NON_QOS_TID, diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 07b01d9be4..51fd500aad 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -48,6 +48,84 @@ __QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO_HIGH, QDF_MODULE_ID_DP_PEER, ## params) #define dp_peer_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_DP_PEER, params) +void check_free_list_for_invalid_flush(struct dp_soc *soc); + +static inline +void add_entry_alloc_list(struct dp_soc *soc, struct dp_rx_tid *rx_tid, + struct dp_peer *peer, void *hw_qdesc_vaddr) +{ + uint32_t max_list_size; + unsigned long curr_ts = qdf_get_system_timestamp(); + uint32_t qref_index = soc->free_addr_list_idx; + + max_list_size = soc->wlan_cfg_ctx->qref_control_size; + + if (max_list_size == 0) + return; + + soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_paddr = + rx_tid->hw_qdesc_paddr; + soc->list_qdesc_addr_alloc[qref_index].ts_qdesc_mem_hdl = curr_ts; + soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_vaddr_align = + hw_qdesc_vaddr; + soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_vaddr_unalign = + rx_tid->hw_qdesc_vaddr_unaligned; + soc->list_qdesc_addr_alloc[qref_index].peer_id = peer->peer_id; + soc->list_qdesc_addr_alloc[qref_index].tid = rx_tid->tid; + soc->alloc_addr_list_idx++; + + if (soc->alloc_addr_list_idx == max_list_size) + soc->alloc_addr_list_idx = 0; +} + +static inline +void add_entry_free_list(struct dp_soc *soc, struct dp_rx_tid *rx_tid) +{ + uint32_t max_list_size; + unsigned long curr_ts = qdf_get_system_timestamp(); + uint32_t qref_index = soc->free_addr_list_idx; + + max_list_size = soc->wlan_cfg_ctx->qref_control_size; + + if (max_list_size == 0) + return; + + soc->list_qdesc_addr_free[qref_index].ts_qdesc_mem_hdl = curr_ts; + soc->list_qdesc_addr_free[qref_index].hw_qdesc_paddr = + rx_tid->hw_qdesc_paddr; + soc->list_qdesc_addr_free[qref_index].hw_qdesc_vaddr_align = + rx_tid->hw_qdesc_vaddr_aligned; + soc->list_qdesc_addr_free[qref_index].hw_qdesc_vaddr_unalign = + rx_tid->hw_qdesc_vaddr_unaligned; + soc->free_addr_list_idx++; + + if (soc->free_addr_list_idx == max_list_size) + soc->free_addr_list_idx = 0; +} + +static inline +void add_entry_write_list(struct dp_soc *soc, struct dp_peer *peer, + uint32_t tid) +{ + uint32_t max_list_size; + unsigned long curr_ts = qdf_get_system_timestamp(); + + max_list_size = soc->wlan_cfg_ctx->qref_control_size; + + if (max_list_size == 0) + return; + + soc->reo_write_list[soc->write_paddr_list_idx].ts_qaddr_del = curr_ts; + soc->reo_write_list[soc->write_paddr_list_idx].peer_id = peer->peer_id; + soc->reo_write_list[soc->write_paddr_list_idx].paddr = + peer->rx_tid[tid].hw_qdesc_paddr; + soc->reo_write_list[soc->write_paddr_list_idx].tid = tid; + soc->write_paddr_list_idx++; + + if (soc->write_paddr_list_idx == max_list_size) + soc->write_paddr_list_idx = 0; +} + #ifdef REO_QDESC_HISTORY enum reo_qdesc_event_type { REO_QDESC_UPDATE_CB = 0, diff --git a/dp/wifi3.0/dp_rx_tid.c b/dp/wifi3.0/dp_rx_tid.c index b8d6b5e6e0..1204b60233 100644 --- a/dp/wifi3.0/dp_rx_tid.c +++ b/dp/wifi3.0/dp_rx_tid.c @@ -484,6 +484,33 @@ static void dp_reo_desc_defer_free(struct dp_soc *soc) } #endif /* !WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */ +void check_free_list_for_invalid_flush(struct dp_soc *soc) +{ + uint32_t i; + uint32_t *addr_deref_val; + unsigned long curr_ts = qdf_get_system_timestamp(); + uint32_t max_list_size; + + max_list_size = soc->wlan_cfg_ctx->qref_control_size; + + if (max_list_size == 0) + return; + + for (i = 0; i < soc->free_addr_list_idx; i++) { + addr_deref_val = (uint32_t *) + soc->list_qdesc_addr_free[i].hw_qdesc_vaddr_unalign; + + if (*addr_deref_val == 0xDDBEEF84 || + *addr_deref_val == 0xADBEEF84 || + *addr_deref_val == 0xBDBEEF84 || + *addr_deref_val == 0xCDBEEF84) { + if (soc->list_qdesc_addr_free[i].ts_hw_flush_back == 0) + soc->list_qdesc_addr_free[i].ts_hw_flush_back = + curr_ts; + } + } +} + /** * dp_reo_desc_free() - Callback free reo descriptor memory after * HW cache flush @@ -519,12 +546,16 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, goto out; DP_RX_REO_QDESC_FREE_EVT(freedesc); + add_entry_free_list(soc, rx_tid); hal_reo_shared_qaddr_cache_clear(soc->hal_soc); qdf_mem_unmap_nbytes_single(soc->osdev, rx_tid->hw_qdesc_paddr, QDF_DMA_BIDIRECTIONAL, rx_tid->hw_qdesc_alloc_size); + check_free_list_for_invalid_flush(soc); + + *(uint32_t *)rx_tid->hw_qdesc_vaddr_unaligned = 0; qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned); out: qdf_mem_free(freedesc); @@ -673,6 +704,8 @@ try_desc_alloc: QDF_DMA_BIDIRECTIONAL, rx_tid->hw_qdesc_alloc_size, &(rx_tid->hw_qdesc_paddr)); + add_entry_alloc_list(soc, rx_tid, peer, hw_qdesc_vaddr); + if (dp_reo_desc_addr_chk(rx_tid->hw_qdesc_paddr) != QDF_STATUS_SUCCESS) { if (alloc_tries++ < 10) { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 69f255d7cc..49e73af493 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2556,6 +2556,25 @@ struct sysfs_stats_config { }; #endif +struct test_mem_free { + unsigned long ts_qdesc_mem_hdl; + qdf_dma_addr_t hw_qdesc_paddr; + void *hw_qdesc_vaddr_align; + void *hw_qdesc_vaddr_unalign; + uint32_t peer_id; + uint32_t tid; + uint8_t chip_id; + unsigned long ts_hw_flush_back; +}; + +struct test_qaddr_del { + unsigned long ts_qaddr_del; + uint32_t peer_id; + uint32_t paddr; + uint32_t tid; + uint8_t chip_id; +}; + /* SOC level structure for data path */ struct dp_soc { /** @@ -3112,6 +3131,14 @@ struct dp_soc { #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) uint8_t mld_mode_ap; #endif + struct test_qaddr_del *list_shared_qaddr_del; + struct test_qaddr_del *reo_write_list; + struct test_mem_free *list_qdesc_addr_free; + struct test_mem_free *list_qdesc_addr_alloc; + uint64_t free_addr_list_idx; + uint64_t alloc_addr_list_idx; + uint64_t shared_qaddr_del_idx; + uint64_t write_paddr_list_idx; }; #ifdef IPA_OFFLOAD diff --git a/wlan_cfg/cfg_dp.h b/wlan_cfg/cfg_dp.h index f46049c8d0..842c0854b1 100644 --- a/wlan_cfg/cfg_dp.h +++ b/wlan_cfg/cfg_dp.h @@ -100,6 +100,8 @@ #define WLAN_CFG_TIME_CONTROL_BP 3000 +#define WLAN_CFG_QREF_CONTROL_SIZE 0 + #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) #define WLAN_CFG_PER_PDEV_RX_RING 0 #define WLAN_CFG_PER_PDEV_LMAC_RING 0 @@ -178,6 +180,9 @@ #define WLAN_CFG_TIME_CONTROL_BP_MIN 3000 #define WLAN_CFG_TIME_CONTROL_BP_MAX 1800000 +#define WLAN_CFG_QREF_CONTROL_SIZE_MIN 0 +#define WLAN_CFG_QREF_CONTROL_SIZE_MAX 4000 + #define WLAN_CFG_TX_COMP_RING_SIZE_MIN 512 #define WLAN_CFG_TX_COMP_RING_SIZE_MAX 0x80000 @@ -760,6 +765,13 @@ WLAN_CFG_TIME_CONTROL_BP,\ CFG_VALUE_OR_DEFAULT, "DP time control back pressure") +#define CFG_DP_QREF_CONTROL_SIZE \ + CFG_INI_UINT("dp_qref_control_size", \ + WLAN_CFG_QREF_CONTROL_SIZE_MIN,\ + WLAN_CFG_QREF_CONTROL_SIZE_MAX,\ + WLAN_CFG_QREF_CONTROL_SIZE,\ + CFG_VALUE_OR_DEFAULT, "DP array size for qref debug") + #ifdef CONFIG_SAWF_STATS #define CFG_DP_SAWF_STATS \ CFG_INI_UINT("dp_sawf_stats", \ @@ -1985,6 +1997,7 @@ CFG(CFG_DP_NSS_COMP_RING_SIZE) \ CFG(CFG_DP_PDEV_LMAC_RING) \ CFG(CFG_DP_TIME_CONTROL_BP) \ + CFG(CFG_DP_QREF_CONTROL_SIZE) \ CFG(CFG_DP_BASE_HW_MAC_ID) \ CFG(CFG_DP_RX_HASH) \ CFG(CFG_DP_RX_RR) \ diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index bde5e80439..c1642db37e 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -4081,6 +4081,8 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc) wlan_cfg_ctx->tx_ring_size = cfg_get(psoc, CFG_DP_TX_RING_SIZE); wlan_cfg_ctx->time_control_bp = cfg_get(psoc, CFG_DP_TIME_CONTROL_BP); + wlan_cfg_ctx->qref_control_size = + cfg_get(psoc, CFG_DP_QREF_CONTROL_SIZE); wlan_cfg_ctx->tx_comp_ring_size = cfg_get(psoc, CFG_DP_TX_COMPL_RING_SIZE); @@ -4693,6 +4695,11 @@ int wlan_cfg_time_control_bp(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->time_control_bp; } +int wlan_cfg_qref_control_size(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->qref_control_size; +} + int wlan_cfg_tx_comp_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) { return cfg->tx_comp_ring_size; diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 11d52277fc..c7d82cb6d1 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -176,6 +176,7 @@ struct wlan_srng_cfg { * @int_timer_threshold_mon: * @tx_ring_size: * @time_control_bp: + * @qref_control_size: list size for memory history arrays * @tx_comp_ring_size: * @tx_comp_ring_size_nss: * @int_rx_mon_ring_mask: Bitmap of Rx monitor ring interrupts mapped to each @@ -376,6 +377,7 @@ struct wlan_cfg_dp_soc_ctxt { int int_timer_threshold_mon; int tx_ring_size; int time_control_bp; + int qref_control_size; int tx_comp_ring_size; int tx_comp_ring_size_nss; uint8_t int_tx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; @@ -1580,6 +1582,14 @@ void wlan_cfg_set_tx_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg, */ int wlan_cfg_time_control_bp(struct wlan_cfg_dp_soc_ctxt *cfg); +/** + * wlan_cfg_qref_control_size - Get debug array size + * @cfg: soc configuration context + * + * Return: array size + */ +int wlan_cfg_qref_control_size(struct wlan_cfg_dp_soc_ctxt *cfg); + /** * wlan_cfg_tx_comp_ring_size - Get Tx completion ring size (WBM Ring) * @cfg: soc configuration context