Fresh pull from upstream
[librecmc/librecmc.git] / package / kernel / mac80211 / patches / 340-mac80211-minstrel-store-probability-variance-instead.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Wed, 14 Dec 2016 20:17:06 +0100
3 Subject: [PATCH] mac80211: minstrel: store probability variance instead of
4  standard deviation
5
6 This avoids the costly int_sqrt calls in the statistics update and moves
7 it to the debugfs code instead.
8 This also fixes an overflow in the previous standard deviation
9 calculation.
10
11 Signed-off-by: Thomas Huehn <thomas.huehn@evernet-eg.de>
12 Signed-off-by: Felix Fietkau <nbd@nbd.name>
13 ---
14
15 --- a/net/mac80211/rc80211_minstrel.c
16 +++ b/net/mac80211/rc80211_minstrel.c
17 @@ -168,10 +168,10 @@ minstrel_calc_rate_stats(struct minstrel
18                         mrs->prob_ewma = cur_prob;
19                 } else {
20                         /* update exponential weighted moving variance */
21 -                       mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd,
22 -                                                        cur_prob,
23 -                                                        mrs->prob_ewma,
24 -                                                        EWMA_LEVEL);
25 +                       mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv,
26 +                                                       cur_prob,
27 +                                                       mrs->prob_ewma,
28 +                                                       EWMA_LEVEL);
29  
30                         /*update exponential weighted moving avarage */
31                         mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
32 --- a/net/mac80211/rc80211_minstrel.h
33 +++ b/net/mac80211/rc80211_minstrel.h
34 @@ -36,21 +36,16 @@ minstrel_ewma(int old, int new, int weig
35  }
36  
37  /*
38 - * Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation
39 + * Perform EWMV (Exponentially Weighted Moving Variance) calculation
40   */
41  static inline int
42 -minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight)
43 +minstrel_ewmv(int old_ewmv, int cur_prob, int prob_ewma, int weight)
44  {
45 -       int diff, incr, tmp_var;
46 +       int diff, incr;
47  
48 -       /* calculate exponential weighted moving variance */
49 -       diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 1000000);
50 +       diff = cur_prob - prob_ewma;
51         incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
52 -       tmp_var = old_ewmsd * old_ewmsd;
53 -       tmp_var = weight * (tmp_var + diff * incr / 1000000) / EWMA_DIV;
54 -
55 -       /* return standard deviation */
56 -       return (u16) int_sqrt(tmp_var);
57 +       return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV;
58  }
59  
60  struct minstrel_rate_stats {
61 @@ -65,7 +60,7 @@ struct minstrel_rate_stats {
62          *  prob_ewma - exponential weighted moving average of prob
63          *  prob_ewmsd - exp. weighted moving standard deviation of prob */
64         unsigned int prob_ewma;
65 -       u16 prob_ewmsd;
66 +       u16 prob_ewmv;
67  
68         /* maximum retry counts */
69         u8 retry_count;
70 @@ -151,6 +146,14 @@ struct minstrel_debugfs_info {
71         char buf[];
72  };
73  
74 +/* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */
75 +static inline int
76 +minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs)
77 +{
78 +       unsigned int ewmv = mrs->prob_ewmv;
79 +       return int_sqrt(MINSTREL_TRUNC(ewmv * 1000 * 1000));
80 +}
81 +
82  extern const struct rate_control_ops mac80211_minstrel;
83  void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
84  void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
85 --- a/net/mac80211/rc80211_minstrel_debugfs.c
86 +++ b/net/mac80211/rc80211_minstrel_debugfs.c
87 @@ -93,6 +93,7 @@ minstrel_stats_open(struct inode *inode,
88         for (i = 0; i < mi->n_rates; i++) {
89                 struct minstrel_rate *mr = &mi->r[i];
90                 struct minstrel_rate_stats *mrs = &mi->r[i].stats;
91 +               unsigned int prob_ewmsd;
92  
93                 *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
94                 *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
95 @@ -108,6 +109,7 @@ minstrel_stats_open(struct inode *inode,
96                 tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
97                 tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
98                 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
99 +               prob_ewmsd = minstrel_get_ewmsd10(mrs);
100  
101                 p += sprintf(p, "%4u.%1u    %4u.%1u     %3u.%1u    %3u.%1u"
102                                 "     %3u   %3u %-3u   "
103 @@ -115,7 +117,7 @@ minstrel_stats_open(struct inode *inode,
104                                 tp_max / 10, tp_max % 10,
105                                 tp_avg / 10, tp_avg % 10,
106                                 eprob / 10, eprob % 10,
107 -                               mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
108 +                               prob_ewmsd / 10, prob_ewmsd % 10,
109                                 mrs->retry_count,
110                                 mrs->last_success,
111                                 mrs->last_attempts,
112 @@ -159,6 +161,7 @@ minstrel_stats_csv_open(struct inode *in
113         for (i = 0; i < mi->n_rates; i++) {
114                 struct minstrel_rate *mr = &mi->r[i];
115                 struct minstrel_rate_stats *mrs = &mi->r[i].stats;
116 +               unsigned int prob_ewmsd;
117  
118                 p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : ""));
119                 p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : ""));
120 @@ -174,13 +177,14 @@ minstrel_stats_csv_open(struct inode *in
121                 tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
122                 tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
123                 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
124 +               prob_ewmsd = minstrel_get_ewmsd10(mrs);
125  
126                 p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
127                                 "%llu,%llu,%d,%d\n",
128                                 tp_max / 10, tp_max % 10,
129                                 tp_avg / 10, tp_avg % 10,
130                                 eprob / 10, eprob % 10,
131 -                               mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
132 +                               prob_ewmsd / 10, prob_ewmsd % 10,
133                                 mrs->retry_count,
134                                 mrs->last_success,
135                                 mrs->last_attempts,
136 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
137 +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
138 @@ -41,6 +41,7 @@ minstrel_ht_stats_dump(struct minstrel_h
139                 struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
140                 static const int bitrates[4] = { 10, 20, 55, 110 };
141                 int idx = i * MCS_GROUP_RATES + j;
142 +               unsigned int prob_ewmsd;
143  
144                 if (!(mi->supported[i] & BIT(j)))
145                         continue;
146 @@ -84,6 +85,7 @@ minstrel_ht_stats_dump(struct minstrel_h
147                 tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
148                 tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
149                 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
150 +               prob_ewmsd = minstrel_get_ewmsd10(mrs);
151  
152                 p += sprintf(p, "%4u.%1u    %4u.%1u     %3u.%1u    %3u.%1u"
153                                 "     %3u   %3u %-3u   "
154 @@ -91,7 +93,7 @@ minstrel_ht_stats_dump(struct minstrel_h
155                                 tp_max / 10, tp_max % 10,
156                                 tp_avg / 10, tp_avg % 10,
157                                 eprob / 10, eprob % 10,
158 -                               mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
159 +                               prob_ewmsd / 10, prob_ewmsd % 10,
160                                 mrs->retry_count,
161                                 mrs->last_success,
162                                 mrs->last_attempts,
163 @@ -185,6 +187,7 @@ minstrel_ht_stats_csv_dump(struct minstr
164                 struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
165                 static const int bitrates[4] = { 10, 20, 55, 110 };
166                 int idx = i * MCS_GROUP_RATES + j;
167 +               unsigned int prob_ewmsd;
168  
169                 if (!(mi->supported[i] & BIT(j)))
170                         continue;
171 @@ -225,13 +228,14 @@ minstrel_ht_stats_csv_dump(struct minstr
172                 tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
173                 tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
174                 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
175 +               prob_ewmsd = minstrel_get_ewmsd10(mrs);
176  
177                 p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,"
178                                 "%u,%llu,%llu,",
179                                 tp_max / 10, tp_max % 10,
180                                 tp_avg / 10, tp_avg % 10,
181                                 eprob / 10, eprob % 10,
182 -                               mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
183 +                               prob_ewmsd / 10, prob_ewmsd % 10,
184                                 mrs->retry_count,
185                                 mrs->last_success,
186                                 mrs->last_attempts,