From 0dc383e4e253ce18a54904df8d83d6bc7ec69b75 Mon Sep 17 00:00:00 2001 From: Jinwei Chen Date: Fri, 23 Aug 2019 00:43:04 +0800 Subject: [PATCH] qcacld-3.0: refine low Tput GRO logic a. when T-put < 18Mbps, do GRO/GRO flush for each RX packet. b. when T-put can kept stable (18Mbps ~ 60 Mbps) last >= 1 second , skip GRO flush logic. Change-Id: Ic8075f10f72b479c6941d7ac12a71fd90f945094 CRs-Fixed: 2509672 --- core/hdd/inc/hdd_dp_cfg.h | 32 +++++++++++++++++++++++++++++++- core/hdd/inc/wlan_hdd_cfg.h | 1 + core/hdd/inc/wlan_hdd_main.h | 15 +++++++++++++++ core/hdd/src/wlan_hdd_main.c | 9 +++++++++ core/hdd/src/wlan_hdd_stats.c | 3 ++- core/hdd/src/wlan_hdd_tx_rx.c | 11 +++++++++-- core/hdd/src/wlan_hdd_wext.c | 3 ++- 7 files changed, 69 insertions(+), 5 deletions(-) diff --git a/core/hdd/inc/hdd_dp_cfg.h b/core/hdd/inc/hdd_dp_cfg.h index 06862ca238..63df0f6c69 100644 --- a/core/hdd/inc/hdd_dp_cfg.h +++ b/core/hdd/inc/hdd_dp_cfg.h @@ -640,6 +640,35 @@ 500, \ CFG_VALUE_OR_DEFAULT, \ "High Threshold inorder to trigger High Tx Tp") + +/* + * + * gBusLowTputCntThreshold - Threshold count to trigger low Tput + * GRO flush skip + * @Min: 0 + * @Max: 200 + * @Default: 10 + * + * This ini is a threshold that if count of times for bus Tput level + * PLD_BUS_WIDTH_LOW in bus_bw_timer() >= this threshold, will enable skipping + * GRO flush, current default threshold is 10, then will delay GRO flush-skip + * 1 second for low Tput level. + * + * Supported Feature: GRO flush skip when low T-put + * + * Usage: Internal + * + * + */ +#define CFG_DP_BUS_LOW_BW_CNT_THRESHOLD \ + CFG_INI_UINT( \ + "gBusLowTputCntThreshold", \ + 0, \ + 200, \ + 10, \ + CFG_VALUE_OR_DEFAULT, \ + "Threshold to trigger GRO flush skip for low T-put") + #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK @@ -1225,7 +1254,8 @@ CFG(CFG_DP_TCP_DELACK_THRESHOLD_HIGH) \ CFG(CFG_DP_TCP_DELACK_THRESHOLD_LOW) \ CFG(CFG_DP_TCP_DELACK_TIMER_COUNT) \ - CFG(CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD) + CFG(CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD) \ + CFG(CFG_DP_BUS_LOW_BW_CNT_THRESHOLD) #else #define CFG_HDD_DP_BUS_BANDWIDTH #endif diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 1e0208f4c2..fed372bc86 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -170,6 +170,7 @@ struct hdd_config { uint32_t tcp_tx_high_tput_thres; uint32_t tcp_delack_timer_count; bool enable_tcp_param_update; + uint32_t bus_low_cnt_threshold; #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 3a40ffb5da..b2a5137faa 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -453,6 +453,7 @@ struct hdd_tx_rx_stats { __u32 rx_gro_dropped; __u32 rx_non_aggregated; __u32 rx_gro_flush_skip; + __u32 rx_gro_low_tput_flush; /* txflow stats */ bool is_txflow_paused; @@ -1755,6 +1756,8 @@ struct hdd_context { uint64_t prev_rx_offload_pkts; int cur_tx_level; uint64_t prev_tx; + qdf_atomic_t low_tput_gro_enable; + uint32_t bus_low_vote_cnt; #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ struct completion ready_to_suspend; @@ -2370,6 +2373,12 @@ hdd_get_current_throughput_level(struct hdd_context *hdd_ctx) return hdd_ctx->cur_vote_level; } +static inline bool +hdd_is_low_tput_gro_enable(struct hdd_context *hdd_ctx) +{ + return (qdf_atomic_read(&hdd_ctx->low_tput_gro_enable)) ? true : false; +} + #define GET_CUR_RX_LVL(config) ((config)->cur_rx_level) #define GET_BW_COMPUTE_INTV(config) ((config)->bus_bw_compute_interval) #else @@ -2421,6 +2430,12 @@ hdd_get_current_throughput_level(struct hdd_context *hdd_ctx) return PLD_BUS_WIDTH_NONE; } +static inline bool +hdd_is_low_tput_gro_enable(struct hdd_context *hdd_ctx) +{ + return false; +} + #define GET_CUR_RX_LVL(config) 0 #define GET_BW_COMPUTE_INTV(config) 0 diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index d4a44877ee..139410b0ad 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -8182,6 +8182,7 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE; enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE; uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count; + uint32_t bus_low_cnt_threshold = hdd_ctx->config->bus_low_cnt_threshold; if (total_pkts > hdd_ctx->config->bus_bw_very_high_threshold) next_vote_level = PLD_BUS_WIDTH_VERY_HIGH; @@ -8197,6 +8198,14 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, dptrace_high_tput_req = next_vote_level > PLD_BUS_WIDTH_IDLE ? true : false; + if (next_vote_level == PLD_BUS_WIDTH_LOW) { + if (++hdd_ctx->bus_low_vote_cnt >= bus_low_cnt_threshold) + qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 1); + } else { + hdd_ctx->bus_low_vote_cnt = 0; + qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 0); + } + if (hdd_ctx->cur_vote_level != next_vote_level) { hdd_debug("BW Vote level %d, tx_packets: %lld, rx_packets: %lld", next_vote_level, tx_packets, rx_packets); diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 84e7ca905f..d020a55ee2 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -5818,13 +5818,14 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *ctx) i, stats->rx_packets[i], stats->rx_dropped[i], stats->rx_delivered[i], stats->rx_refused[i]); } - hdd_debug("RX - packets %u, dropped %u, unsolict_arp_n_mcast_drp %u, delivered %u, refused %u GRO - agg %u drop %u non-agg %u flush-skip %u disabled(conc %u low-tput %u)", + hdd_debug("RX - packets %u, dropped %u, unsolict_arp_n_mcast_drp %u, delivered %u, refused %u GRO - agg %u drop %u non-agg %u flush_skip %u low_tput_flush %u disabled(conc %u low-tput %u)", total_rx_pkt, total_rx_dropped, qdf_atomic_read(&stats->rx_usolict_arp_n_mcast_drp), total_rx_delv, total_rx_refused, stats->rx_aggregated, stats->rx_gro_dropped, stats->rx_non_aggregated, stats->rx_gro_flush_skip, + stats->rx_gro_low_tput_flush, qdf_atomic_read(&ctx->disable_rx_ol_in_concurrency), qdf_atomic_read(&ctx->disable_rx_ol_in_low_tput)); } diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index d65d08a76b..cfc9e43cb5 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -1545,12 +1545,18 @@ static QDF_STATUS hdd_gro_rx_bh_disable(struct hdd_adapter *adapter, struct sk_buff *skb) { QDF_STATUS status = QDF_STATUS_SUCCESS; + struct hdd_context *hdd_ctx = adapter->hdd_ctx; gro_result_t gro_res; skb_set_hash(skb, QDF_NBUF_CB_RX_FLOW_ID(skb), PKT_HASH_TYPE_L4); local_bh_disable(); gro_res = napi_gro_receive(napi_to_use, skb); + + if (hdd_get_current_throughput_level(hdd_ctx) == PLD_BUS_WIDTH_IDLE) { + adapter->hdd_stats.tx_rx_stats.rx_gro_low_tput_flush++; + napi_gro_flush(napi_to_use, false); + } local_bh_enable(); if (gro_res == GRO_DROP) @@ -1888,8 +1894,7 @@ QDF_STATUS hdd_rx_thread_gro_flush_ind_cbk(void *adapter, int rx_ctx_id) return QDF_STATUS_E_FAILURE; } - if (hdd_get_current_throughput_level(hdd_adapter->hdd_ctx) == - PLD_BUS_WIDTH_LOW) { + if (hdd_is_low_tput_gro_enable(hdd_adapter->hdd_ctx)) { hdd_adapter->hdd_stats.tx_rx_stats.rx_gro_flush_skip++; return QDF_STATUS_SUCCESS; } @@ -2902,6 +2907,8 @@ static void hdd_ini_bus_bandwidth(struct hdd_config *config, cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD); config->bus_bw_compute_interval = cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_COMPUTE_INTERVAL); + config->bus_low_cnt_threshold = + cfg_get(psoc, CFG_DP_BUS_LOW_BW_CNT_THRESHOLD); } /** diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 2b8dd8cad8..3dc7417013 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -3115,7 +3115,7 @@ void hdd_wlan_get_stats(struct hdd_adapter *adapter, uint16_t *length, "\n[classified] BK %u, BE %u, VI %u, VO %u" "\n\nReceive[%lu] - " "packets %u, dropped %u, unsolict_arp_n_mcast_drp %u, delivered %u, refused %u\n" - "GRO - agg %u non-agg %u flush-skip %u disabled(conc %u low-tput %u)\n", + "GRO - agg %u non-agg %u flush_skip %u low_tput_flush %u disabled(conc %u low-tput %u)\n", qdf_system_ticks(), stats->tx_called, stats->tx_dropped, @@ -3135,6 +3135,7 @@ void hdd_wlan_get_stats(struct hdd_adapter *adapter, uint16_t *length, total_rx_refused, stats->rx_aggregated, stats->rx_non_aggregated, stats->rx_gro_flush_skip, + stats->rx_gro_low_tput_flush, qdf_atomic_read(&hdd_ctx->disable_rx_ol_in_concurrency), qdf_atomic_read(&hdd_ctx->disable_rx_ol_in_low_tput));