qcacld-3.0: Refactor TX/RX tuning in bus BW worker
Refactor tuning done in hdd_pld_request_bus_bandwidth for TX and RX. Change-Id: I1e994394d286c3152b5a01f3e0747e06d56e811b CRs-Fixed: 3045963
This commit is contained in:

gecommit door
Madan Koyyalamudi

bovenliggende
2f5862c059
commit
1b920619fb
@@ -10065,6 +10065,165 @@ static inline void hdd_low_tput_gro_flush_skip_handler(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_bus_bandwidth_work_tune_rx() - Function to tune for RX
|
||||
* @hdd_ctx - handle to hdd context
|
||||
* @rx_packets - receive packet count in last bus bandwidth interval
|
||||
* @next_rx_level - pointer to next_rx_level to be filled
|
||||
* @is_rx_pm_qos_high - pointer indicating if high qos is needed, to be filled
|
||||
*
|
||||
* The function tunes various aspects of the driver based on a running average
|
||||
* of RX packets received in last bus bandwidth interval.
|
||||
*
|
||||
* Returns: true if RX level has changed, else returns false
|
||||
*/
|
||||
static
|
||||
bool hdd_bus_bandwidth_work_tune_rx(struct hdd_context *hdd_ctx,
|
||||
const uint64_t rx_packets,
|
||||
enum wlan_tp_level *next_rx_level,
|
||||
bool *is_rx_pm_qos_high)
|
||||
{
|
||||
bool rx_level_change = false;
|
||||
bool rxthread_high_tput_req;
|
||||
uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
|
||||
uint64_t avg_rx;
|
||||
uint64_t no_rx_offload_pkts, avg_no_rx_offload_pkts;
|
||||
uint64_t rx_offload_pkts, avg_rx_offload_pkts;
|
||||
|
||||
/*
|
||||
* Includes tcp+udp, if perf core is required for tcp, then
|
||||
* perf core is also required for udp.
|
||||
*/
|
||||
no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
|
||||
hdd_ctx->no_rx_offload_pkt_cnt = 0;
|
||||
rx_offload_pkts = rx_packets - no_rx_offload_pkts;
|
||||
|
||||
avg_no_rx_offload_pkts = (no_rx_offload_pkts +
|
||||
hdd_ctx->prev_no_rx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
|
||||
|
||||
avg_rx_offload_pkts = (rx_offload_pkts +
|
||||
hdd_ctx->prev_rx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
|
||||
|
||||
avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
|
||||
/*
|
||||
* Takes care to set Rx_thread affinity for below case
|
||||
* 1)LRO/GRO not supported ROME case
|
||||
* 2)when rx_ol is disabled in cases like concurrency etc
|
||||
* 3)For UDP cases
|
||||
*/
|
||||
if (avg_no_rx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold) {
|
||||
rxthread_high_tput_req = true;
|
||||
*is_rx_pm_qos_high = true;
|
||||
} else {
|
||||
rxthread_high_tput_req = false;
|
||||
*is_rx_pm_qos_high = false;
|
||||
}
|
||||
|
||||
if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
|
||||
hdd_warn("Rx thread high_tput(%d) affinity request failed",
|
||||
rxthread_high_tput_req);
|
||||
|
||||
/* fine-tuning parameters for RX Flows */
|
||||
if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
|
||||
if (hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH &&
|
||||
++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt) {
|
||||
*next_rx_level = WLAN_SVC_TP_HIGH;
|
||||
}
|
||||
} else {
|
||||
hdd_ctx->rx_high_ind_cnt = 0;
|
||||
*next_rx_level = WLAN_SVC_TP_LOW;
|
||||
}
|
||||
|
||||
if (hdd_ctx->cur_rx_level != *next_rx_level) {
|
||||
struct wlan_rx_tp_data rx_tp_data = {0};
|
||||
|
||||
hdd_ctx->cur_rx_level = *next_rx_level;
|
||||
rx_level_change = true;
|
||||
/* Send throughput indication only if it is enabled.
|
||||
* Disabling tcp_del_ack will revert the tcp stack behavior
|
||||
* to default delayed ack. Note that this will disable the
|
||||
* dynamic delayed ack mechanism across the system
|
||||
*/
|
||||
if (hdd_ctx->en_tcp_delack_no_lro)
|
||||
rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
|
||||
|
||||
if (hdd_ctx->config->enable_tcp_adv_win_scale)
|
||||
rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
|
||||
|
||||
rx_tp_data.level = *next_rx_level;
|
||||
wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data);
|
||||
}
|
||||
|
||||
return rx_level_change;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_bus_bandwidth_work_tune_tx() - Function to tune for TX
|
||||
* @hdd_ctx - handle to hdd context
|
||||
* @tx_packets - transmit packet count in last bus bandwidth interval
|
||||
* @next_tx_level - pointer to next_tx_level to be filled
|
||||
* @is_tx_pm_qos_high - pointer indicating if high qos is needed, to be filled
|
||||
*
|
||||
* The function tunes various aspects of the driver based on a running average
|
||||
* of TX packets received in last bus bandwidth interval.
|
||||
*
|
||||
* Returns: true if TX level has changed, else returns false
|
||||
*/
|
||||
static
|
||||
bool hdd_bus_bandwidth_work_tune_tx(struct hdd_context *hdd_ctx,
|
||||
const uint64_t tx_packets,
|
||||
enum wlan_tp_level *next_tx_level,
|
||||
bool *is_tx_pm_qos_high)
|
||||
{
|
||||
bool tx_level_change = false;
|
||||
uint64_t no_tx_offload_pkts, avg_no_tx_offload_pkts;
|
||||
uint64_t tx_offload_pkts, avg_tx_offload_pkts;
|
||||
uint64_t avg_tx;
|
||||
|
||||
no_tx_offload_pkts = hdd_ctx->no_tx_offload_pkt_cnt;
|
||||
hdd_ctx->no_tx_offload_pkt_cnt = 0;
|
||||
tx_offload_pkts = tx_packets - no_tx_offload_pkts;
|
||||
|
||||
avg_no_tx_offload_pkts = (no_tx_offload_pkts +
|
||||
hdd_ctx->prev_no_tx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_no_tx_offload_pkts = no_tx_offload_pkts;
|
||||
|
||||
avg_tx_offload_pkts = (tx_offload_pkts +
|
||||
hdd_ctx->prev_tx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_tx_offload_pkts = tx_offload_pkts;
|
||||
|
||||
avg_tx = avg_no_tx_offload_pkts + avg_tx_offload_pkts;
|
||||
|
||||
/* fine-tuning parameters for TX Flows */
|
||||
hdd_ctx->prev_tx = tx_packets;
|
||||
|
||||
if (avg_no_tx_offload_pkts >
|
||||
hdd_ctx->config->bus_bw_high_threshold)
|
||||
*is_tx_pm_qos_high = true;
|
||||
else
|
||||
*is_tx_pm_qos_high = false;
|
||||
|
||||
if (avg_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
|
||||
*next_tx_level = WLAN_SVC_TP_HIGH;
|
||||
else
|
||||
*next_tx_level = WLAN_SVC_TP_LOW;
|
||||
|
||||
if (hdd_ctx->config->enable_tcp_limit_output &&
|
||||
hdd_ctx->cur_tx_level != *next_tx_level) {
|
||||
struct wlan_tx_tp_data tx_tp_data = {0};
|
||||
|
||||
hdd_ctx->cur_tx_level = *next_tx_level;
|
||||
tx_level_change = true;
|
||||
tx_tp_data.level = *next_tx_level;
|
||||
tx_tp_data.tcp_limit_output = true;
|
||||
wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data);
|
||||
}
|
||||
|
||||
return tx_level_change;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
|
||||
* @hdd_ctx - handle to hdd context
|
||||
@@ -10076,30 +10235,22 @@ static inline void hdd_low_tput_gro_flush_skip_handler(
|
||||
*
|
||||
* Returns: None
|
||||
*/
|
||||
|
||||
static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
|
||||
const uint64_t tx_packets,
|
||||
const uint64_t rx_packets)
|
||||
{
|
||||
uint16_t index = 0;
|
||||
uint16_t index;
|
||||
bool vote_level_change = false;
|
||||
bool rx_level_change = false;
|
||||
bool tx_level_change = false;
|
||||
bool rxthread_high_tput_req = false;
|
||||
bool rx_level_change;
|
||||
bool tx_level_change;
|
||||
bool dptrace_high_tput_req;
|
||||
u64 total_pkts = tx_packets + rx_packets;
|
||||
uint64_t avg_tx = 0, avg_rx = 0;
|
||||
uint64_t no_rx_offload_pkts = 0, avg_no_rx_offload_pkts = 0;
|
||||
uint64_t rx_offload_pkts = 0, avg_rx_offload_pkts = 0;
|
||||
uint64_t no_tx_offload_pkts = 0, avg_no_tx_offload_pkts = 0;
|
||||
uint64_t tx_offload_pkts = 0, avg_tx_offload_pkts = 0;
|
||||
enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_IDLE;
|
||||
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;
|
||||
cpumask_t pm_qos_cpu_mask;
|
||||
bool is_rx_pm_qos_high = false;
|
||||
bool is_tx_pm_qos_high = false;
|
||||
bool is_rx_pm_qos_high;
|
||||
bool is_tx_pm_qos_high;
|
||||
enum tput_level tput_level;
|
||||
struct bbm_params param = {0};
|
||||
bool legacy_client = false;
|
||||
@@ -10107,6 +10258,9 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
|
||||
ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
|
||||
static enum tput_level prev_tput_level = TPUT_LEVEL_NONE;
|
||||
|
||||
if (!soc)
|
||||
return;
|
||||
|
||||
cpumask_clear(&pm_qos_cpu_mask);
|
||||
|
||||
if (hdd_ctx->high_bus_bw_request) {
|
||||
@@ -10234,113 +10388,18 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
|
||||
|
||||
qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
|
||||
|
||||
/*
|
||||
* Includes tcp+udp, if perf core is required for tcp, then
|
||||
* perf core is also required for udp.
|
||||
*/
|
||||
no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
|
||||
hdd_ctx->no_rx_offload_pkt_cnt = 0;
|
||||
rx_offload_pkts = rx_packets - no_rx_offload_pkts;
|
||||
rx_level_change = hdd_bus_bandwidth_work_tune_rx(hdd_ctx,
|
||||
rx_packets,
|
||||
&next_rx_level,
|
||||
&is_rx_pm_qos_high);
|
||||
|
||||
avg_no_rx_offload_pkts = (no_rx_offload_pkts +
|
||||
hdd_ctx->prev_no_rx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
|
||||
tx_level_change = hdd_bus_bandwidth_work_tune_tx(hdd_ctx,
|
||||
tx_packets,
|
||||
&next_tx_level,
|
||||
&is_tx_pm_qos_high);
|
||||
|
||||
avg_rx_offload_pkts = (rx_offload_pkts +
|
||||
hdd_ctx->prev_rx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
|
||||
|
||||
avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
|
||||
/*
|
||||
* Takes care to set Rx_thread affinity for below case
|
||||
* 1)LRO/GRO not supported ROME case
|
||||
* 2)when rx_ol is disabled in cases like concurrency etc
|
||||
* 3)For UDP cases
|
||||
*/
|
||||
if (avg_no_rx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold) {
|
||||
rxthread_high_tput_req = true;
|
||||
is_rx_pm_qos_high = true;
|
||||
} else {
|
||||
rxthread_high_tput_req = false;
|
||||
is_rx_pm_qos_high = false;
|
||||
}
|
||||
|
||||
hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, is_rx_pm_qos_high);
|
||||
|
||||
if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
|
||||
hdd_warn("Rx thread high_tput(%d) affinity request failed",
|
||||
rxthread_high_tput_req);
|
||||
|
||||
/* fine-tuning parameters for RX Flows */
|
||||
if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
|
||||
if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
|
||||
(++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
|
||||
next_rx_level = WLAN_SVC_TP_HIGH;
|
||||
}
|
||||
} else {
|
||||
hdd_ctx->rx_high_ind_cnt = 0;
|
||||
next_rx_level = WLAN_SVC_TP_LOW;
|
||||
}
|
||||
|
||||
if (hdd_ctx->cur_rx_level != next_rx_level) {
|
||||
struct wlan_rx_tp_data rx_tp_data = {0};
|
||||
|
||||
hdd_ctx->cur_rx_level = next_rx_level;
|
||||
rx_level_change = true;
|
||||
/* Send throughput indication only if it is enabled.
|
||||
* Disabling tcp_del_ack will revert the tcp stack behavior
|
||||
* to default delayed ack. Note that this will disable the
|
||||
* dynamic delayed ack mechanism across the system
|
||||
*/
|
||||
if (hdd_ctx->en_tcp_delack_no_lro) {
|
||||
rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
|
||||
}
|
||||
|
||||
if (hdd_ctx->config->enable_tcp_adv_win_scale)
|
||||
rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
|
||||
|
||||
rx_tp_data.level = next_rx_level;
|
||||
wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data);
|
||||
}
|
||||
|
||||
no_tx_offload_pkts = hdd_ctx->no_tx_offload_pkt_cnt;
|
||||
hdd_ctx->no_tx_offload_pkt_cnt = 0;
|
||||
tx_offload_pkts = tx_packets - no_tx_offload_pkts;
|
||||
|
||||
avg_no_tx_offload_pkts = (no_tx_offload_pkts +
|
||||
hdd_ctx->prev_no_tx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_no_tx_offload_pkts = no_tx_offload_pkts;
|
||||
|
||||
avg_tx_offload_pkts = (tx_offload_pkts +
|
||||
hdd_ctx->prev_tx_offload_pkts) / 2;
|
||||
hdd_ctx->prev_tx_offload_pkts = tx_offload_pkts;
|
||||
|
||||
avg_tx = avg_no_tx_offload_pkts + avg_tx_offload_pkts;
|
||||
|
||||
/* fine-tuning parameters for TX Flows */
|
||||
hdd_ctx->prev_tx = tx_packets;
|
||||
|
||||
if (avg_no_tx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold)
|
||||
is_tx_pm_qos_high = true;
|
||||
else
|
||||
is_tx_pm_qos_high = false;
|
||||
|
||||
hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, is_tx_pm_qos_high);
|
||||
|
||||
if (avg_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
|
||||
next_tx_level = WLAN_SVC_TP_HIGH;
|
||||
else
|
||||
next_tx_level = WLAN_SVC_TP_LOW;
|
||||
|
||||
if ((hdd_ctx->config->enable_tcp_limit_output) &&
|
||||
(hdd_ctx->cur_tx_level != next_tx_level)) {
|
||||
struct wlan_tx_tp_data tx_tp_data = {0};
|
||||
hdd_ctx->cur_tx_level = next_tx_level;
|
||||
tx_level_change = true;
|
||||
tx_tp_data.level = next_tx_level;
|
||||
tx_tp_data.tcp_limit_output = true;
|
||||
wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data);
|
||||
}
|
||||
hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask,
|
||||
is_tx_pm_qos_high | is_rx_pm_qos_high);
|
||||
|
||||
index = hdd_ctx->hdd_txrx_hist_idx;
|
||||
if (vote_level_change || tx_level_change || rx_level_change) {
|
||||
@@ -10364,9 +10423,6 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
|
||||
hdd_ctx->hdd_txrx_hist_idx++;
|
||||
hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
|
||||
|
||||
/* Clear all the mask if no silver/gold vote is required */
|
||||
if (next_vote_level < PLD_BUS_WIDTH_MEDIUM)
|
||||
cpumask_clear(&pm_qos_cpu_mask);
|
||||
|
||||
if (!hdd_ctx->pm_qos_request)
|
||||
hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
|
||||
|
Verwijs in nieuw issue
Block a user