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>
This commit is contained in:
parent
f4ec7cb0f9
commit
506dbf90c1
|
@ -167,12 +167,6 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
|
||||||
if (unlikely(!mrs->att_hist)) {
|
if (unlikely(!mrs->att_hist)) {
|
||||||
mrs->prob_ewma = cur_prob;
|
mrs->prob_ewma = cur_prob;
|
||||||
} else {
|
} else {
|
||||||
/* update exponential weighted moving variance */
|
|
||||||
mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv,
|
|
||||||
cur_prob,
|
|
||||||
mrs->prob_ewma,
|
|
||||||
EWMA_LEVEL);
|
|
||||||
|
|
||||||
/*update exponential weighted moving avarage */
|
/*update exponential weighted moving avarage */
|
||||||
mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
|
mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
|
||||||
cur_prob,
|
cur_prob,
|
||||||
|
|
|
@ -35,19 +35,6 @@ minstrel_ewma(int old, int new, int weight)
|
||||||
return old + incr;
|
return old + incr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform EWMV (Exponentially Weighted Moving Variance) calculation
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
minstrel_ewmv(int old_ewmv, int cur_prob, int prob_ewma, int weight)
|
|
||||||
{
|
|
||||||
int diff, incr;
|
|
||||||
|
|
||||||
diff = cur_prob - prob_ewma;
|
|
||||||
incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
|
|
||||||
return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct minstrel_rate_stats {
|
struct minstrel_rate_stats {
|
||||||
/* current / last sampling period attempts/success counters */
|
/* current / last sampling period attempts/success counters */
|
||||||
u16 attempts, last_attempts;
|
u16 attempts, last_attempts;
|
||||||
|
@ -56,11 +43,8 @@ struct minstrel_rate_stats {
|
||||||
/* total attempts/success counters */
|
/* total attempts/success counters */
|
||||||
u32 att_hist, succ_hist;
|
u32 att_hist, succ_hist;
|
||||||
|
|
||||||
/* statistis of packet delivery probability
|
/* prob_ewma - exponential weighted moving average of prob */
|
||||||
* prob_ewma - exponential weighted moving average of prob
|
|
||||||
* prob_ewmsd - exp. weighted moving standard deviation of prob */
|
|
||||||
u16 prob_ewma;
|
u16 prob_ewma;
|
||||||
u16 prob_ewmv;
|
|
||||||
|
|
||||||
/* maximum retry counts */
|
/* maximum retry counts */
|
||||||
u8 retry_count;
|
u8 retry_count;
|
||||||
|
@ -140,14 +124,6 @@ struct minstrel_debugfs_info {
|
||||||
char buf[];
|
char buf[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */
|
|
||||||
static inline int
|
|
||||||
minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs)
|
|
||||||
{
|
|
||||||
unsigned int ewmv = mrs->prob_ewmv;
|
|
||||||
return int_sqrt(MINSTREL_TRUNC(ewmv * 1000 * 1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
extern const struct rate_control_ops mac80211_minstrel;
|
extern const struct rate_control_ops mac80211_minstrel;
|
||||||
void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
|
void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
|
||||||
|
|
||||||
|
|
|
@ -70,14 +70,13 @@ minstrel_stats_open(struct inode *inode, struct file *file)
|
||||||
p = ms->buf;
|
p = ms->buf;
|
||||||
p += sprintf(p, "\n");
|
p += sprintf(p, "\n");
|
||||||
p += sprintf(p,
|
p += sprintf(p,
|
||||||
"best __________rate_________ ________statistics________ ____last_____ ______sum-of________\n");
|
"best __________rate_________ ____statistics___ ____last_____ ______sum-of________\n");
|
||||||
p += sprintf(p,
|
p += sprintf(p,
|
||||||
"rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n");
|
"rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n");
|
||||||
|
|
||||||
for (i = 0; i < mi->n_rates; i++) {
|
for (i = 0; i < mi->n_rates; i++) {
|
||||||
struct minstrel_rate *mr = &mi->r[i];
|
struct minstrel_rate *mr = &mi->r[i];
|
||||||
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
|
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
|
||||||
unsigned int prob_ewmsd;
|
|
||||||
|
|
||||||
*(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
|
*(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
|
||||||
*(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
|
*(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
|
||||||
|
@ -93,15 +92,13 @@ minstrel_stats_open(struct inode *inode, struct file *file)
|
||||||
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
|
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
|
||||||
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
|
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
|
||||||
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||||
prob_ewmsd = minstrel_get_ewmsd10(mrs);
|
|
||||||
|
|
||||||
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
|
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u"
|
||||||
" %3u %3u %-3u "
|
" %3u %3u %-3u "
|
||||||
"%9llu %-9llu\n",
|
"%9llu %-9llu\n",
|
||||||
tp_max / 10, tp_max % 10,
|
tp_max / 10, tp_max % 10,
|
||||||
tp_avg / 10, tp_avg % 10,
|
tp_avg / 10, tp_avg % 10,
|
||||||
eprob / 10, eprob % 10,
|
eprob / 10, eprob % 10,
|
||||||
prob_ewmsd / 10, prob_ewmsd % 10,
|
|
||||||
mrs->retry_count,
|
mrs->retry_count,
|
||||||
mrs->last_success,
|
mrs->last_success,
|
||||||
mrs->last_attempts,
|
mrs->last_attempts,
|
||||||
|
@ -137,7 +134,6 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file)
|
||||||
for (i = 0; i < mi->n_rates; i++) {
|
for (i = 0; i < mi->n_rates; i++) {
|
||||||
struct minstrel_rate *mr = &mi->r[i];
|
struct minstrel_rate *mr = &mi->r[i];
|
||||||
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
|
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
|
||||||
unsigned int prob_ewmsd;
|
|
||||||
|
|
||||||
p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : ""));
|
p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : ""));
|
||||||
p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : ""));
|
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)
|
||||||
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
|
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
|
||||||
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
|
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
|
||||||
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||||
prob_ewmsd = minstrel_get_ewmsd10(mrs);
|
|
||||||
|
|
||||||
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
|
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u,"
|
||||||
"%llu,%llu,%d,%d\n",
|
"%llu,%llu,%d,%d\n",
|
||||||
tp_max / 10, tp_max % 10,
|
tp_max / 10, tp_max % 10,
|
||||||
tp_avg / 10, tp_avg % 10,
|
tp_avg / 10, tp_avg % 10,
|
||||||
eprob / 10, eprob % 10,
|
eprob / 10, eprob % 10,
|
||||||
prob_ewmsd / 10, prob_ewmsd % 10,
|
|
||||||
mrs->retry_count,
|
mrs->retry_count,
|
||||||
mrs->last_success,
|
mrs->last_success,
|
||||||
mrs->last_attempts,
|
mrs->last_attempts,
|
||||||
|
|
|
@ -57,7 +57,6 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
||||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||||
static const int bitrates[4] = { 10, 20, 55, 110 };
|
static const int bitrates[4] = { 10, 20, 55, 110 };
|
||||||
int idx = i * MCS_GROUP_RATES + j;
|
int idx = i * MCS_GROUP_RATES + j;
|
||||||
unsigned int prob_ewmsd;
|
|
||||||
unsigned int duration;
|
unsigned int duration;
|
||||||
|
|
||||||
if (!(mi->supported[i] & BIT(j)))
|
if (!(mi->supported[i] & BIT(j)))
|
||||||
|
@ -104,15 +103,13 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
||||||
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
||||||
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
|
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
|
||||||
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||||
prob_ewmsd = minstrel_get_ewmsd10(mrs);
|
|
||||||
|
|
||||||
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
|
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u"
|
||||||
" %3u %3u %-3u "
|
" %3u %3u %-3u "
|
||||||
"%9llu %-9llu\n",
|
"%9llu %-9llu\n",
|
||||||
tp_max / 10, tp_max % 10,
|
tp_max / 10, tp_max % 10,
|
||||||
tp_avg / 10, tp_avg % 10,
|
tp_avg / 10, tp_avg % 10,
|
||||||
eprob / 10, eprob % 10,
|
eprob / 10, eprob % 10,
|
||||||
prob_ewmsd / 10, prob_ewmsd % 10,
|
|
||||||
mrs->retry_count,
|
mrs->retry_count,
|
||||||
mrs->last_success,
|
mrs->last_success,
|
||||||
mrs->last_attempts,
|
mrs->last_attempts,
|
||||||
|
@ -149,9 +146,9 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
p += sprintf(p, "\n");
|
p += sprintf(p, "\n");
|
||||||
p += sprintf(p,
|
p += sprintf(p,
|
||||||
" best ____________rate__________ ________statistics________ _____last____ ______sum-of________\n");
|
" best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n");
|
||||||
p += sprintf(p,
|
p += sprintf(p,
|
||||||
"mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n");
|
"mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n");
|
||||||
|
|
||||||
p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
|
p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
|
||||||
for (i = 0; i < MINSTREL_CCK_GROUP; i++)
|
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)
|
||||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||||
static const int bitrates[4] = { 10, 20, 55, 110 };
|
static const int bitrates[4] = { 10, 20, 55, 110 };
|
||||||
int idx = i * MCS_GROUP_RATES + j;
|
int idx = i * MCS_GROUP_RATES + j;
|
||||||
unsigned int prob_ewmsd;
|
|
||||||
unsigned int duration;
|
unsigned int duration;
|
||||||
|
|
||||||
if (!(mi->supported[i] & BIT(j)))
|
if (!(mi->supported[i] & BIT(j)))
|
||||||
|
@ -251,14 +247,12 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
||||||
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
||||||
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
|
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
|
||||||
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||||
prob_ewmsd = minstrel_get_ewmsd10(mrs);
|
|
||||||
|
|
||||||
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,"
|
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,"
|
||||||
"%u,%llu,%llu,",
|
"%u,%llu,%llu,",
|
||||||
tp_max / 10, tp_max % 10,
|
tp_max / 10, tp_max % 10,
|
||||||
tp_avg / 10, tp_avg % 10,
|
tp_avg / 10, tp_avg % 10,
|
||||||
eprob / 10, eprob % 10,
|
eprob / 10, eprob % 10,
|
||||||
prob_ewmsd / 10, prob_ewmsd % 10,
|
|
||||||
mrs->retry_count,
|
mrs->retry_count,
|
||||||
mrs->last_success,
|
mrs->last_success,
|
||||||
mrs->last_attempts,
|
mrs->last_attempts,
|
||||||
|
|
Loading…
Reference in New Issue