Browse Source

qcald-3.0: tweak sys params during high tx bandwidth case

qcacld-2.0 to qcacld-3.0 propagation

In hdd_cnss_request_bus_bandwidth function, the overall bus bandwidth
and rx bandwidth requirements are being determined based on tx and
rx packets. This change detects tx bandwidth required (high or low)
and sends WLAN_SVC_WLAN_TP_TX_IND indication to cnss-daemon which can
tweak system parameters depending upon TX bandwidth needed.

Change-Id: I3eec2e3f95fa32b191d905209a38cb6d48837c33
CRs-Fixed: 918529
Mohit Khanna 9 years ago
parent
commit
e71e2264cd

+ 13 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -2181,6 +2181,18 @@ typedef enum {
 #define CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT       (1000)
 #define CFG_TCP_DELACK_THRESHOLD_LOW_MIN           (0)
 #define CFG_TCP_DELACK_THRESHOLD_LOW_MAX           (10000)
+
+/* TCP_TX_HIGH_TPUT_THRESHOLD specifies the threshold of packets transmitted
+ * over a period of 100 ms beyond which TCP can be considered to have a high
+ * TX throughput requirement. The driver uses this condition to tweak TCP TX
+ * specific parameters (via cnss-daemon).
+ * default  - 500
+ */
+#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_NAME         "gTcpTxHighTputThreshold"
+#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_DEFAULT      (500)
+#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MIN          (0)
+#define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MAX          (16000)
+
 #endif /* MSM_PLATFORM */
 
 #ifdef WLAN_FEATURE_11W
@@ -3172,6 +3184,7 @@ struct hdd_config {
 	uint32_t busBandwidthComputeInterval;
 	uint32_t tcpDelackThresholdHigh;
 	uint32_t tcpDelackThresholdLow;
+	uint32_t tcp_tx_high_tput_thres;
 #endif /* MSM_PLATFORM */
 
 	/* FW debug log parameters */

+ 23 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -317,6 +317,26 @@ extern spinlock_t hdd_context_lock;
 #define NUM_TX_RX_HISTOGRAM 1024
 #define NUM_TX_RX_HISTOGRAM_MASK (NUM_TX_RX_HISTOGRAM - 1)
 
+/**
+ * struct hdd_tx_rx_histogram - structure to keep track of tx and rx packets
+ *				received over 100ms intervals
+ * @interval_rx:	# of rx packets received in the last 100ms interval
+ * @interval_tx:	# of tx packets received in the last 100ms interval
+ * @total_rx:		# of total rx packets received on interface
+ * @total_tx:		# of total tx packets received on interface
+ * @next_vote_level:	cnss_bus_width_type voting level (high or low)
+ *			determined on the basis of total tx and rx packets
+ *			received in the last 100ms interval
+ * @next_rx_level:	cnss_bus_width_type voting level (high or low)
+ *			determined on the basis of rx packets received in the
+ *			last 100ms interval
+ * @next_tx_level:	cnss_bus_width_type voting level (high or low)
+ *			determined on the basis of tx packets received in the
+ *			last 100ms interval
+ *
+ * The structure keeps track of throughput requirements of wlan driver in 100ms
+ * intervals for later analysis.
+ */
 struct hdd_tx_rx_histogram {
 	uint64_t interval_rx;
 	uint64_t interval_tx;
@@ -324,6 +344,7 @@ struct hdd_tx_rx_histogram {
 	uint64_t total_tx;
 	uint32_t next_vote_level;
 	uint32_t next_rx_level;
+	uint32_t next_tx_level;
 };
 
 typedef struct hdd_tx_rx_stats_s {
@@ -1215,6 +1236,8 @@ struct hdd_context_s {
 	spinlock_t bus_bw_lock;
 	int cur_rx_level;
 	uint64_t prev_rx;
+	int cur_tx_level;
+	uint64_t prev_tx;
 #endif
 	/* VHT80 allowed */
 	bool isVHT80Allowed;

+ 13 - 0
core/hdd/src/wlan_hdd_cfg.c

@@ -2973,6 +2973,14 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT,
 		     CFG_TCP_DELACK_THRESHOLD_LOW_MIN,
 		     CFG_TCP_DELACK_THRESHOLD_LOW_MAX),
+
+	REG_VARIABLE(CFG_TCP_TX_HIGH_TPUT_THRESHOLD_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, tcp_tx_high_tput_thres,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_TCP_TX_HIGH_TPUT_THRESHOLD_DEFAULT,
+		CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MIN,
+		CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MAX),
+
 #endif
 
 	REG_VARIABLE(CFG_ENABLE_FW_LOG_TYPE, WLAN_PARAM_Integer,
@@ -4913,6 +4921,11 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [gTcpDelAckThresholdLow] Value = [%u] ",
 		  pHddCtx->config->tcpDelackThresholdLow);
+	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
+		"Name = [%s] Value = [%u] ",
+		CFG_TCP_TX_HIGH_TPUT_THRESHOLD_NAME,
+		pHddCtx->config->tcp_tx_high_tput_thres);
+
 #endif
 
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,

+ 41 - 13
core/hdd/src/wlan_hdd_main.c

@@ -3942,14 +3942,17 @@ static CDF_STATUS wlan_hdd_regulatory_init(hdd_context_t *hdd_ctx)
 
 #ifdef MSM_PLATFORM
 void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx,
-				    uint64_t tx_packets, uint64_t rx_packets)
+			const uint64_t tx_packets, const uint64_t rx_packets)
 {
 #ifdef CONFIG_CNSS
 	uint64_t total = tx_packets + rx_packets;
+	uint64_t temp_rx = 0;
+	uint64_t temp_tx = 0;
 	enum cnss_bus_width_type next_vote_level = CNSS_BUS_WIDTH_NONE;
+	enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
+	enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
+
 
-	uint64_t temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;
-	enum cnss_bus_width_type next_rx_level = CNSS_BUS_WIDTH_NONE;
 	if (total > hdd_ctx->config->busBandwidthHighThreshold)
 		next_vote_level = CNSS_BUS_WIDTH_HIGH;
 	else if (total > hdd_ctx->config->busBandwidthMediumThreshold)
@@ -3959,8 +3962,8 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx,
 	else
 		next_vote_level = CNSS_BUS_WIDTH_NONE;
 
-	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_vote_level
-							   = next_vote_level;
+	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_vote_level =
+							next_vote_level;
 
 	if (hdd_ctx->cur_vote_level != next_vote_level) {
 		hddLog(CDF_TRACE_LEVEL_DEBUG,
@@ -3971,14 +3974,18 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx,
 		hdd_ctx->cur_vote_level = next_vote_level;
 		cnss_request_bus_bandwidth(next_vote_level);
 	}
+
+	/* fine-tuning parameters for RX Flows */
+	temp_rx = (rx_packets + hdd_ctx->prev_rx) / 2;
+
 	hdd_ctx->prev_rx = rx_packets;
 	if (temp_rx > hdd_ctx->config->tcpDelackThresholdHigh)
-		next_rx_level = CNSS_BUS_WIDTH_HIGH;
+		next_rx_level = WLAN_SVC_TP_HIGH;
 	else
-		next_rx_level = CNSS_BUS_WIDTH_LOW;
+		next_rx_level = WLAN_SVC_TP_LOW;
 
-	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_rx_level
-								= next_rx_level;
+	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_rx_level =
+								next_rx_level;
 
 	if (hdd_ctx->cur_rx_level != next_rx_level) {
 		hddLog(CDF_TRACE_LEVEL_DEBUG,
@@ -3990,6 +3997,25 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *hdd_ctx,
 					    sizeof(next_rx_level));
 	}
 
+	/* fine-tuning parameters for TX Flows */
+	temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
+	hdd_ctx->prev_tx = tx_packets;
+	if (temp_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->cur_tx_level != next_tx_level) {
+		hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
+				next_tx_level, temp_tx);
+		hdd_ctx->cur_tx_level = next_tx_level;
+		wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_TX_IND,
+				&next_tx_level,
+				sizeof(next_tx_level));
+	}
+
+	hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_tx_level =
+								next_tx_level;
 	hdd_ctx->hdd_txrx_hist_idx++;
 	hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
 #endif
@@ -4097,18 +4123,19 @@ void wlan_hdd_display_tx_rx_histogram(hdd_context_t *hdd_ctx)
 		hdd_ctx->config->tcpDelackThresholdLow);
 #endif
 
-	hddLog(CDF_TRACE_LEVEL_ERROR, "index, total_rx, interval_rx,"
-		"total_tx, interval_tx, next_vote_level, next_rx_level");
+	hddLog(CDF_TRACE_LEVEL_ERROR,
+		"index, total_rx, interval_rx, total_tx, interval_tx, next_vote_level, next_rx_level, next_tx_level");
 
 	for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
 		hddLog(CDF_TRACE_LEVEL_ERROR,
-			"%d: %llu, %llu, %llu, %llu, %d, %d",
+			"%d: %llu, %llu, %llu, %llu, %d, %d, %d",
 			i, hdd_ctx->hdd_txrx_hist[i].total_rx,
 			hdd_ctx->hdd_txrx_hist[i].interval_rx,
 			hdd_ctx->hdd_txrx_hist[i].total_tx,
 			hdd_ctx->hdd_txrx_hist[i].interval_tx,
 			hdd_ctx->hdd_txrx_hist[i].next_vote_level,
-			hdd_ctx->hdd_txrx_hist[i].next_rx_level);
+			hdd_ctx->hdd_txrx_hist[i].next_rx_level,
+			hdd_ctx->hdd_txrx_hist[i].next_tx_level);
 	}
 	return;
 }
@@ -6158,6 +6185,7 @@ void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
 	case WLAN_SVC_DFS_RADAR_DETECT_IND:
 	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
 	case WLAN_SVC_WLAN_TP_IND:
+	case WLAN_SVC_WLAN_TP_TX_IND:
 		ani_hdr->length = len;
 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
 		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);

+ 21 - 1
core/utils/nlink/inc/wlan_nlink_common.h

@@ -79,7 +79,7 @@
 #define WLAN_SVC_WLAN_VERSION_IND   0x107
 #define WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND 0x108
 #define WLAN_SVC_WLAN_TP_IND        0x109
-
+#define WLAN_SVC_WLAN_TP_TX_IND     0x10B
 #define WLAN_SVC_MAX_SSID_LEN    32
 #define WLAN_SVC_MAX_BSSID_LEN   6
 #define WLAN_SVC_MAX_STR_LEN     16
@@ -136,4 +136,24 @@ struct wlan_dfs_info {
 	uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN];
 };
 
+/**
+ * enum wlan_tp_level - indicates wlan throughput level
+ * @WLAN_SVC_TP_NONE:	 used for initialization
+ * @WLAN_SVC_TP_LOW:	 used to identify low throughput level
+ * @WLAN_SVC_TP_MEDIUM:	 used to identify medium throughput level
+ * @WLAN_SVC_TP_HIGH:	 used to identify high throughput level
+ *
+ * The different throughput levels are determined on the basis of # of tx and
+ * rx packets and other threshold values. For example, if the # of total
+ * packets sent or received by the driver is greater than 500 in the last 100ms
+ * , the driver has a high throughput requirement. The driver may tweak certain
+ * system parameters based on the throughput level.
+ */
+enum wlan_tp_level {
+	WLAN_SVC_TP_NONE,
+	WLAN_SVC_TP_LOW,
+	WLAN_SVC_TP_MEDIUM,
+	WLAN_SVC_TP_HIGH,
+};
+
 #endif /* WLAN_NLINK_COMMON_H__ */