Skip to content

Commit 5f919ab

Browse files
thuehnjmberg-intel
authored andcommitted
mac80211: add standard deviation to Minstrel stats
This patch adds the statistical descriptor "standard deviation" to better describe the current properties of Minstrel and Minstrel-HTs success probability distribution. The standard deviation (SD) is calculated as exponential weighted moving standard deviation (EWMSD) and its current value is added as new column in all rc_stats (in debugfs). Signed-off-by: Thomas Huehn <[email protected]> Acked-by: Felix Fietkau <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent ade6d4a commit 5f919ab

File tree

4 files changed

+56
-18
lines changed

4 files changed

+56
-18
lines changed

net/mac80211/rc80211_minstrel.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,19 +153,28 @@ minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
153153
}
154154

155155
/*
156-
* Recalculate success probabilities and counters for a given rate using EWMA
156+
* Recalculate statistics and counters of a given rate
157157
*/
158158
void
159159
minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
160160
{
161161
if (unlikely(mrs->attempts > 0)) {
162162
mrs->sample_skipped = 0;
163163
mrs->cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
164-
if (unlikely(!mrs->att_hist))
164+
if (unlikely(!mrs->att_hist)) {
165165
mrs->prob_ewma = mrs->cur_prob;
166-
else
166+
} else {
167+
/* update exponential weighted moving variance */
168+
mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd,
169+
mrs->cur_prob,
170+
mrs->prob_ewma,
171+
EWMA_LEVEL);
172+
173+
/*update exponential weighted moving avarage */
167174
mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
168-
mrs->cur_prob, EWMA_LEVEL);
175+
mrs->cur_prob,
176+
EWMA_LEVEL);
177+
}
169178
mrs->att_hist += mrs->attempts;
170179
mrs->succ_hist += mrs->success;
171180
} else {
@@ -193,7 +202,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
193202
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
194203
struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats;
195204

196-
/* Update success probabilities per rate */
205+
/* Update statistics of success probability per rate */
197206
minstrel_calc_rate_stats(mrs);
198207

199208
/* Sample less often below the 10% chance of success.

net/mac80211/rc80211_minstrel.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@ minstrel_ewma(int old, int new, int weight)
3535
return old + incr;
3636
}
3737

38+
/*
39+
* Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation
40+
*/
41+
static inline int
42+
minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight)
43+
{
44+
int diff, incr, tmp_var;
45+
46+
/* calculate exponential weighted moving variance */
47+
diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 1000000);
48+
incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
49+
tmp_var = old_ewmsd * old_ewmsd;
50+
tmp_var = weight * (tmp_var + diff * incr / 1000000) / EWMA_DIV;
51+
52+
/* return standard deviation */
53+
return (u16) int_sqrt(tmp_var);
54+
}
55+
3856
struct minstrel_rate_stats {
3957
/* current / last sampling period attempts/success counters */
4058
u16 attempts, last_attempts;
@@ -45,9 +63,11 @@ struct minstrel_rate_stats {
4563

4664
/* statistis of packet delivery probability
4765
* cur_prob - current prob within last update intervall
48-
* prob_ewma - exponential weighted moving average of prob */
66+
* prob_ewma - exponential weighted moving average of prob
67+
* prob_ewmsd - exp. weighted moving standard deviation of prob */
4968
unsigned int cur_prob;
5069
unsigned int prob_ewma;
70+
u16 prob_ewmsd;
5171

5272
/* maximum retry counts */
5373
u8 retry_count;

net/mac80211/rc80211_minstrel_debugfs.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ minstrel_stats_open(struct inode *inode, struct file *file)
8585
file->private_data = ms;
8686
p = ms->buf;
8787
p += sprintf(p, "\n");
88-
p += sprintf(p, "best __________rate_________ __statistics__ "
89-
"________last_______ ______sum-of________\n");
90-
p += sprintf(p, "rate [name idx airtime max_tp] [ ø(tp) ø(prob)] "
91-
"[prob.|retry|suc|att] [#success | #attempts]\n");
88+
p += sprintf(p, "best __________rate_________ ______"
89+
"statistics______ ________last_______ "
90+
"______sum-of________\n");
91+
p += sprintf(p, "rate [name idx airtime max_tp] [ ø(tp) ø(prob) "
92+
"sd(prob)] [prob.|retry|suc|att] "
93+
"[#success | #attempts]\n");
9294

9395
for (i = 0; i < mi->n_rates; i++) {
9496
struct minstrel_rate *mr = &mi->r[i];
@@ -110,11 +112,13 @@ minstrel_stats_open(struct inode *inode, struct file *file)
110112
prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
111113
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
112114

113-
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u %3u"
114-
" %3u %-3u %9llu %-9llu\n",
115+
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
116+
" %3u.%1u %3u %3u %-3u "
117+
"%9llu %-9llu\n",
115118
tp_max / 10, tp_max % 10,
116119
tp_avg / 10, tp_avg % 10,
117120
eprob / 10, eprob % 10,
121+
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
118122
prob / 10, prob % 10,
119123
mrs->retry_count,
120124
mrs->last_success,
@@ -176,11 +180,12 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file)
176180
prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
177181
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
178182

179-
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
183+
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
180184
"%llu,%llu,%d,%d\n",
181185
tp_max / 10, tp_max % 10,
182186
tp_avg / 10, tp_avg % 10,
183187
eprob / 10, eprob % 10,
188+
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
184189
prob / 10, prob % 10,
185190
mrs->retry_count,
186191
mrs->last_success,

net/mac80211/rc80211_minstrel_ht_debugfs.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,13 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
8686
prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
8787
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
8888

89-
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u "
90-
"%3u %3u %-3u %9llu %-9llu\n",
89+
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
90+
" %3u.%1u %3u %3u %-3u "
91+
"%9llu %-9llu\n",
9192
tp_max / 10, tp_max % 10,
9293
tp_avg / 10, tp_avg % 10,
9394
eprob / 10, eprob % 10,
95+
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
9496
prob / 10, prob % 10,
9597
mrs->retry_count,
9698
mrs->last_success,
@@ -128,10 +130,10 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
128130

129131
p += sprintf(p, "\n");
130132
p += sprintf(p, " best ____________rate__________ "
131-
"__statistics__ ________last_______ "
133+
"______statistics______ ________last_______ "
132134
"______sum-of________\n");
133135
p += sprintf(p, "mode guard # rate [name idx airtime max_tp] "
134-
"[ ø(tp) ø(prob)] [prob.|retry|suc|att] [#success | "
136+
"[ ø(tp) ø(prob) sd(prob)] [prob.|retry|suc|att] [#success | "
135137
"#attempts]\n");
136138

137139
p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
@@ -229,10 +231,12 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
229231
prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
230232
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
231233

232-
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,%llu,%llu,",
234+
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,"
235+
"%u,%llu,%llu,",
233236
tp_max / 10, tp_max % 10,
234237
tp_avg / 10, tp_avg % 10,
235238
eprob / 10, eprob % 10,
239+
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
236240
prob / 10, prob % 10,
237241
mrs->retry_count,
238242
mrs->last_success,

0 commit comments

Comments
 (0)