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