mac80211: minstrel_ht: significantly redesign the rate probing strategy

The biggest flaw in current minstrel_ht is the fact that it needs way too
many probing packets to be able to quickly find the best rate.
Depending on the wifi hardware and operating mode, this can significantly
reduce throughput when not operating at the highest available data rate.

In order to be able to significantly reduce the amount of rate sampling,
we need a much smarter selection of probing rates.

The new approach introduced by this patch maintains a limited set of
available rates to be tested during a statistics window.

They are split into distinct categories:
- MINSTREL_SAMPLE_TYPE_INC - incremental rate upgrade:
  Pick the next rate group and find the first rate that is faster than
  the current max. throughput rate
- MINSTREL_SAMPLE_TYPE_JUMP - random testing of higher rates:
  Pick a random rate from the next group that is faster than the current
  max throughput rate. This allows faster adaptation when the link changes
  significantly
- MINSTREL_SAMPLE_TYPE_SLOW - test a rate between max_prob, max_tp2 and
  max_tp in order to reduce the gap between them

In order to prioritize sampling, every 6 attempts are split into 3x INC,
2x JUMP, 1x SLOW.

Available rates are checked and refilled on every stats window update.

With this approach, we finally get a very small delta in throughput when
comparing setting the optimal data rate as a fixed rate vs normal rate
control operation.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20210127055735.78599-4-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Felix Fietkau
2021-01-27 06:57:33 +01:00
committed by Johannes Berg
parent 7aece471a0
commit 80d55154b2
2 changed files with 336 additions and 239 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -69,6 +69,8 @@
#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate)
#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate)
#define MINSTREL_SAMPLE_RATES 5 /* rates per sample type */
#define MINSTREL_SAMPLE_INTERVAL (HZ / 50)
struct minstrel_priv {
struct ieee80211_hw *hw;
@@ -126,6 +128,13 @@ struct minstrel_rate_stats {
bool retry_updated;
};
enum minstrel_sample_type {
MINSTREL_SAMPLE_TYPE_INC,
MINSTREL_SAMPLE_TYPE_JUMP,
MINSTREL_SAMPLE_TYPE_SLOW,
__MINSTREL_SAMPLE_TYPE_MAX
};
struct minstrel_mcs_group_data {
u8 index;
u8 column;
@@ -144,6 +153,12 @@ enum minstrel_sample_mode {
MINSTREL_SAMPLE_PENDING,
};
struct minstrel_sample_category {
u8 sample_group;
u16 sample_rates[MINSTREL_SAMPLE_RATES];
u16 cur_sample_rates[MINSTREL_SAMPLE_RATES];
};
struct minstrel_ht_sta {
struct ieee80211_sta *sta;
@@ -175,16 +190,14 @@ struct minstrel_ht_sta {
/* tx flags to add for frames for this sta */
u32 tx_flags;
u8 sample_wait;
u8 sample_tries;
u8 sample_count;
unsigned long sample_time;
struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
u8 sample_seq;
enum minstrel_sample_mode sample_mode;
u16 sample_rate;
/* current MCS group to be sampled */
u8 sample_group;
u8 band;
/* Bitfield of supported MCS rates of all groups */