aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2020-01-13 19:38:55 +0100
committerFelix Fietkau <nbd@nbd.name>2020-01-14 14:56:46 +0100
commitfe1818cdbc70331228506a543a9a6ac50cb90018 (patch)
tree6cc82cad6afe7898a7a62cd55abf66081ec3257a /package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch
parente845c094d5c9d6afbb1ab3f0815d6ed546b9d429 (diff)
downloadupstream-fe1818cdbc70331228506a543a9a6ac50cb90018.tar.gz
upstream-fe1818cdbc70331228506a543a9a6ac50cb90018.tar.bz2
upstream-fe1818cdbc70331228506a543a9a6ac50cb90018.zip
mac80211: renumber subsys patches accepted upstream
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch235
1 files changed, 0 insertions, 235 deletions
diff --git a/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch b/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch
deleted file mode 100644
index bce9e75378..0000000000
--- a/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch
+++ /dev/null
@@ -1,235 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 28 Sep 2019 15:46:06 +0200
-Subject: [PATCH] mac80211: minstrel_ht: replace rate stats ewma with a
- better moving average
-
-Rate success probability usually fluctuates a lot under normal conditions.
-With a simple EWMA, noise and fluctuation can be reduced by increasing the
-window length, but that comes at the cost of introducing lag on sudden
-changes.
-
-This change replaces the EWMA implementation with a moving average that's
-designed to significantly reduce lag while keeping a bigger window size
-by being better at filtering out noise.
-
-It is only slightly more expensive than the simple EWMA and still avoids
-divisions in its calculation.
-
-The algorithm is adapted from an implementation intended for a completely
-different field (stock market trading), where the tradeoff of lag vs
-noise filtering is equally important.
-
-The algorithm works in the same way as the "smoothing filter" from
-http://www.stockspotter.com/files/PredictiveIndicators.pdf adapted for
-fixed-point math with some constants, using only addition, bit shifts
-and multiplication
-
-To better make use of the filtering and bigger window size, the update
-interval is cut in half.
-
-For testing, the algorithm can be reverted to the older one via debugfs
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/rc80211_minstrel.c
-+++ b/net/mac80211/rc80211_minstrel.c
-@@ -157,14 +157,18 @@ minstrel_update_rates(struct minstrel_pr
- * Recalculate statistics and counters of a given rate
- */
- void
--minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
-+minstrel_calc_rate_stats(struct minstrel_priv *mp,
-+ struct minstrel_rate_stats *mrs)
- {
- unsigned int cur_prob;
-
- if (unlikely(mrs->attempts > 0)) {
- mrs->sample_skipped = 0;
- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
-- if (unlikely(!mrs->att_hist)) {
-+ if (mp->new_avg) {
-+ mrs->prob_ewma = minstrel_filter_avg_add(&mrs->avg,
-+ cur_prob);
-+ } else if (unlikely(!mrs->att_hist)) {
- mrs->prob_ewma = cur_prob;
- } else {
- /*update exponential weighted moving avarage */
-@@ -200,7 +204,7 @@ minstrel_update_stats(struct minstrel_pr
- struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats;
-
- /* Update statistics of success probability per rate */
-- minstrel_calc_rate_stats(mrs);
-+ minstrel_calc_rate_stats(mp, mrs);
-
- /* Sample less often below the 10% chance of success.
- * Sample less often above the 95% chance of success. */
-@@ -289,7 +293,8 @@ minstrel_tx_status(void *priv, struct ie
- if (mi->sample_deferred > 0)
- mi->sample_deferred--;
-
-- if (time_after(jiffies, mi->last_stats_update + mp->update_interval))
-+ if (time_after(jiffies, mi->last_stats_update +
-+ mp->update_interval / (mp->new_avg ? 2 : 1)))
- minstrel_update_stats(mp, mi);
- }
-
---- a/net/mac80211/rc80211_minstrel.h
-+++ b/net/mac80211/rc80211_minstrel.h
-@@ -19,6 +19,21 @@
- #define MAX_THR_RATES 4
-
- /*
-+ * Coefficients for moving average with noise filter (period=16),
-+ * scaled by 10 bits
-+ *
-+ * a1 = exp(-pi * sqrt(2) / period)
-+ * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period)
-+ * coeff3 = -sqr(a1)
-+ * coeff1 = 1 - coeff2 - coeff3
-+ */
-+#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \
-+ MINSTREL_AVG_COEFF2 - \
-+ MINSTREL_AVG_COEFF3)
-+#define MINSTREL_AVG_COEFF2 0x00001499
-+#define MINSTREL_AVG_COEFF3 -0x0000092e
-+
-+/*
- * Perform EWMA (Exponentially Weighted Moving Average) calculation
- */
- static inline int
-@@ -32,6 +47,41 @@ minstrel_ewma(int old, int new, int weig
- return old + incr;
- }
-
-+struct minstrel_avg_ctx {
-+ s32 prev[2];
-+};
-+
-+static inline int minstrel_filter_avg_add(struct minstrel_avg_ctx *ctx, s32 in)
-+{
-+ s32 out_1 = ctx->prev[0];
-+ s32 out_2 = ctx->prev[1];
-+ s32 val;
-+
-+ if (!in)
-+ in += 1;
-+
-+ if (!out_1) {
-+ val = out_1 = in;
-+ goto out;
-+ }
-+
-+ val = MINSTREL_AVG_COEFF1 * in;
-+ val += MINSTREL_AVG_COEFF2 * out_1;
-+ val += MINSTREL_AVG_COEFF3 * out_2;
-+ val >>= MINSTREL_SCALE;
-+
-+ if (val > 1 << MINSTREL_SCALE)
-+ val = 1 << MINSTREL_SCALE;
-+ if (val < 0)
-+ val = 1;
-+
-+out:
-+ ctx->prev[1] = out_1;
-+ ctx->prev[0] = val;
-+
-+ return val;
-+}
-+
- struct minstrel_rate_stats {
- /* current / last sampling period attempts/success counters */
- u16 attempts, last_attempts;
-@@ -40,6 +90,8 @@ struct minstrel_rate_stats {
- /* total attempts/success counters */
- u32 att_hist, succ_hist;
-
-+ struct minstrel_avg_ctx avg;
-+
- /* prob_ewma - exponential weighted moving average of prob */
- u16 prob_ewma;
-
-@@ -95,6 +147,7 @@ struct minstrel_sta_info {
- struct minstrel_priv {
- struct ieee80211_hw *hw;
- bool has_mrr;
-+ bool new_avg;
- u32 sample_switch;
- unsigned int cw_min;
- unsigned int cw_max;
-@@ -126,7 +179,8 @@ extern const struct rate_control_ops mac
- void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
-
- /* Recalculate success probabilities and counters for a given rate using EWMA */
--void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs);
-+void minstrel_calc_rate_stats(struct minstrel_priv *mp,
-+ struct minstrel_rate_stats *mrs);
- int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma);
-
- /* debugfs */
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -737,7 +737,7 @@ minstrel_ht_update_stats(struct minstrel
-
- mrs = &mg->rates[i];
- mrs->retry_updated = false;
-- minstrel_calc_rate_stats(mrs);
-+ minstrel_calc_rate_stats(mp, mrs);
- cur_prob = mrs->prob_ewma;
-
- if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
-@@ -773,6 +773,8 @@ minstrel_ht_update_stats(struct minstrel
-
- /* try to sample all available rates during each interval */
- mi->sample_count *= 8;
-+ if (mp->new_avg)
-+ mi->sample_count /= 2;
-
- if (sample)
- minstrel_ht_rate_sample_switch(mp, mi);
-@@ -889,6 +891,7 @@ minstrel_ht_tx_status(void *priv, struct
- struct ieee80211_tx_rate *ar = info->status.rates;
- struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL;
- struct minstrel_priv *mp = priv;
-+ u32 update_interval = mp->update_interval / 2;
- bool last, update = false;
- bool sample_status = false;
- int i;
-@@ -943,6 +946,10 @@ minstrel_ht_tx_status(void *priv, struct
-
- switch (mi->sample_mode) {
- case MINSTREL_SAMPLE_IDLE:
-+ if (mp->new_avg &&
-+ (mp->hw->max_rates > 1 ||
-+ mi->total_packets_cur < SAMPLE_SWITCH_THR))
-+ update_interval /= 2;
- break;
-
- case MINSTREL_SAMPLE_ACTIVE:
-@@ -983,8 +990,7 @@ minstrel_ht_tx_status(void *priv, struct
- }
- }
-
-- if (time_after(jiffies, mi->last_stats_update +
-- mp->update_interval / 2)) {
-+ if (time_after(jiffies, mi->last_stats_update + update_interval)) {
- update = true;
- minstrel_ht_update_stats(mp, mi, true);
- }
-@@ -1665,6 +1671,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
-
- mp->hw = hw;
- mp->update_interval = HZ / 10;
-+ mp->new_avg = true;
-
- #ifdef CPTCFG_MAC80211_DEBUGFS
- mp->fixed_rate_idx = (u32) -1;
-@@ -1672,6 +1679,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h
- &mp->fixed_rate_idx);
- debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir,
- &mp->sample_switch);
-+ debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir,
-+ &mp->new_avg);
- #endif
-
- minstrel_ht_init_cck_rates(mp);