While working on Tx aggregation I noticed that TCP streams will start stalling whenever MiRa decides to start sending frames at Tx rates which the AP tends to fail to receive. This means we're dropping far too many frames while trying to find an optimal Tx rate to use.
The problem can be observed with tcpbench falling into 0.0 Mbps occasionally and taking lots of time to recover. This problem disappeared when I hacked a fixed working Tx rate into the driver and disabled MiRa. So I took a closer look at MiRa again and measured percentage of good/bad MCS used for transmission. The diff below eliminates a lot of frames being sent at bad rates and results in more steady overall Tx performance while testing my WIP Tx aggregation code. I can my numbers by recording outgoing frame headers in pcap file while running tcpbench: tcpdump -n -i iwn0 -y IEEE802_11_RADIO -w /tmp/iwn.pcap Now I filter this pcap file by MCS index in wireshark, with an expression such as 'radiotap.mcs.index == 7', and look at the 'Displayed:' percentage in the bottom right corner of wireshark's window. Since I am knee-deep in Tx aggregation right now, I would like to delegate testing of the diff below against plain -current to the community. If some of you could test the diff below and report back to me I would appreciate it. You don't need to get numbers from wireshark for this if you don't want to. Letting me know if Tx is faster or not and whether there are any perceived regressions is sufficient. The drivers affected by this change are athn(4), iwn(4), and iwm(4). Don't bother testing with any other drivers. I have tested this diff with iwn(4) only so far. diff refs/heads/master refs/heads/txagg blob - 0d14daff4d1c8973b1d1180a9885a25c6754940b blob + 8a0f3b90198e9707ae08ef53aa4e68706ce2fa15 --- sys/net80211/ieee80211_mira.c +++ sys/net80211/ieee80211_mira.c @@ -510,6 +510,12 @@ ieee80211_mira_reset_driver_stats(struct ieee80211_mir /* Number of bytes which, alternatively, render a probe valid. */ #define IEEE80211_MIRA_MIN_PROBE_BYTES IEEE80211_MAX_LEN +/* Number of Tx failures which, alternatively, render a probe valid. */ +#define IEEE80211_MIRA_MAX_PROBE_TXFAIL 1 + +/* Number of Tx retries which, alternatively, render a probe valid. */ +#define IEEE80211_MIRA_MAX_PROBE_RETRIES 4 + int ieee80211_mira_next_lower_intra_rate(struct ieee80211_mira_node *mn, struct ieee80211_node *ni) @@ -719,7 +725,9 @@ ieee80211_mira_probe_valid(struct ieee80211_mira_node struct ieee80211_mira_goodput_stats *g = &mn->g[ni->ni_txmcs]; return (g->nprobes >= IEEE80211_MIRA_MIN_PROBE_FRAMES || - g->nprobe_bytes >= IEEE80211_MIRA_MIN_PROBE_BYTES); + g->nprobe_bytes >= IEEE80211_MIRA_MIN_PROBE_BYTES || + mn->txfail >= IEEE80211_MIRA_MAX_PROBE_TXFAIL || + mn->retries >= IEEE80211_MIRA_MAX_PROBE_RETRIES); } void