From 813b3bb474a670087c509b065266797b5ae99969 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Thu, 8 Apr 2021 04:15:49 -0700 Subject: [PATCH] qcacmn: Add near-full irq handler for TX completion ring Add the handler to process the near-full condition on the tx completion ring. Change-Id: I547cd27d2a8a347fca1cebc6b27072f2d1d8a99d CRs-Fixed: 2965081 --- dp/wifi3.0/be/dp_be.c | 30 +++++++++++++++++++++ dp/wifi3.0/be/dp_be.h | 12 ++++----- dp/wifi3.0/be/dp_be_rx.c | 4 +-- dp/wifi3.0/be/dp_be_tx.c | 12 ++++++++- dp/wifi3.0/dp_tx.c | 57 ++++++++++++++++++++++++++++++++++++---- dp/wifi3.0/dp_types.h | 5 ++++ 6 files changed, 106 insertions(+), 14 deletions(-) diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index a043156a2b..246727582f 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -570,11 +570,41 @@ budget_done: return dp_budget - budget; } +/** + * dp_srng_test_and_update_nf_params_be() - Check if the srng is in near full + * state and set the reap_limit appropriately + * as per the near full state + * @soc: Datapath soc handle + * @dp_srng: Datapath handle for SRNG + * @max_reap_limit: [Output Buffer] Buffer to set the max reap limit as per + * the srng near-full state + * + * Return: 1, if the srng is in near-full state + * 0, if the srng is not in near-full state + */ +static int +dp_srng_test_and_update_nf_params_be(struct dp_soc *soc, + struct dp_srng *dp_srng, + int *max_reap_limit) +{ + return _dp_srng_test_and_update_nf_params(soc, dp_srng, max_reap_limit); +} + +/** + * dp_init_near_full_arch_ops_be() - Initialize the arch ops handler for the + * near full IRQ handling operations. + * @arch_ops: arch ops handle + * + * Return: none + */ static inline void dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops) { arch_ops->dp_service_near_full_srngs = dp_service_near_full_srngs_be; + arch_ops->dp_srng_test_and_update_nf_params = + dp_srng_test_and_update_nf_params_be; } + #else static inline void dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops) diff --git a/dp/wifi3.0/be/dp_be.h b/dp/wifi3.0/be/dp_be.h index 29518b4272..d6a6275f79 100644 --- a/dp/wifi3.0/be/dp_be.h +++ b/dp/wifi3.0/be/dp_be.h @@ -441,9 +441,9 @@ dp_srng_get_near_full_level(struct dp_soc *soc, struct dp_srng *dp_srng) * 0, if the srng is not near full */ static inline int -dp_srng_test_and_update_nf_params(struct dp_soc *soc, - struct dp_srng *srng, - int *max_reap_limit) +_dp_srng_test_and_update_nf_params(struct dp_soc *soc, + struct dp_srng *srng, + int *max_reap_limit) { int ring_near_full = 0, near_full_level; @@ -471,9 +471,9 @@ dp_srng_test_and_update_nf_params(struct dp_soc *soc, } #else static inline int -dp_srng_test_and_update_nf_params(struct dp_soc *soc, - struct dp_srng *srng, - int *max_reap_limit) +_dp_srng_test_and_update_nf_params(struct dp_soc *soc, + struct dp_srng *srng, + int *max_reap_limit) { return 0; } diff --git a/dp/wifi3.0/be/dp_be_rx.c b/dp/wifi3.0/be/dp_be_rx.c index 53143704ec..5eb2cf8ed4 100644 --- a/dp/wifi3.0/be/dp_be_rx.c +++ b/dp/wifi3.0/be/dp_be_rx.c @@ -134,8 +134,8 @@ more_data: qdf_mem_zero(head, sizeof(head)); qdf_mem_zero(tail, sizeof(tail)); - ring_near_full = dp_srng_test_and_update_nf_params(soc, rx_ring, - &max_reap_limit); + ring_near_full = _dp_srng_test_and_update_nf_params(soc, rx_ring, + &max_reap_limit); if (qdf_unlikely(dp_rx_srng_access_start(int_ctx, soc, hal_ring_hdl))) { /* diff --git a/dp/wifi3.0/be/dp_be_tx.c b/dp/wifi3.0/be/dp_be_tx.c index 746d08a147..0132b422b9 100644 --- a/dp/wifi3.0/be/dp_be_tx.c +++ b/dp/wifi3.0/be/dp_be_tx.c @@ -435,6 +435,16 @@ uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl, uint8_t ring_id, uint32_t quota) { - return 0; + struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[ring_id]; + uint32_t work_done = 0; + + if (dp_srng_get_near_full_level(soc, tx_comp_ring) < + DP_SRNG_THRESH_NEAR_FULL) + return 0; + + qdf_atomic_set(&tx_comp_ring->near_full, 1); + work_done++; + + return work_done; } #endif diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index ae4a294ce8..1abf17c7d7 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -4355,13 +4355,13 @@ void dp_tx_process_htt_completion(struct dp_soc *soc, #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT static inline -bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped) +bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped, + int max_reap_limit) { bool limit_hit = false; - struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx; limit_hit = - (num_reaped >= cfg->tx_comp_loop_pkt_limit) ? true : false; + (num_reaped >= max_reap_limit) ? true : false; if (limit_hit) DP_STATS_INC(soc, tx.tx_comp_loop_pkt_limit_hit, 1); @@ -4373,9 +4373,17 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc) { return soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check; } + +static inline int dp_tx_comp_get_loop_pkt_limit(struct dp_soc *soc) +{ + struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx; + + return cfg->tx_comp_loop_pkt_limit; +} #else static inline -bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped) +bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped, + int max_reap_limit) { return false; } @@ -4384,6 +4392,28 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc) { return false; } + +static inline int dp_tx_comp_get_loop_pkt_limit(struct dp_soc *soc) +{ + return 0; +} +#endif + +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ +static inline int +dp_srng_test_and_update_nf_params(struct dp_soc *soc, struct dp_srng *dp_srng, + int *max_reap_limit) +{ + return soc->arch_ops.dp_srng_test_and_update_nf_params(soc, dp_srng, + max_reap_limit); +} +#else +static inline int +dp_srng_test_and_update_nf_params(struct dp_soc *soc, struct dp_srng *dp_srng, + int *max_reap_limit) +{ + return 0; +} #endif uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, @@ -4399,6 +4429,8 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, uint32_t count; uint32_t num_avail_for_reap = 0; bool force_break = false; + struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[ring_id]; + int max_reap_limit, ring_near_full; DP_HIST_INIT(); @@ -4407,6 +4439,10 @@ more_data: head_desc = NULL; tail_desc = NULL; count = 0; + max_reap_limit = dp_tx_comp_get_loop_pkt_limit(soc); + + ring_near_full = dp_srng_test_and_update_nf_params(soc, tx_comp_ring, + &max_reap_limit); if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) { dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl); @@ -4561,7 +4597,7 @@ next_desc: count++; - if (dp_tx_comp_loop_pkt_limit_hit(soc, count)) + if (dp_tx_comp_loop_pkt_limit_hit(soc, count, max_reap_limit)) break; } @@ -4571,6 +4607,17 @@ next_desc: if (head_desc) dp_tx_comp_process_desc_list(soc, head_desc, ring_id); + /* + * If we are processing in near-full condition, there are 3 scenario + * 1) Ring entries has reached critical state + * 2) Ring entries are still near high threshold + * 3) Ring entries are below the safe level + * + * One more loop will move te state to normal processing and yield + */ + if (ring_near_full) + goto more_data; + if (dp_tx_comp_enable_eol_data_check(soc)) { if (num_processed >= quota) diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 39fb0257d8..4cdbfe0296 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1557,6 +1557,8 @@ enum dp_context_type { * source from HAL desc for wbm release ring * @dp_service_near_full_srngs: Handler for servicing the near full IRQ * @txrx_set_vdev_param: target specific ops while setting vdev params + * @dp_srng_test_and_update_nf_params: Check if the srng is in near full state + * and set the near-full params. */ struct dp_arch_ops { /* INIT/DEINIT Arch Ops */ @@ -1620,6 +1622,9 @@ struct dp_arch_ops { /* Misc Arch Ops */ qdf_size_t (*txrx_get_context_size)(enum dp_context_type); + int (*dp_srng_test_and_update_nf_params)(struct dp_soc *soc, + struct dp_srng *dp_srng, + int *max_reap_limit); }; /* SOC level structure for data path */