1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-29 16:44:03 +00:00

I give up - just throw the EWMA update into the normal update_stats()

routine.

There were still corner cases where the EWMA update stats are being
called on a rix which didn't have an intermediary stats update; thus
no packets were counted against it.  Sigh.

This should fix the crashes I've been seeing on recent -HEAD.
This commit is contained in:
Adrian Chadd 2013-02-27 04:33:06 +00:00
parent 085c638420
commit ee563d630b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=247372

View File

@ -708,71 +708,6 @@ ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
s3code, sched->t3); /* series 3 */
}
/*
* Update the EWMA percentage.
*
* This is a simple hack to track an EWMA based on the current
* rate scenario. For the rate codes which failed, this will
* record a 0% against it. For the rate code which succeeded,
* EWMA will record the nbad*100/nframes percentage against it.
*/
static void
update_ewma_stats(struct ath_softc *sc, struct ath_node *an,
int frame_size,
int rix0, int tries0,
int rix1, int tries1,
int rix2, int tries2,
int rix3, int tries3,
int short_tries, int tries, int status,
int nframes, int nbad)
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
const int size_bin = size_to_bin(frame_size);
int tries_so_far;
int pct;
int rix = rix0;
/* Calculate percentage based on current rate */
if (nframes == 0)
nframes = nbad = 1;
pct = ((nframes - nbad) * 1000) / nframes;
/* Figure out which rate index succeeded */
tries_so_far = tries0;
if (tries1 && tries_so_far < tries) {
tries_so_far += tries1;
rix = rix1;
/* XXX bump ewma pct */
}
if (tries2 && tries_so_far < tries) {
tries_so_far += tries2;
rix = rix2;
/* XXX bump ewma pct */
}
if (tries3 && tries_so_far < tries) {
rix = rix3;
/* XXX bump ewma pct */
}
/* rix is the successful rate, update EWMA for final rix */
if (sn->stats[size_bin][rix].total_packets <
ssc->smoothing_minpackets) {
/* just average the first few packets */
int a_pct = (sn->stats[size_bin][rix].packets_acked * 1000) /
(sn->stats[size_bin][rix].total_packets);
sn->stats[size_bin][rix].ewma_pct = a_pct;
} else {
/* use a ewma */
sn->stats[size_bin][rix].ewma_pct =
((sn->stats[size_bin][rix].ewma_pct * ssc->smoothing_rate) +
(pct * (100 - ssc->smoothing_rate))) / 100;
}
}
static void
update_stats(struct ath_softc *sc, struct ath_node *an,
int frame_size,
@ -792,6 +727,7 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
const int size = bin_to_size(size_bin);
int tt, tries_so_far;
int is_ht40 = (an->an_node.ni_chw == 40);
int pct;
if (!IS_RATE_DEFINED(sn, rix0))
return;
@ -865,6 +801,27 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
sn->stats[size_bin][rix0].last_tx = ticks;
sn->stats[size_bin][rix0].total_packets += nframes;
/* update EWMA for this rix */
/* Calculate percentage based on current rate */
if (nframes == 0)
nframes = nbad = 1;
pct = ((nframes - nbad) * 1000) / nframes;
if (sn->stats[size_bin][rix0].total_packets <
ssc->smoothing_minpackets) {
/* just average the first few packets */
int a_pct = (sn->stats[size_bin][rix0].packets_acked * 1000) /
(sn->stats[size_bin][rix0].total_packets);
sn->stats[size_bin][rix0].ewma_pct = a_pct;
} else {
/* use a ewma */
sn->stats[size_bin][rix0].ewma_pct =
((sn->stats[size_bin][rix0].ewma_pct * ssc->smoothing_rate) +
(pct * (100 - ssc->smoothing_rate))) / 100;
}
if (rix0 == sn->current_sample_rix[size_bin]) {
IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
&an->an_node,
@ -907,6 +864,11 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
short_tries = ts->ts_shortretry;
long_tries = ts->ts_longretry + 1;
if (nframes == 0) {
device_printf(sc->sc_dev, "%s: nframes=0?\n", __func__);
return;
}
if (frame_size == 0) /* NB: should not happen */
frame_size = 1500;
@ -950,13 +912,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
0, 0,
short_tries, long_tries, status,
nframes, nbad);
update_ewma_stats(sc, an, frame_size,
final_rix, long_tries,
0, 0,
0, 0,
0, 0,
short_tries, long_tries, status,
nframes, nbad);
} else {
int finalTSIdx = ts->ts_finaltsi;
@ -1008,15 +963,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
short_tries, long_tries,
long_tries > rc[0].tries,
nframes, nbad);
update_ewma_stats(sc, an, frame_size,
rc[0].rix, rc[0].tries,
rc[1].rix, rc[1].tries,
rc[2].rix, rc[2].tries,
rc[3].rix, rc[3].tries,
short_tries, long_tries,
long_tries > rc[0].tries,
nframes, nbad);
long_tries -= rc[0].tries;
}
@ -1029,14 +975,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
short_tries, long_tries,
status,
nframes, nbad);
update_ewma_stats(sc, an, frame_size,
rc[1].rix, rc[1].tries,
rc[2].rix, rc[2].tries,
rc[3].rix, rc[3].tries,
0, 0,
short_tries, long_tries,
status,
nframes, nbad);
long_tries -= rc[1].tries;
}
@ -1049,14 +987,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
short_tries, long_tries,
status,
nframes, nbad);
update_ewma_stats(sc, an, frame_size,
rc[2].rix, rc[2].tries,
rc[3].rix, rc[3].tries,
0, 0,
0, 0,
short_tries, long_tries,
status,
nframes, nbad);
long_tries -= rc[2].tries;
}
@ -1069,14 +999,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
short_tries, long_tries,
status,
nframes, nbad);
update_ewma_stats(sc, an, frame_size,
rc[3].rix, rc[3].tries,
0, 0,
0, 0,
0, 0,
short_tries, long_tries,
status,
nframes, nbad);
}
}
}