Commit 80d55154 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

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: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20210127055735.78599-4-nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 7aece471
This diff is collapsed.
...@@ -69,6 +69,8 @@ ...@@ -69,6 +69,8 @@
#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate) #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 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 minstrel_priv {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
...@@ -126,6 +128,13 @@ struct minstrel_rate_stats { ...@@ -126,6 +128,13 @@ struct minstrel_rate_stats {
bool retry_updated; 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 { struct minstrel_mcs_group_data {
u8 index; u8 index;
u8 column; u8 column;
...@@ -144,6 +153,12 @@ enum minstrel_sample_mode { ...@@ -144,6 +153,12 @@ enum minstrel_sample_mode {
MINSTREL_SAMPLE_PENDING, 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 minstrel_ht_sta {
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
...@@ -175,16 +190,14 @@ struct minstrel_ht_sta { ...@@ -175,16 +190,14 @@ struct minstrel_ht_sta {
/* tx flags to add for frames for this sta */ /* tx flags to add for frames for this sta */
u32 tx_flags; u32 tx_flags;
u8 sample_wait; unsigned long sample_time;
u8 sample_tries; struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
u8 sample_count;
u8 sample_seq;
enum minstrel_sample_mode sample_mode; enum minstrel_sample_mode sample_mode;
u16 sample_rate; u16 sample_rate;
/* current MCS group to be sampled */
u8 sample_group;
u8 band; u8 band;
/* Bitfield of supported MCS rates of all groups */ /* Bitfield of supported MCS rates of all groups */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment