aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch132
1 files changed, 0 insertions, 132 deletions
diff --git a/package/kernel/mac80211/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch b/package/kernel/mac80211/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch
deleted file mode 100644
index 037ab8e180..0000000000
--- a/package/kernel/mac80211/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 28 May 2022 16:44:53 +0200
-Subject: [PATCH] mac80211: fix overflow issues in airtime fairness code
-
-The airtime weight calculation overflows with a default weight value of 256
-whenever more than 8ms worth of airtime is reported.
-Bigger weight values impose even smaller limits on maximum airtime values.
-This can mess up airtime based calculations for drivers that don't report
-per-PPDU airtime values, but batch up values instead.
-
-Fix this by reordering multiplications/shifts and by reducing unnecessary
-intermediate precision (which was lost in a later stage anyway).
-
-The new shift value limits the maximum weight to 4096, which should be more
-than enough. Any values bigger than that will be clamped to the upper limit.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1666,50 +1666,34 @@ static inline struct airtime_info *to_ai
- /* To avoid divisions in the fast path, we keep pre-computed reciprocals for
- * airtime weight calculations. There are two different weights to keep track
- * of: The per-station weight and the sum of weights per phy.
-- *
-- * For the per-station weights (kept in airtime_info below), we use 32-bit
-- * reciprocals with a devisor of 2^19. This lets us keep the multiplications and
-- * divisions for the station weights as 32-bit operations at the cost of a bit
-- * of rounding error for high weights; but the choice of divisor keeps rounding
-- * errors <10% for weights <2^15, assuming no more than 8ms of airtime is
-- * reported at a time.
-- *
-- * For the per-phy sum of weights the values can get higher, so we use 64-bit
-- * operations for those with a 32-bit divisor, which should avoid any
-- * significant rounding errors.
-+ * The per-sta shift value supports weight values of 1-4096
- */
--#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL
--#define IEEE80211_RECIPROCAL_SHIFT_64 32
--#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U
--#define IEEE80211_RECIPROCAL_SHIFT_32 19
-+#define IEEE80211_RECIPROCAL_SHIFT_SUM 24
-+#define IEEE80211_RECIPROCAL_SHIFT_STA 12
-+#define IEEE80211_WEIGHT_SHIFT 8
-
--static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight)
-+static inline void airtime_weight_set(struct airtime_info *air_info, u32 weight)
- {
-+ weight = min_t(u32, weight, BIT(IEEE80211_RECIPROCAL_SHIFT_STA));
- if (air_info->weight == weight)
- return;
-
- air_info->weight = weight;
-- if (weight) {
-- air_info->weight_reciprocal =
-- IEEE80211_RECIPROCAL_DIVISOR_32 / weight;
-- } else {
-- air_info->weight_reciprocal = 0;
-- }
-+ if (weight)
-+ weight = BIT(IEEE80211_RECIPROCAL_SHIFT_STA) / weight;
-+ air_info->weight_reciprocal = weight;
- }
-
- static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched,
-- int weight_sum)
-+ u32 weight_sum)
- {
- if (air_sched->weight_sum == weight_sum)
- return;
-
- air_sched->weight_sum = weight_sum;
-- if (air_sched->weight_sum) {
-- air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64;
-- do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum);
-- } else {
-- air_sched->weight_sum_reciprocal = 0;
-- }
-+ if (weight_sum)
-+ weight_sum = BIT(IEEE80211_RECIPROCAL_SHIFT_SUM) / weight_sum;
-+ air_sched->weight_sum_reciprocal = weight_sum;
- }
-
- /* A problem when trying to enforce airtime fairness is that we want to divide
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -1894,9 +1894,9 @@ void ieee80211_register_airtime(struct i
- {
- struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
- struct ieee80211_local *local = sdata->local;
-- u64 weight_sum, weight_sum_reciprocal;
- struct airtime_sched_info *air_sched;
- struct airtime_info *air_info;
-+ u64 weight_sum_reciprocal;
- u32 airtime = 0;
-
- air_sched = &local->airtime[txq->ac];
-@@ -1907,27 +1907,21 @@ void ieee80211_register_airtime(struct i
- if (local->airtime_flags & AIRTIME_USE_RX)
- airtime += rx_airtime;
-
-- /* Weights scale so the unit weight is 256 */
-- airtime <<= 8;
--
- spin_lock_bh(&air_sched->lock);
-
- air_info->tx_airtime += tx_airtime;
- air_info->rx_airtime += rx_airtime;
-
-- if (air_sched->weight_sum) {
-- weight_sum = air_sched->weight_sum;
-+ if (air_sched->weight_sum)
- weight_sum_reciprocal = air_sched->weight_sum_reciprocal;
-- } else {
-- weight_sum = air_info->weight;
-+ else
- weight_sum_reciprocal = air_info->weight_reciprocal;
-- }
-
- /* Round the calculation of global vt */
-- air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) *
-- weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64;
-- air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) *
-- air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32;
-+ air_sched->v_t += ((u64)airtime * weight_sum_reciprocal) >>
-+ (IEEE80211_RECIPROCAL_SHIFT_SUM - IEEE80211_WEIGHT_SHIFT);
-+ air_info->v_t += (airtime * air_info->weight_reciprocal) >>
-+ (IEEE80211_RECIPROCAL_SHIFT_STA - IEEE80211_WEIGHT_SHIFT);
- ieee80211_resort_txq(&local->hw, txq);
-
- spin_unlock_bh(&air_sched->lock);