diff options
author | Felix Fietkau <nbd@nbd.name> | 2018-10-06 13:35:07 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2018-10-11 10:01:05 -0400 |
commit | 506dbf90c1ba98d998b26e17a2e3e69bffef52f4 (patch) | |
tree | c4476f0b470499290908109f3259d192e71ee1b5 | |
parent | f4ec7cb0f9ea65a7622b001bb48dbac1a7e6ad1e (diff) |
mac80211: rc80211_minstrel: remove variance / stddev calculation
When there are few packets (e.g. for sampling attempts), the exponentially
weighted variance is usually vastly overestimated, making the resulting data
essentially useless. As far as I know, there has not been any practical use
for this, so let's not waste any cycles on it.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 6 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel.h | 26 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_debugfs.c | 14 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht_debugfs.c | 14 |
4 files changed, 9 insertions, 51 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index dead57ba9eac..a34e9c2ca626 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -167,12 +167,6 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs) | |||
167 | if (unlikely(!mrs->att_hist)) { | 167 | if (unlikely(!mrs->att_hist)) { |
168 | mrs->prob_ewma = cur_prob; | 168 | mrs->prob_ewma = cur_prob; |
169 | } else { | 169 | } else { |
170 | /* update exponential weighted moving variance */ | ||
171 | mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv, | ||
172 | cur_prob, | ||
173 | mrs->prob_ewma, | ||
174 | EWMA_LEVEL); | ||
175 | |||
176 | /*update exponential weighted moving avarage */ | 170 | /*update exponential weighted moving avarage */ |
177 | mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma, | 171 | mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma, |
178 | cur_prob, | 172 | cur_prob, |
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 54b2b2c3e10a..23ec953e3a24 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h | |||
@@ -35,19 +35,6 @@ minstrel_ewma(int old, int new, int weight) | |||
35 | return old + incr; | 35 | return old + incr; |
36 | } | 36 | } |
37 | 37 | ||
38 | /* | ||
39 | * Perform EWMV (Exponentially Weighted Moving Variance) calculation | ||
40 | */ | ||
41 | static inline int | ||
42 | minstrel_ewmv(int old_ewmv, int cur_prob, int prob_ewma, int weight) | ||
43 | { | ||
44 | int diff, incr; | ||
45 | |||
46 | diff = cur_prob - prob_ewma; | ||
47 | incr = (EWMA_DIV - weight) * diff / EWMA_DIV; | ||
48 | return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV; | ||
49 | } | ||
50 | |||
51 | struct minstrel_rate_stats { | 38 | struct minstrel_rate_stats { |
52 | /* current / last sampling period attempts/success counters */ | 39 | /* current / last sampling period attempts/success counters */ |
53 | u16 attempts, last_attempts; | 40 | u16 attempts, last_attempts; |
@@ -56,11 +43,8 @@ struct minstrel_rate_stats { | |||
56 | /* total attempts/success counters */ | 43 | /* total attempts/success counters */ |
57 | u32 att_hist, succ_hist; | 44 | u32 att_hist, succ_hist; |
58 | 45 | ||
59 | /* statistis of packet delivery probability | 46 | /* prob_ewma - exponential weighted moving average of prob */ |
60 | * prob_ewma - exponential weighted moving average of prob | ||
61 | * prob_ewmsd - exp. weighted moving standard deviation of prob */ | ||
62 | u16 prob_ewma; | 47 | u16 prob_ewma; |
63 | u16 prob_ewmv; | ||
64 | 48 | ||
65 | /* maximum retry counts */ | 49 | /* maximum retry counts */ |
66 | u8 retry_count; | 50 | u8 retry_count; |
@@ -140,14 +124,6 @@ struct minstrel_debugfs_info { | |||
140 | char buf[]; | 124 | char buf[]; |
141 | }; | 125 | }; |
142 | 126 | ||
143 | /* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */ | ||
144 | static inline int | ||
145 | minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs) | ||
146 | { | ||
147 | unsigned int ewmv = mrs->prob_ewmv; | ||
148 | return int_sqrt(MINSTREL_TRUNC(ewmv * 1000 * 1000)); | ||
149 | } | ||
150 | |||
151 | extern const struct rate_control_ops mac80211_minstrel; | 127 | extern const struct rate_control_ops mac80211_minstrel; |
152 | void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); | 128 | void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); |
153 | 129 | ||
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index 698a668b5316..c8afd85b51a0 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c | |||
@@ -70,14 +70,13 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
70 | p = ms->buf; | 70 | p = ms->buf; |
71 | p += sprintf(p, "\n"); | 71 | p += sprintf(p, "\n"); |
72 | p += sprintf(p, | 72 | p += sprintf(p, |
73 | "best __________rate_________ ________statistics________ ____last_____ ______sum-of________\n"); | 73 | "best __________rate_________ ____statistics___ ____last_____ ______sum-of________\n"); |
74 | p += sprintf(p, | 74 | p += sprintf(p, |
75 | "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n"); | 75 | "rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n"); |
76 | 76 | ||
77 | for (i = 0; i < mi->n_rates; i++) { | 77 | for (i = 0; i < mi->n_rates; i++) { |
78 | struct minstrel_rate *mr = &mi->r[i]; | 78 | struct minstrel_rate *mr = &mi->r[i]; |
79 | struct minstrel_rate_stats *mrs = &mi->r[i].stats; | 79 | struct minstrel_rate_stats *mrs = &mi->r[i].stats; |
80 | unsigned int prob_ewmsd; | ||
81 | 80 | ||
82 | *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; | 81 | *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; |
83 | *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; | 82 | *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; |
@@ -93,15 +92,13 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
93 | tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); | 92 | tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); |
94 | tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); | 93 | tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); |
95 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); | 94 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); |
96 | prob_ewmsd = minstrel_get_ewmsd10(mrs); | ||
97 | 95 | ||
98 | p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" | 96 | p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u" |
99 | " %3u %3u %-3u " | 97 | " %3u %3u %-3u " |
100 | "%9llu %-9llu\n", | 98 | "%9llu %-9llu\n", |
101 | tp_max / 10, tp_max % 10, | 99 | tp_max / 10, tp_max % 10, |
102 | tp_avg / 10, tp_avg % 10, | 100 | tp_avg / 10, tp_avg % 10, |
103 | eprob / 10, eprob % 10, | 101 | eprob / 10, eprob % 10, |
104 | prob_ewmsd / 10, prob_ewmsd % 10, | ||
105 | mrs->retry_count, | 102 | mrs->retry_count, |
106 | mrs->last_success, | 103 | mrs->last_success, |
107 | mrs->last_attempts, | 104 | mrs->last_attempts, |
@@ -137,7 +134,6 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file) | |||
137 | for (i = 0; i < mi->n_rates; i++) { | 134 | for (i = 0; i < mi->n_rates; i++) { |
138 | struct minstrel_rate *mr = &mi->r[i]; | 135 | struct minstrel_rate *mr = &mi->r[i]; |
139 | struct minstrel_rate_stats *mrs = &mi->r[i].stats; | 136 | struct minstrel_rate_stats *mrs = &mi->r[i].stats; |
140 | unsigned int prob_ewmsd; | ||
141 | 137 | ||
142 | p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : "")); | 138 | p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : "")); |
143 | p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : "")); | 139 | p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : "")); |
@@ -153,14 +149,12 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file) | |||
153 | tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); | 149 | tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); |
154 | tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); | 150 | tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); |
155 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); | 151 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); |
156 | prob_ewmsd = minstrel_get_ewmsd10(mrs); | ||
157 | 152 | ||
158 | p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u," | 153 | p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u," |
159 | "%llu,%llu,%d,%d\n", | 154 | "%llu,%llu,%d,%d\n", |
160 | tp_max / 10, tp_max % 10, | 155 | tp_max / 10, tp_max % 10, |
161 | tp_avg / 10, tp_avg % 10, | 156 | tp_avg / 10, tp_avg % 10, |
162 | eprob / 10, eprob % 10, | 157 | eprob / 10, eprob % 10, |
163 | prob_ewmsd / 10, prob_ewmsd % 10, | ||
164 | mrs->retry_count, | 158 | mrs->retry_count, |
165 | mrs->last_success, | 159 | mrs->last_success, |
166 | mrs->last_attempts, | 160 | mrs->last_attempts, |
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index 8065da2cf0f1..57820a5f2c16 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c | |||
@@ -57,7 +57,6 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) | |||
57 | struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; | 57 | struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; |
58 | static const int bitrates[4] = { 10, 20, 55, 110 }; | 58 | static const int bitrates[4] = { 10, 20, 55, 110 }; |
59 | int idx = i * MCS_GROUP_RATES + j; | 59 | int idx = i * MCS_GROUP_RATES + j; |
60 | unsigned int prob_ewmsd; | ||
61 | unsigned int duration; | 60 | unsigned int duration; |
62 | 61 | ||
63 | if (!(mi->supported[i] & BIT(j))) | 62 | if (!(mi->supported[i] & BIT(j))) |
@@ -104,15 +103,13 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) | |||
104 | tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); | 103 | tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); |
105 | tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); | 104 | tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); |
106 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); | 105 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); |
107 | prob_ewmsd = minstrel_get_ewmsd10(mrs); | ||
108 | 106 | ||
109 | p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" | 107 | p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u" |
110 | " %3u %3u %-3u " | 108 | " %3u %3u %-3u " |
111 | "%9llu %-9llu\n", | 109 | "%9llu %-9llu\n", |
112 | tp_max / 10, tp_max % 10, | 110 | tp_max / 10, tp_max % 10, |
113 | tp_avg / 10, tp_avg % 10, | 111 | tp_avg / 10, tp_avg % 10, |
114 | eprob / 10, eprob % 10, | 112 | eprob / 10, eprob % 10, |
115 | prob_ewmsd / 10, prob_ewmsd % 10, | ||
116 | mrs->retry_count, | 113 | mrs->retry_count, |
117 | mrs->last_success, | 114 | mrs->last_success, |
118 | mrs->last_attempts, | 115 | mrs->last_attempts, |
@@ -149,9 +146,9 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) | |||
149 | 146 | ||
150 | p += sprintf(p, "\n"); | 147 | p += sprintf(p, "\n"); |
151 | p += sprintf(p, | 148 | p += sprintf(p, |
152 | " best ____________rate__________ ________statistics________ _____last____ ______sum-of________\n"); | 149 | " best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n"); |
153 | p += sprintf(p, | 150 | p += sprintf(p, |
154 | "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n"); | 151 | "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n"); |
155 | 152 | ||
156 | p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); | 153 | p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); |
157 | for (i = 0; i < MINSTREL_CCK_GROUP; i++) | 154 | for (i = 0; i < MINSTREL_CCK_GROUP; i++) |
@@ -206,7 +203,6 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) | |||
206 | struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; | 203 | struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; |
207 | static const int bitrates[4] = { 10, 20, 55, 110 }; | 204 | static const int bitrates[4] = { 10, 20, 55, 110 }; |
208 | int idx = i * MCS_GROUP_RATES + j; | 205 | int idx = i * MCS_GROUP_RATES + j; |
209 | unsigned int prob_ewmsd; | ||
210 | unsigned int duration; | 206 | unsigned int duration; |
211 | 207 | ||
212 | if (!(mi->supported[i] & BIT(j))) | 208 | if (!(mi->supported[i] & BIT(j))) |
@@ -251,14 +247,12 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) | |||
251 | tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); | 247 | tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); |
252 | tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); | 248 | tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); |
253 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); | 249 | eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); |
254 | prob_ewmsd = minstrel_get_ewmsd10(mrs); | ||
255 | 250 | ||
256 | p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u," | 251 | p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u," |
257 | "%u,%llu,%llu,", | 252 | "%u,%llu,%llu,", |
258 | tp_max / 10, tp_max % 10, | 253 | tp_max / 10, tp_max % 10, |
259 | tp_avg / 10, tp_avg % 10, | 254 | tp_avg / 10, tp_avg % 10, |
260 | eprob / 10, eprob % 10, | 255 | eprob / 10, eprob % 10, |
261 | prob_ewmsd / 10, prob_ewmsd % 10, | ||
262 | mrs->retry_count, | 256 | mrs->retry_count, |
263 | mrs->last_success, | 257 | mrs->last_success, |
264 | mrs->last_attempts, | 258 | mrs->last_attempts, |