From baf49c9f89033a035881ed1594538fc0e123b51a Mon Sep 17 00:00:00 2001 From: Nanda Krishnan Date: Thu, 8 Jun 2023 11:01:18 +0530 Subject: [PATCH] qcacmn: Tracking the ring util stats Added serviceability changes to track ppe2tcl and wbm2rel ring util stats Change-Id: Ia154ae4914c47f010921eaed10b8a4dde50884bf CRs-Fixed: 3537655 --- dp/wifi3.0/be/dp_be.c | 42 +++++++++++++++++++++++++++++ dp/wifi3.0/be/dp_be_tx.c | 9 +++++++ dp/wifi3.0/dp_main.c | 11 ++++++++ dp/wifi3.0/dp_stats.c | 3 +++ dp/wifi3.0/dp_types.h | 6 +++++ hal/wifi3.0/hal_api.h | 57 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 128 insertions(+) diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index 8c7101afcd..4370722901 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -38,6 +38,16 @@ #include #endif +#ifdef WLAN_SUPPORT_PPEDS +static const char *ring_usage_dump[RING_USAGE_MAX] = { + "100%", + "Greater than 90%", + "70 to 90%", + "50 to 70%", + "Less than 50%" +}; +#endif + /* Generic AST entry aging timer value */ #define DP_AST_AGING_TIMER_DEFAULT_MS 5000 @@ -108,6 +118,36 @@ static void dp_ppeds_clear_stats(struct dp_soc *soc) be_soc->ppeds_stats.tx.desc_alloc_failed = 0; } + +static void dp_ppeds_rings_stats(struct dp_soc *soc) +{ + struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); + int i = 0; + + DP_PRINT_STATS("Ring utilization statistics"); + DP_PRINT_STATS("WBM2SW_RELEASE"); + + for (i = 0; i < RING_USAGE_MAX; i++) + DP_PRINT_STATS("\t %s utilized %d instances", + ring_usage_dump[i], + be_soc->ppeds_wbm_release_ring.stats.util[i]); + + DP_PRINT_STATS("PPE2TCL"); + + for (i = 0; i < RING_USAGE_MAX; i++) + DP_PRINT_STATS("\t %s utilized %d instances", + ring_usage_dump[i], + be_soc->ppe2tcl_ring.stats.util[i]); +} + +static void dp_ppeds_clear_rings_stats(struct dp_soc *soc) +{ + struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc); + + memset(&be_soc->ppeds_wbm_release_ring.stats, 0, + sizeof(struct ring_util_stats)); + memset(&be_soc->ppe2tcl_ring.stats, 0, sizeof(struct ring_util_stats)); +} #endif static void dp_soc_cfg_attach_be(struct dp_soc *soc) @@ -2912,6 +2952,8 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops) arch_ops->dp_free_ppeds_interrupts = dp_free_ppeds_interrupts; arch_ops->dp_tx_ppeds_inuse_desc = dp_ppeds_inuse_desc; arch_ops->dp_ppeds_clear_stats = dp_ppeds_clear_stats; + arch_ops->dp_txrx_ppeds_rings_stats = dp_ppeds_rings_stats; + arch_ops->dp_txrx_ppeds_clear_rings_stats = dp_ppeds_clear_rings_stats; arch_ops->dp_tx_ppeds_cfg_astidx_cache_mapping = dp_tx_ppeds_cfg_astidx_cache_mapping; #ifdef DP_UMAC_HW_RESET_SUPPORT diff --git a/dp/wifi3.0/be/dp_be_tx.c b/dp/wifi3.0/be/dp_be_tx.c index f39c581d64..c6412b0085 100644 --- a/dp/wifi3.0/be/dp_be_tx.c +++ b/dp/wifi3.0/be/dp_be_tx.c @@ -1037,6 +1037,7 @@ int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota) dp_txrx_ref_handle txrx_ref_handle = NULL; struct dp_vdev *vdev = NULL; struct dp_pdev *pdev = NULL; + struct dp_srng *srng; if (qdf_unlikely(dp_srng_access_start(NULL, soc, hal_ring_hdl))) { dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl); @@ -1053,6 +1054,14 @@ int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota) last_prefetch_hw_desc = dp_srng_dst_prefetch(hal_soc, hal_ring_hdl, num_avail_for_reap); + srng = &be_soc->ppeds_wbm_release_ring; + + if (srng) { + hal_update_ring_util(soc->hal_soc, srng->hal_srng, + WBM2SW_RELEASE, + &be_soc->ppeds_wbm_release_ring.stats); + } + while (qdf_likely(num_avail_for_reap--)) { tx_comp_hal_desc = dp_srng_dst_get_next(soc, hal_ring_hdl); if (qdf_unlikely(!tx_comp_hal_desc)) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index e863c7ce56..5ea34676a0 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -6262,10 +6262,20 @@ static void dp_clear_tx_ppeds_stats(struct dp_soc *soc) if (soc->arch_ops.dp_ppeds_clear_stats) soc->arch_ops.dp_ppeds_clear_stats(soc); } + +static void dp_ppeds_clear_ring_util_stats(struct dp_soc *soc) +{ + if (soc->arch_ops.dp_txrx_ppeds_clear_rings_stats) + soc->arch_ops.dp_txrx_ppeds_clear_rings_stats(soc); +} #else static void dp_clear_tx_ppeds_stats(struct dp_soc *soc) { } + +static void dp_ppeds_clear_ring_util_stats(struct dp_soc *soc) +{ +} #endif /** @@ -6301,6 +6311,7 @@ dp_txrx_host_stats_clr(struct dp_vdev *vdev, struct dp_soc *soc) DP_STATS_CLR(vdev->pdev->soc); dp_clear_tx_ppeds_stats(soc); + dp_ppeds_clear_ring_util_stats(soc); hif_clear_napi_stats(vdev->pdev->soc->hif_handle); diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index bd0509cd29..b82860567b 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -7979,6 +7979,9 @@ void dp_print_tx_ppeds_stats(struct dp_soc *soc) DP_PRINT_STATS("PPE-DS Tx desc fw2wbm_tx_drop %u", soc->stats.tx.fw2wbm_tx_drop); + + if (soc->arch_ops.dp_txrx_ppeds_rings_stats) + soc->arch_ops.dp_txrx_ppeds_rings_stats(soc); } #else void dp_print_tx_ppeds_stats(struct dp_soc *soc) diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index ec0e3ea74c..630fd9d4f6 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -845,6 +845,7 @@ struct dp_txrx_pool_stats { * @cached: is the srng ring memory cached or un-cached memory * @irq: irq number of the srng ring * @num_entries: number of entries in the srng ring + * @stats: Structure to track the ring utilization stats * @is_mem_prealloc: Is this srng memory pre-allocated * @crit_thresh: Critical threshold for near-full processing of this srng * @safe_thresh: Safe threshold for near-full processing of this srng @@ -860,6 +861,7 @@ struct dp_srng { uint8_t cached; int irq; uint32_t num_entries; + struct ring_util_stats stats; #ifdef DP_MEM_PRE_ALLOC uint8_t is_mem_prealloc; #endif @@ -2215,6 +2217,8 @@ enum dp_context_type { * @dp_tx_ppeds_inuse_desc: * @dp_ppeds_clear_stats: Clear ppeds related stats * @dp_tx_ppeds_cfg_astidx_cache_mapping: + * @dp_txrx_ppeds_rings_stats: Printing the util stats of ring + * @dp_txrx_ppeds_clear_rings_stats: Clearing the ring util stats * @txrx_soc_ppeds_start: * @txrx_soc_ppeds_stop: * @dp_register_ppeds_interrupts: @@ -2444,6 +2448,8 @@ struct dp_arch_ops { void (*dp_tx_ppeds_cfg_astidx_cache_mapping)(struct dp_soc *soc, struct dp_vdev *vdev, bool peer_map); + void (*dp_txrx_ppeds_rings_stats)(struct dp_soc *soc); + void (*dp_txrx_ppeds_clear_rings_stats)(struct dp_soc *soc); #endif bool (*ppeds_handle_attached)(struct dp_soc *soc); QDF_STATUS (*txrx_soc_ppeds_start)(struct dp_soc *soc); diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index d412ee2e1a..33a38444dc 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -43,6 +43,30 @@ #define CHECK_SHADOW_REGISTERS false #endif +/* + * Indices for stats + */ +enum RING_USAGE { + RING_USAGE_100, + RING_USAGE_GREAT_90, + RING_USAGE_70_TO_90, + RING_USAGE_50_TO_70, + RING_USAGE_LESS_50, + RING_USAGE_MAX, +}; + +/* + * Structure for tracking ring utilization + */ +struct ring_util_stats { + uint32_t util[RING_USAGE_MAX]; +}; + +#define RING_USAGE_100_PERCENTAGE 100 +#define RING_USAGE_50_PERCENTAGE 50 +#define RING_USAGE_70_PERCENTAGE 70 +#define RING_USAGE_90_PERCENTAGE 90 + /* calculate the register address offset from bar0 of shadow register x */ #if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ defined(QCA_WIFI_KIWI) @@ -3233,6 +3257,39 @@ uint32_t hal_get_ring_usage( return ring_usage; } +/* + * hal_update_ring_util_stats - API for tracking ring utlization + * @hal_soc: Opaque HAL SOC handle + * @hal_ring_hdl: Source ring pointer + * @ring_type: Ring type + * @ring_util_stats: Ring utilisation structure + */ +static inline +void hal_update_ring_util(void *hal_soc, hal_ring_handle_t hal_ring_hdl, + enum hal_ring_type ring_type, + struct ring_util_stats *ring_utilisation) +{ + uint32_t tailp, headp, ring_usage; + + hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tailp, &headp); + ring_usage = hal_get_ring_usage(hal_ring_hdl, ring_type, &headp, + &tailp); + + if (ring_usage == RING_USAGE_100_PERCENTAGE) { + ring_utilisation->util[RING_USAGE_100]++; + } else if (ring_usage > RING_USAGE_90_PERCENTAGE) { + ring_utilisation->util[RING_USAGE_GREAT_90]++; + } else if ((ring_usage > RING_USAGE_70_PERCENTAGE) && + (ring_usage <= RING_USAGE_90_PERCENTAGE)) { + ring_utilisation->util[RING_USAGE_70_TO_90]++; + } else if ((ring_usage > RING_USAGE_50_PERCENTAGE) && + (ring_usage <= RING_USAGE_70_PERCENTAGE)) { + ring_utilisation->util[RING_USAGE_50_TO_70]++; + } else { + ring_utilisation->util[RING_USAGE_LESS_50]++; + } +} + /** * hal_cmem_write() - function for CMEM buffer writing * @hal_soc_hdl: HAL SOC handle