svn commit: r360998 - in head/sys/dev/ath: . ath_rate/amrr ath_rate/onoe ath_rate/sample

Adrian Chadd adrian at FreeBSD.org
Wed May 13 00:05:13 UTC 2020


Author: adrian
Date: Wed May 13 00:05:11 2020
New Revision: 360998
URL: https://svnweb.freebsd.org/changeset/base/360998

Log:
  [ath] [ath_rate] Add some extra data into the rate control lookup.
  
  Right now (well, since I did this in 2011/2012) the rate control code
  makes some super bad choices for 11n aggregates/rates, and it tracks
  statistics even more questionably.
  
  It's been long enough and I'm now trying to use it again daily, so let's
  start by:
  
  * telling the rate control code if it's an aggregate or not;
  * being clearer about the TID - yes it can be extracted from the
    ath_buf but this way it can be overridden by the caller without
    changing the TID itself.
  
    (This is for doing experiments with voice/video QoS at some point..)
  
  * Return an optional field to limit how long the aggregate is in
    microseconds.  Right now the rate control code supplies a rate table
    and the ath aggr form code will look at the rate table and limit
    the aggregate size to 4ms at the slowest rate.  Yeah, this is pretty
    terrible.
  
  * Add some more TODO comments around handling txpower, rate and
    handling filtered frames status so if I continue to have spoons for
    this I can go poke at it.

Modified:
  head/sys/dev/ath/ath_rate/amrr/amrr.c
  head/sys/dev/ath/ath_rate/onoe/onoe.c
  head/sys/dev/ath/ath_rate/sample/sample.c
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_ath_tx.c
  head/sys/dev/ath/if_athrate.h

Modified: head/sys/dev/ath/ath_rate/amrr/amrr.c
==============================================================================
--- head/sys/dev/ath/ath_rate/amrr/amrr.c	Wed May 13 00:03:39 2020	(r360997)
+++ head/sys/dev/ath/ath_rate/amrr/amrr.c	Wed May 13 00:05:11 2020	(r360998)
@@ -104,8 +104,8 @@ ath_rate_node_cleanup(struct ath_softc *sc, struct ath
 
 void
 ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
-	int shortPreamble, size_t frameLen,
-	u_int8_t *rix, int *try0, u_int8_t *txrate)
+	int shortPreamble, size_t frameLen, int tid, bool is_aggr,
+	u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur)
 {
 	struct amrr_node *amn = ATH_NODE_AMRR(an);
 
@@ -115,6 +115,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
 		*txrate = amn->amn_tx_rate0sp;
 	else
 		*txrate = amn->amn_tx_rate0;
+	maxdur = -1;
 }
 
 /*

Modified: head/sys/dev/ath/ath_rate/onoe/onoe.c
==============================================================================
--- head/sys/dev/ath/ath_rate/onoe/onoe.c	Wed May 13 00:03:39 2020	(r360997)
+++ head/sys/dev/ath/ath_rate/onoe/onoe.c	Wed May 13 00:05:11 2020	(r360998)
@@ -112,8 +112,8 @@ ath_rate_node_cleanup(struct ath_softc *sc, struct ath
 
 void
 ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
-	int shortPreamble, size_t frameLen,
-	u_int8_t *rix, int *try0, u_int8_t *txrate)
+	int shortPreamble, size_t frameLen, int tid, bool is_aggr,
+	u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur)
 {
 	struct onoe_node *on = ATH_NODE_ONOE(an);
 
@@ -123,6 +123,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
 		*txrate = on->on_tx_rate0sp;
 	else
 		*txrate = on->on_tx_rate0;
+	*maxdur = -1;
 }
 
 /*

Modified: head/sys/dev/ath/ath_rate/sample/sample.c
==============================================================================
--- head/sys/dev/ath/ath_rate/sample/sample.c	Wed May 13 00:03:39 2020	(r360997)
+++ head/sys/dev/ath/ath_rate/sample/sample.c	Wed May 13 00:05:11 2020	(r360998)
@@ -482,8 +482,9 @@ ath_rate_pick_seed_rate_ht(struct ath_softc *sc, struc
 
 void
 ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
-		  int shortPreamble, size_t frameLen,
-		  u_int8_t *rix0, int *try0, u_int8_t *txrate)
+		  int shortPreamble, size_t frameLen, int tid,
+		  bool is_aggr, u_int8_t *rix0, int *try0,
+		  u_int8_t *txrate, int *maxdur)
 {
 #define	DOT11RATE(ix)	(rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
 #define	MCS(ix)		(rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
@@ -497,6 +498,10 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
 	unsigned average_tx_time;
 
 	ath_rate_update_static_rix(sc, &an->an_node);
+
+	/* For now don't take TID, is_aggr into account */
+	/* Also for now don't calculate a max duration; that'll come later */
+	*maxdur = -1;
 
 	if (sn->currates != sc->sc_currates) {
 		device_printf(sc->sc_dev, "%s: currates != sc_currates!\n",

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Wed May 13 00:03:39 2020	(r360997)
+++ head/sys/dev/ath/if_ath.c	Wed May 13 00:05:11 2020	(r360998)
@@ -4312,6 +4312,11 @@ ath_tx_update_ratectrl(struct ath_softc *sc, struct ie
 	an = ATH_NODE(ni);
 	ATH_NODE_UNLOCK_ASSERT(an);
 
+	/*
+	 * XXX TODO: teach the rate control about TXERR_FILT and
+	 * see about handling it (eg see how many attempts were
+	 * made before it got filtered and account for that.)
+	 */
 	if ((ts->ts_status & HAL_TXERR_FILT) == 0) {
 		ATH_NODE_LOCK(an);
 		ath_rate_tx_complete(sc, an, rc, ts, frmlen, nframes, nbad);
@@ -4355,6 +4360,9 @@ ath_tx_process_buf_completion(struct ath_softc *sc, st
 			/*
 			 * XXX assume this isn't an aggregate
 			 * frame.
+			 *
+			 * XXX TODO: also do this for filtered frames?
+			 * Once rate control knows about them?
 			 */
 			ath_tx_update_ratectrl(sc, ni,
 			     bf->bf_state.bfs_rc, ts,

Modified: head/sys/dev/ath/if_ath_tx.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx.c	Wed May 13 00:03:39 2020	(r360997)
+++ head/sys/dev/ath/if_ath_tx.c	Wed May 13 00:05:11 2020	(r360998)
@@ -1376,10 +1376,12 @@ ath_tx_setds(struct ath_softc *sc, struct ath_buf *bf)
  * as they may depend upon the rate chosen.
  */
 static void
-ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf)
+ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf, int tid,
+    bool is_aggr)
 {
 	uint8_t rate, rix;
 	int try0;
+	int maxdur; // Note: Unused for now
 
 	if (! bf->bf_state.bfs_doratelookup)
 		return;
@@ -1389,7 +1391,7 @@ ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_
 
 	ATH_NODE_LOCK(ATH_NODE(bf->bf_node));
 	ath_rate_findrate(sc, ATH_NODE(bf->bf_node), bf->bf_state.bfs_shpream,
-	    bf->bf_state.bfs_pktlen, &rix, &try0, &rate);
+	    bf->bf_state.bfs_pktlen, tid, is_aggr, &rix, &try0, &rate, &maxdur);
 
 	/* In case MRR is disabled, make sure rc[0] is setup correctly */
 	bf->bf_state.bfs_rc[0].rix = rix;
@@ -1519,7 +1521,7 @@ ath_tx_xmit_normal(struct ath_softc *sc, struct ath_tx
 	bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK;
 
 	/* Setup the descriptor before handoff */
-	ath_tx_do_ratelookup(sc, bf);
+	ath_tx_do_ratelookup(sc, bf, tid->tid, false);
 	ath_tx_calc_duration(sc, bf);
 	ath_tx_calc_protection(sc, bf);
 	ath_tx_set_rtscts(sc, bf);
@@ -3094,7 +3096,7 @@ ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node
 	ath_tx_update_clrdmask(sc, tid, bf);
 
 	/* Direct dispatch to hardware */
-	ath_tx_do_ratelookup(sc, bf);
+	ath_tx_do_ratelookup(sc, bf, tid->tid, false);
 	ath_tx_calc_duration(sc, bf);
 	ath_tx_calc_protection(sc, bf);
 	ath_tx_set_rtscts(sc, bf);
@@ -4689,6 +4691,8 @@ ath_tx_comp_aggr_error(struct ath_softc *sc, struct at
 	 *
 	 * XXX use the length in the first frame in the series;
 	 * XXX just so things are consistent for now.
+	 *
+	 * XXX TODO: need to signal this is a large frame no matter what...
 	 */
 	ath_tx_update_ratectrl(sc, ni, bf_first->bf_state.bfs_rc,
 	    &bf_first->bf_status.ds_txstat,
@@ -5088,9 +5092,11 @@ ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath
 	 * Now we know how many frames were bad, call the rate
 	 * control code.
 	 */
-	if (fail == 0)
+	if (fail == 0) {
+		/* XXX TODO: what's pktlen here? */
 		ath_tx_update_ratectrl(sc, ni, rc, &ts, pktlen, nframes,
 		    nbad);
+	}
 
 	/*
 	 * send bar if we dropped any frames
@@ -5429,7 +5435,7 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct 
 			/* Update CLRDMASK just before this frame is queued */
 			ath_tx_update_clrdmask(sc, tid, bf);
 
-			ath_tx_do_ratelookup(sc, bf);
+			ath_tx_do_ratelookup(sc, bf, tid->tid, false);
 			ath_tx_calc_duration(sc, bf);
 			ath_tx_calc_protection(sc, bf);
 			ath_tx_set_rtscts(sc, bf);
@@ -5453,7 +5459,7 @@ ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct 
 		 * really "do" aggregate lookups, so it only considers
 		 * the size of the first frame.
 		 */
-		ath_tx_do_ratelookup(sc, bf);
+		ath_tx_do_ratelookup(sc, bf, tid->tid, true);
 		bf->bf_state.bfs_rc[3].rix = 0;
 		bf->bf_state.bfs_rc[3].tries = 0;
 
@@ -5644,7 +5650,7 @@ ath_tx_tid_hw_queue_norm(struct ath_softc *sc, struct 
 		ath_tx_update_clrdmask(sc, tid, bf);
 
 		/* Program descriptors + rate control */
-		ath_tx_do_ratelookup(sc, bf);
+		ath_tx_do_ratelookup(sc, bf, tid->tid, false);
 		ath_tx_calc_duration(sc, bf);
 		ath_tx_calc_protection(sc, bf);
 		ath_tx_set_rtscts(sc, bf);

Modified: head/sys/dev/ath/if_athrate.h
==============================================================================
--- head/sys/dev/ath/if_athrate.h	Wed May 13 00:03:39 2020	(r360997)
+++ head/sys/dev/ath/if_athrate.h	Wed May 13 00:05:11 2020	(r360998)
@@ -132,10 +132,15 @@ void	ath_rate_getxtxrates(struct ath_softc *sc, struct
  * is to be setup then try0 should contain a value other than ATH_TXMATRY
  * and ath_rate_setupxtxdesc will be called after deciding if the frame
  * can be transmitted with multi-rate retry.
+ *
+ * maxdur is an optional return value (or -1 if not set) that defines
+ * the maximum frame duration in microseconds.  This allows the rate
+ * control selection to override the maximum duration (normally 4ms)
+ * that the packet aggregation logic makes.
  */
 void	ath_rate_findrate(struct ath_softc *, struct ath_node *,
-		int shortPreamble, size_t frameLen,
-		u_int8_t *rix, int *try0, u_int8_t *txrate);
+		int shortPreamble, size_t frameLen, int tid, bool is_aggr,
+		u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur);
 /*
  * Setup any extended (multi-rate) descriptor state for a data packet.
  * The rate index returned by ath_rate_findrate is passed back in.


More information about the svn-src-all mailing list