qcacmn: Tracking the ring util stats

Added serviceability changes to track ppe2tcl
and wbm2rel ring util stats

Change-Id: Ia154ae4914c47f010921eaed10b8a4dde50884bf
CRs-Fixed: 3537655
This commit is contained in:
Nanda Krishnan
2023-06-08 11:01:18 +05:30
committed by Rahul Choudhary
parent c9d9e88708
commit baf49c9f89
6 changed files with 128 additions and 0 deletions

View File

@@ -38,6 +38,16 @@
#include <ppe_drv_sc.h> #include <ppe_drv_sc.h>
#endif #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 */ /* Generic AST entry aging timer value */
#define DP_AST_AGING_TIMER_DEFAULT_MS 5000 #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; 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 #endif
static void dp_soc_cfg_attach_be(struct dp_soc *soc) 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_free_ppeds_interrupts = dp_free_ppeds_interrupts;
arch_ops->dp_tx_ppeds_inuse_desc = dp_ppeds_inuse_desc; arch_ops->dp_tx_ppeds_inuse_desc = dp_ppeds_inuse_desc;
arch_ops->dp_ppeds_clear_stats = dp_ppeds_clear_stats; 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 = arch_ops->dp_tx_ppeds_cfg_astidx_cache_mapping =
dp_tx_ppeds_cfg_astidx_cache_mapping; dp_tx_ppeds_cfg_astidx_cache_mapping;
#ifdef DP_UMAC_HW_RESET_SUPPORT #ifdef DP_UMAC_HW_RESET_SUPPORT

View File

@@ -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; dp_txrx_ref_handle txrx_ref_handle = NULL;
struct dp_vdev *vdev = NULL; struct dp_vdev *vdev = NULL;
struct dp_pdev *pdev = NULL; struct dp_pdev *pdev = NULL;
struct dp_srng *srng;
if (qdf_unlikely(dp_srng_access_start(NULL, soc, hal_ring_hdl))) { if (qdf_unlikely(dp_srng_access_start(NULL, soc, hal_ring_hdl))) {
dp_err("HAL RING Access Failed -- %pK", 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, last_prefetch_hw_desc = dp_srng_dst_prefetch(hal_soc, hal_ring_hdl,
num_avail_for_reap); 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--)) { while (qdf_likely(num_avail_for_reap--)) {
tx_comp_hal_desc = dp_srng_dst_get_next(soc, hal_ring_hdl); tx_comp_hal_desc = dp_srng_dst_get_next(soc, hal_ring_hdl);
if (qdf_unlikely(!tx_comp_hal_desc)) if (qdf_unlikely(!tx_comp_hal_desc))

View File

@@ -6262,10 +6262,20 @@ static void dp_clear_tx_ppeds_stats(struct dp_soc *soc)
if (soc->arch_ops.dp_ppeds_clear_stats) if (soc->arch_ops.dp_ppeds_clear_stats)
soc->arch_ops.dp_ppeds_clear_stats(soc); 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 #else
static void dp_clear_tx_ppeds_stats(struct dp_soc *soc) static void dp_clear_tx_ppeds_stats(struct dp_soc *soc)
{ {
} }
static void dp_ppeds_clear_ring_util_stats(struct dp_soc *soc)
{
}
#endif #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_STATS_CLR(vdev->pdev->soc);
dp_clear_tx_ppeds_stats(soc); dp_clear_tx_ppeds_stats(soc);
dp_ppeds_clear_ring_util_stats(soc);
hif_clear_napi_stats(vdev->pdev->soc->hif_handle); hif_clear_napi_stats(vdev->pdev->soc->hif_handle);

View File

@@ -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", DP_PRINT_STATS("PPE-DS Tx desc fw2wbm_tx_drop %u",
soc->stats.tx.fw2wbm_tx_drop); 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 #else
void dp_print_tx_ppeds_stats(struct dp_soc *soc) void dp_print_tx_ppeds_stats(struct dp_soc *soc)

View File

@@ -845,6 +845,7 @@ struct dp_txrx_pool_stats {
* @cached: is the srng ring memory cached or un-cached memory * @cached: is the srng ring memory cached or un-cached memory
* @irq: irq number of the srng ring * @irq: irq number of the srng ring
* @num_entries: number of entries in 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 * @is_mem_prealloc: Is this srng memory pre-allocated
* @crit_thresh: Critical threshold for near-full processing of this srng * @crit_thresh: Critical threshold for near-full processing of this srng
* @safe_thresh: Safe 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; uint8_t cached;
int irq; int irq;
uint32_t num_entries; uint32_t num_entries;
struct ring_util_stats stats;
#ifdef DP_MEM_PRE_ALLOC #ifdef DP_MEM_PRE_ALLOC
uint8_t is_mem_prealloc; uint8_t is_mem_prealloc;
#endif #endif
@@ -2215,6 +2217,8 @@ enum dp_context_type {
* @dp_tx_ppeds_inuse_desc: * @dp_tx_ppeds_inuse_desc:
* @dp_ppeds_clear_stats: Clear ppeds related stats * @dp_ppeds_clear_stats: Clear ppeds related stats
* @dp_tx_ppeds_cfg_astidx_cache_mapping: * @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_start:
* @txrx_soc_ppeds_stop: * @txrx_soc_ppeds_stop:
* @dp_register_ppeds_interrupts: * @dp_register_ppeds_interrupts:
@@ -2444,6 +2448,8 @@ struct dp_arch_ops {
void (*dp_tx_ppeds_cfg_astidx_cache_mapping)(struct dp_soc *soc, void (*dp_tx_ppeds_cfg_astidx_cache_mapping)(struct dp_soc *soc,
struct dp_vdev *vdev, struct dp_vdev *vdev,
bool peer_map); 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 #endif
bool (*ppeds_handle_attached)(struct dp_soc *soc); bool (*ppeds_handle_attached)(struct dp_soc *soc);
QDF_STATUS (*txrx_soc_ppeds_start)(struct dp_soc *soc); QDF_STATUS (*txrx_soc_ppeds_start)(struct dp_soc *soc);

View File

@@ -43,6 +43,30 @@
#define CHECK_SHADOW_REGISTERS false #define CHECK_SHADOW_REGISTERS false
#endif #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 */ /* calculate the register address offset from bar0 of shadow register x */
#if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ #if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \
defined(QCA_WIFI_KIWI) defined(QCA_WIFI_KIWI)
@@ -3233,6 +3257,39 @@ uint32_t hal_get_ring_usage(
return 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_cmem_write() - function for CMEM buffer writing
* @hal_soc_hdl: HAL SOC handle * @hal_soc_hdl: HAL SOC handle