Lets make wifi fast again!
 help / color / mirror / Atom feed
* [Make-wifi-fast] [PATCH v2 1/2] iw: Print TXQ statistics for stations and interfaces
@ 2018-05-08 11:22 Toke Høiland-Jørgensen
  2018-05-08 11:22 ` [Make-wifi-fast] [PATCH v2 2/2] iw: Add getting and setting of TXQ params for phy Toke Høiland-Jørgensen
  0 siblings, 1 reply; 2+ messages in thread
From: Toke Høiland-Jørgensen @ 2018-05-08 11:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: make-wifi-fast

This adds printing of TXQ statistics for stations and interfaces when
supplied by the kernel. For stations, another section is added when verbose
mode is enabled; for interfaces, the multicast queue information is always
printed when available.

This is the information also available through debugfs in
/sys/kernel/debug/ieee80211/phyX/netdev:Y/aqm and
/sys/kernel/debug/ieee80211/phyX/netdev:Y/stations/*/aqm.

Sample output:

$ iw dev wlp2s0 station dump -v
Station xx:xx:xx:xx:xx:xx (on wlp2s0)
[...]
	TXQs:
		TID	qsz-byt	qsz-pkt	flows	drops	marks	overlmt	hashcol	tx-bytes	tx-packets
		0	0	0	0	0	0	0	0	0		0
		1	0	0	0	0	0	0	0	0		0
		2	0	0	0	0	0	0	0	0		0
		3	0	0	0	0	0	0	0	0		0
		4	0	0	0	0	0	0	0	0		0
		5	0	0	0	0	0	0	0	0		0
		6	0	0	0	0	0	0	0	0		0
		7	0	0	0	0	0	0	0	0		0
		8	0	0	0	0	0	0	0	0		0
		9	0	0	0	0	0	0	0	0		0
		10	0	0	0	0	0	0	0	0		0
		11	0	0	0	0	0	0	0	0		0
		12	0	0	0	0	0	0	0	0		0
		13	0	0	0	0	0	0	0	0		0
		14	0	0	0	0	0	0	0	0		0
		15	0	0	0	0	0	0	0	0		0
[...]

$ iw dev wlp2s0 info
Interface wlp2s0
	ifindex 9
	wdev 0x1
	addr xx:xx:xx:xx:xx:xx
	type AP
	wiphy 0
	channel 165 (5825 MHz), width: 20 MHz, center1: 5825 MHz
	txpower 24.00 dBm
	multicast TXQ:
		qsz-byt	qsz-pkt	flows	drops	marks	overlmt	hashcol	tx-bytes	tx-packets
		0	0	72	0	0	0	0	7380		72

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
---
 interface.c |    6 +++++
 iw.h        |    2 ++
 station.c   |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/interface.c b/interface.c
index a19c83f..712bbdc 100644
--- a/interface.c
+++ b/interface.c
@@ -441,6 +441,12 @@ static int print_iface_handler(struct nl_msg *msg, void *arg)
 		       indent, txp / 100, txp % 100);
 	}
 
+	if (tb_msg[NL80211_ATTR_TXQ_STATS]) {
+		char buf[150];
+		parse_txq_stats(buf, sizeof(buf), tb_msg[NL80211_ATTR_TXQ_STATS], 1, -1, indent);
+		printf("%s\tmulticast TXQ:%s\n", indent, buf);
+	}
+
 	return NL_SKIP;
 }
 
diff --git a/iw.h b/iw.h
index ee7ca20..47aa27d 100644
--- a/iw.h
+++ b/iw.h
@@ -183,6 +183,8 @@ unsigned char *parse_hex(char *hex, size_t *outlen);
 int parse_keys(struct nl_msg *msg, char **argv, int argc);
 int parse_freqchan(struct chandef *chandef, bool chan, int argc, char **argv, int *parsed);
 enum nl80211_chan_width str_to_bw(const char *str);
+int parse_txq_stats(char *buf, int buflen, struct nlattr *tid_stats_attr, int header,
+		    int tid, const char *indent);
 int put_chandef(struct nl_msg *msg, struct chandef *chandef);
 
 void print_ht_mcs(const __u8 *mcs);
diff --git a/station.c b/station.c
index 4885dc0..38c5f91 100644
--- a/station.c
+++ b/station.c
@@ -43,6 +43,62 @@ static void print_power_mode(struct nlattr *a)
 	}
 }
 
+int parse_txq_stats(char *buf, int buflen, struct nlattr *tid_stats_attr, int header,
+		    int tid, const char *indent)
+{
+	struct nlattr *txqstats_info[NL80211_TXQ_STATS_MAX + 1], *txqinfo;
+	static struct nla_policy txqstats_policy[NL80211_TXQ_STATS_MAX + 1] = {
+		[NL80211_TXQ_STATS_BACKLOG_BYTES] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_BACKLOG_PACKETS] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_FLOWS] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_DROPS] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_ECN_MARKS] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_OVERLIMIT] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_COLLISIONS] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_TX_BYTES] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_TX_PACKETS] = { .type = NLA_U32 },
+	};
+	char *pos = buf;
+	if (nla_parse_nested(txqstats_info, NL80211_TXQ_STATS_MAX, tid_stats_attr,
+			     txqstats_policy)) {
+		printf("failed to parse nested TXQ stats attributes!");
+		return 0;
+	}
+
+	if (header)
+		pos += snprintf(buf, buflen, "\n%s\t%s\tqsz-byt\t"
+				"qsz-pkt\tflows\tdrops\tmarks\toverlmt\t"
+				"hashcol\ttx-bytes\ttx-packets", indent,
+				tid >= 0 ? "TID" : "");
+
+	pos += snprintf(pos, buflen - (pos - buf), "\n%s\t", indent);
+	if (tid >= 0)
+		pos += snprintf(pos, buflen - (pos - buf), "%d", tid);
+
+#define PRINT_STAT(key, spacer) do {					 \
+		txqinfo = txqstats_info[NL80211_TXQ_STATS_ ## key];	 \
+		pos += snprintf(pos, buflen - (pos - buf), spacer);	 \
+		if (txqinfo)						 \
+			pos += snprintf(pos, buflen - (pos - buf), "%u", \
+					nla_get_u32(txqinfo));		 \
+	} while (0)
+
+
+	PRINT_STAT(BACKLOG_BYTES, "\t");
+	PRINT_STAT(BACKLOG_PACKETS, "\t");
+	PRINT_STAT(FLOWS, "\t");
+	PRINT_STAT(DROPS, "\t");
+	PRINT_STAT(ECN_MARKS, "\t");
+	PRINT_STAT(OVERLIMIT, "\t");
+	PRINT_STAT(COLLISIONS, "\t");
+	PRINT_STAT(TX_BYTES, "\t");
+	PRINT_STAT(TX_PACKETS, "\t\t");
+
+#undef PRINT_STAT
+
+	return pos - buf;
+
+}
 void parse_tid_stats(struct nlattr *tid_stats_attr)
 {
 	struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1], *tidattr, *info;
@@ -51,8 +107,11 @@ void parse_tid_stats(struct nlattr *tid_stats_attr)
 		[NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
 		[NL80211_TID_STATS_TX_MSDU_RETRIES] = { .type = NLA_U64 },
 		[NL80211_TID_STATS_TX_MSDU_FAILED] = { .type = NLA_U64 },
+		[NL80211_TID_STATS_TXQ_STATS] = { .type = NLA_NESTED },
 	};
 	int rem, i = 0;
+	char txqbuf[2000] = {}, *pos = txqbuf;
+	int buflen = sizeof(txqbuf), foundtxq = 0;
 
 	printf("\n\tMSDU:\n\t\tTID\trx\ttx\ttx retries\ttx failed");
 	nla_for_each_nested(tidattr, tid_stats_attr, rem) {
@@ -61,7 +120,7 @@ void parse_tid_stats(struct nlattr *tid_stats_attr)
 			printf("failed to parse nested stats attributes!");
 			return;
 		}
-		printf("\n\t\t%d", i++);
+		printf("\n\t\t%d", i);
 		info = stats_info[NL80211_TID_STATS_RX_MSDU];
 		if (info)
 			printf("\t%llu", (unsigned long long)nla_get_u64(info));
@@ -74,7 +133,17 @@ void parse_tid_stats(struct nlattr *tid_stats_attr)
 		info = stats_info[NL80211_TID_STATS_TX_MSDU_FAILED];
 		if (info)
 			printf("\t\t%llu", (unsigned long long)nla_get_u64(info));
+		info = stats_info[NL80211_TID_STATS_TXQ_STATS];
+		if (info) {
+			pos += parse_txq_stats(pos, buflen - (pos - txqbuf), info, !foundtxq, i, "\t");
+			foundtxq = 1;
+		}
+
+		i++;
 	}
+
+	if (foundtxq)
+		printf("\n\tTXQs:%s", txqbuf);
 }
 
 void parse_bss_param(struct nlattr *bss_param_attr)


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Make-wifi-fast] [PATCH v2 2/2] iw: Add getting and setting of TXQ params for phy
  2018-05-08 11:22 [Make-wifi-fast] [PATCH v2 1/2] iw: Print TXQ statistics for stations and interfaces Toke Høiland-Jørgensen
@ 2018-05-08 11:22 ` Toke Høiland-Jørgensen
  0 siblings, 0 replies; 2+ messages in thread
From: Toke Høiland-Jørgensen @ 2018-05-08 11:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: make-wifi-fast

This adds commands to get and set the per-phy TXQ parameters for drivers
that use the intermediate TXQs. These are the settings and statistics that
are also available through /sys/kernel/debug/ieee80211/phyX/aqm.

Sample output:

$ iw phy phy0 get txq
Packet limit:		8192 pkts
Memory limit:		4194304 bytes
Quantum:		300 bytes
Number of queues:	4096
Backlog:		12 pkts
Memory usage:		52224 bytes
Packet limit overflows:	0
Memory limit overflows:	0
Hash collisions:	1

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
---
 info.c |    2 +
 phy.c  |  116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+)

diff --git a/info.c b/info.c
index be68571..fbf3ee0 100644
--- a/info.c
+++ b/info.c
@@ -686,6 +686,8 @@ broken_combination:
 		ext_feat_print(tb, NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
 			       "CONTROL_PORT_OVER_NL80211",
 			       "control port over nl80211");
+		ext_feat_print(tb, NL80211_EXT_FEATURE_TXQS,
+			       "TXQS", "FQ-CoDel-enabled intermediate TXQs");
 	}
 
 	if (tb_msg[NL80211_ATTR_COALESCE_RULE]) {
diff --git a/phy.c b/phy.c
index be31820..77df7a7 100644
--- a/phy.c
+++ b/phy.c
@@ -727,3 +727,119 @@ COMMAND(set, antenna, "<bitmap> | all | <tx bitmap> <rx bitmap>",
 	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna,
 	"Set a bitmap of allowed antennas to use for TX and RX.\n"
 	"The driver may reject antenna configurations it cannot support.");
+
+static int handle_set_txq(struct nl80211_state *state,
+			  struct nl_msg *msg,
+			  int argc, char **argv,
+			  enum id_input id)
+{
+	unsigned int argval;
+	char *end;
+
+	if (argc != 2)
+		return 1;
+
+	if (!*argv[0] || !*argv[1])
+		return 1;
+
+	argval = strtoul(argv[1], &end, 10);
+
+	if (*end)
+		return 1;
+
+	if (!argval)
+		return 1;
+
+	if (strcmp("limit", argv[0]) == 0)
+		NLA_PUT_U32(msg, NL80211_ATTR_TXQ_LIMIT, argval);
+	else if (strcmp("memory_limit", argv[0]) == 0)
+		NLA_PUT_U32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT, argval);
+	else if (strcmp("quantum", argv[0]) == 0)
+		NLA_PUT_U32(msg, NL80211_ATTR_TXQ_QUANTUM, argval);
+	else
+		return -1;
+
+	return 0;
+ nla_put_failure:
+	return -ENOBUFS;
+}
+COMMAND(set, txq, "limit <packets> | memory_limit <bytes> | quantum <bytes>",
+	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_set_txq,
+	"Set TXQ parameters. The limit and memory_limit are global queue limits\n"
+	"for the whole phy. The quantum is the DRR scheduler quantum setting.\n"
+	"Valid values: 1 - 2**32");
+
+static int print_txq_handler(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *attrs[NL80211_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct nlattr *txqstats_info[NL80211_TXQ_STATS_MAX + 1], *txqinfo;
+	static struct nla_policy txqstats_policy[NL80211_TXQ_STATS_MAX + 1] = {
+		[NL80211_TXQ_STATS_BACKLOG_PACKETS] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_BACKLOG_BYTES] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_OVERLIMIT] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_OVERMEMORY] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_COLLISIONS] = { .type = NLA_U32 },
+		[NL80211_TXQ_STATS_MAX_FLOWS] = { .type = NLA_U32 },
+	};
+
+	nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+
+	if (attrs[NL80211_ATTR_TXQ_LIMIT])
+		printf("Packet limit:\t\t%u pkts\n",
+			nla_get_u32(attrs[NL80211_ATTR_TXQ_LIMIT]));
+	if (attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT])
+		printf("Memory limit:\t\t%u bytes\n",
+			nla_get_u32(attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]));
+	if (attrs[NL80211_ATTR_TXQ_QUANTUM])
+		printf("Quantum:\t\t%u bytes\n",
+			nla_get_u32(attrs[NL80211_ATTR_TXQ_QUANTUM]));
+
+	if (attrs[NL80211_ATTR_TXQ_STATS]) {
+		if (nla_parse_nested(txqstats_info, NL80211_TXQ_STATS_MAX,
+				     attrs[NL80211_ATTR_TXQ_STATS],
+				     txqstats_policy)) {
+			printf("failed to parse nested TXQ stats attributes!");
+			return 0;
+		}
+		txqinfo = txqstats_info[NL80211_TXQ_STATS_MAX_FLOWS];
+		if (txqinfo)
+			printf("Number of queues:\t%u\n", nla_get_u32(txqinfo));
+
+		txqinfo = txqstats_info[NL80211_TXQ_STATS_BACKLOG_PACKETS];
+		if (txqinfo)
+			printf("Backlog:\t\t%u pkts\n", nla_get_u32(txqinfo));
+
+		txqinfo = txqstats_info[NL80211_TXQ_STATS_BACKLOG_BYTES];
+		if (txqinfo)
+			printf("Memory usage:\t\t%u bytes\n", nla_get_u32(txqinfo));
+
+		txqinfo = txqstats_info[NL80211_TXQ_STATS_OVERLIMIT];
+		if (txqinfo)
+			printf("Packet limit overflows:\t%u\n", nla_get_u32(txqinfo));
+
+		txqinfo = txqstats_info[NL80211_TXQ_STATS_OVERMEMORY];
+		if (txqinfo)
+			printf("Memory limit overflows:\t%u\n", nla_get_u32(txqinfo));
+		txqinfo = txqstats_info[NL80211_TXQ_STATS_COLLISIONS];
+		if (txqinfo)
+			printf("Hash collisions:\t%u\n", nla_get_u32(txqinfo));
+	}
+	return NL_SKIP;
+}
+
+static int handle_get_txq(struct nl80211_state *state,
+			  struct nl_msg *msg,
+			  int argc, char **argv,
+			  enum id_input id)
+{
+	nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
+	nlmsg_hdr(msg)->nlmsg_flags |= NLM_F_DUMP;
+	register_handler(print_txq_handler, NULL);
+	return 0;
+}
+COMMAND(get, txq, "",
+	NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_get_txq,
+	"Get TXQ parameters.");


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-05-08 11:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-08 11:22 [Make-wifi-fast] [PATCH v2 1/2] iw: Print TXQ statistics for stations and interfaces Toke Høiland-Jørgensen
2018-05-08 11:22 ` [Make-wifi-fast] [PATCH v2 2/2] iw: Add getting and setting of TXQ params for phy Toke Høiland-Jørgensen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox