svn commit: r225401 -
user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample
Adrian Chadd
adrian at FreeBSD.org
Mon Sep 5 15:11:01 UTC 2011
Author: adrian
Date: Mon Sep 5 15:11:01 2011
New Revision: 225401
URL: http://svn.freebsd.org/changeset/base/225401
Log:
Begin fleshing out an EWMA packet rate percentage figure and use
that when considering the best rate.
This is a more optimal figure than using the overall percentage,
which doesn't adapt quickly over time.
This is a lot more stable than before (between 100-130mbit on my netbook)
but as the rate sampling for MCS still samples (almost) all rates, performance
can jump quite a bit.
Modified:
user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c
user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.h
Modified: user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c Mon Sep 5 14:37:59 2011 (r225400)
+++ user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.c Mon Sep 5 15:11:01 2011 (r225401)
@@ -195,9 +195,7 @@ pick_best_rate(struct ath_node *an, cons
/* Calculate percentage if possible */
if (sn->stats[size_bin][rix].total_packets > 0) {
- pct =
- (100 * sn->stats[size_bin][rix].packets_acked) /
- sn->stats[size_bin][rix].total_packets;
+ pct = sn->stats[size_bin][rix].ewma_pct;
} else {
/* XXX for now, assume 95% ok */
pct = 95;
@@ -683,6 +681,71 @@ ath_rate_setupxtxdesc(struct ath_softc *
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][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;
+ }
+}
+
static void
update_stats(struct ath_softc *sc, struct ath_node *an,
int frame_size,
@@ -852,6 +915,14 @@ ath_rate_tx_complete(struct ath_softc *s
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;
int i;
@@ -938,6 +1009,16 @@ ath_rate_tx_complete(struct ath_softc *s
status,
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);
+
}
}
@@ -1059,6 +1140,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
sn->stats[y][rix].total_packets = 0;
sn->stats[y][rix].packets_acked = 0;
sn->stats[y][rix].last_tx = 0;
+ sn->stats[y][rix].ewma_pct = 0;
sn->stats[y][rix].perfect_tx_time =
calc_usecs_unicast_packet(sc, size, rix, 0, 0,
@@ -1124,12 +1206,14 @@ sample_stats(void *arg, struct ieee80211
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
if (sn->stats[y][rix].total_packets == 0)
continue;
- printf("[%2u %s:%4u] %8d:%-8d (%3d%%) T %8d F %4d avg %5u last %u\n",
+ printf("[%2u %s:%4u] %8d:%-8d (%3d%%) (EWMA %3d.%1d%%) T %8d F %4d avg %5u last %u\n",
dot11rate(rt, rix), dot11rate_label(rt, rix),
bin_to_size(y),
sn->stats[y][rix].total_packets,
sn->stats[y][rix].packets_acked,
(100*sn->stats[y][rix].packets_acked)/sn->stats[y][rix].total_packets,
+ sn->stats[y][rix].ewma_pct / 10,
+ sn->stats[y][rix].ewma_pct % 10,
sn->stats[y][rix].tries,
sn->stats[y][rix].successive_failures,
sn->stats[y][rix].average_tx_time,
Modified: user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.h
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.h Mon Sep 5 14:37:59 2011 (r225400)
+++ user/adrian/if_ath_tx/sys/dev/ath/ath_rate/sample/sample.h Mon Sep 5 15:11:01 2011 (r225401)
@@ -51,6 +51,7 @@ struct sample_softc {
int max_successive_failures;
int stale_failure_timeout; /* how long to honor max_successive_failures */
int min_switch; /* min time between rate changes */
+ int min_good_pct; /* min good percentage for a rate to be considered */
};
#define ATH_SOFTC_SAMPLE(sc) ((struct sample_softc *)sc->sc_rc)
@@ -58,8 +59,9 @@ struct rate_stats {
unsigned average_tx_time;
int successive_failures;
int tries;
- int total_packets;
- int packets_acked;
+ int total_packets; /* pkts total since assoc */
+ int packets_acked; /* pkts acked since assoc */
+ int ewma_pct; /* EWMA percentage */
unsigned perfect_tx_time; /* transmit time for 0 retries */
int last_tx;
};
More information about the svn-src-user
mailing list