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

Adrian Chadd adrian at FreeBSD.org
Sat May 16 05:07:47 UTC 2020


Author: adrian
Date: Sat May 16 05:07:45 2020
New Revision: 361106
URL: https://svnweb.freebsd.org/changeset/base/361106

Log:
  [ath_rate_sample] Limit the tx schedules for A-MPDU ; don't take short retries
  into account and remove the requirement that the MCS rate is "higher" if we're
   considering a new rate.
  
  Ok, another fun one.
  
  * In order for reliable non-software retried higher MCS rates, the TX schedules
    (inconsistently!) use hard-coded lower rates at the end of the schedule.
    Now, hard-coded is a problem because (a) it means that aggregate formation
    is limited by the SLOWEST rate, so I never formed large AMDU frames for
    3 stream rates, and (b) if the AP disables lower rates as base rates, it
    complains about "unknown rix" every frame you transmit at that rate.
  
    So, for now just disable the third and fourth schedule entry for AMPDUs.
    Now I'm forming 32k and 64k aggregates for the higher density MCS rates
    much more reliably.
  
    It would be much nicer if the rate schedule stuff wasn't fixed but instead
    I'd just populate ath_rc_series[] when I fetch the rates.  This is all a
    holdover of ye olde pre-11n stuff and I really just need to nuke it.
  
    But for now, ye hack.
  
  * The check for "is this MCS rate better" based on MCS itself is just garbage.
    It meant things like going MCS0->7 would be fine, and say 0->8->16 is fine,
    (as they're equivalent encoding but 1,2,3 spatial streams), BUT it meant
    going something like MCS7->11 would fail even though it's likely that
    MCS11 would just be better, both for EWMA/BER and throughput.
  
    So for now just use the average tx time.  The "right" way for this comparison
    would be to compare PHY bitrates rather than MCS / rate indexes, but I'm not
    yet there.  The bit rates ARE available in the PHY index, but honestly
    I have a lot of other cleaning up to here before I think about that.
  
  * Don't include the RTS/CTS retry count (and thus time) into the average tx time
    caluation.  It just makes temporarily failures make the rate look bad by
    QUITE A LOT, as RTS/CTS exchanges are (a) long, and (b) mostly irrelevant
    to the actual rate being tried.  If we keep hitting RTS/CTS failures then
    there's something ELSE wrong on the channel, not our selected rate.

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_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	Sat May 16 04:52:29 2020	(r361105)
+++ head/sys/dev/ath/ath_rate/amrr/amrr.c	Sat May 16 05:07:45 2020	(r361106)
@@ -128,7 +128,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
  */
 void
 ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
-    uint8_t rix0, struct ath_rc_series *rc)
+    uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
 {
 	struct amrr_node *amn = ATH_NODE_AMRR(an);
 

Modified: head/sys/dev/ath/ath_rate/onoe/onoe.c
==============================================================================
--- head/sys/dev/ath/ath_rate/onoe/onoe.c	Sat May 16 04:52:29 2020	(r361105)
+++ head/sys/dev/ath/ath_rate/onoe/onoe.c	Sat May 16 05:07:45 2020	(r361106)
@@ -136,7 +136,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
  */
 void
 ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
-    uint8_t rix0, struct ath_rc_series *rc)
+    uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
 {
 	struct onoe_node *on = ATH_NODE_ONOE(an);
 

Modified: head/sys/dev/ath/ath_rate/sample/sample.c
==============================================================================
--- head/sys/dev/ath/ath_rate/sample/sample.c	Sat May 16 04:52:29 2020	(r361105)
+++ head/sys/dev/ath/ath_rate/sample/sample.c	Sat May 16 05:07:45 2020	(r361106)
@@ -168,7 +168,7 @@ static int ath_rate_sample_max_4ms_framelen[4][32] = {
  */
 static int
 ath_rate_sample_find_min_pktlength(struct ath_softc *sc,
-    struct ath_node *an, uint8_t rix0)
+    struct ath_node *an, uint8_t rix0, int is_aggr)
 {
 #define	MCS_IDX(ix)		(rt->info[ix].dot11Rate)
 	const HAL_RATE_TABLE *rt = sc->sc_currates;
@@ -196,6 +196,24 @@ ath_rate_sample_find_min_pktlength(struct ath_softc *s
 	 * is not zero.
 	 *
 	 * Note: assuming all four PHYs are HT!
+	 *
+	 * XXX TODO: right now I hardcode here and in getxtxrates() that
+	 * rates 2 and 3 in the tx schedule are ignored.  This is important
+	 * for forming larger aggregates because right now (a) the tx schedule
+	 * per rate is fixed, and (b) reliable packet transmission at those
+	 * higher rates kinda needs a lower MCS rate in there somewhere.
+	 * However, this means we can only form shorter aggregates.
+	 * If we've negotiated aggregation then we can actually just
+	 * rely on software retransmit rather than having things fall
+	 * back to like MCS0/1 in hardware, and rate control will hopefully
+	 * do the right thing.
+	 *
+	 * Once the whole rate schedule is passed into ath_rate_findrate(),
+	 * the ath_rc_series is populated ,the fixed tx schedule stuff
+	 * is removed AND getxtxrates() is removed then we can remove this
+	 * check as it can just NOT populate t2/t3.  It also means
+	 * probing can actually use rix0 for probeing and rix1 for the
+	 * current best rate..
 	 */
 	if (sched->t0 != 0) {
 		max_pkt_length = MIN(max_pkt_length,
@@ -205,11 +223,11 @@ ath_rate_sample_find_min_pktlength(struct ath_softc *s
 		max_pkt_length = MIN(max_pkt_length,
 		    ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r1)]);
 	}
-	if (sched->t2 != 0) {
+	if (sched->t2 != 0 && (! is_aggr)) {
 		max_pkt_length = MIN(max_pkt_length,
 		    ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r2)]);
 	}
-	if (sched->t3 != 0) {
+	if (sched->t3 != 0 && (! is_aggr)) {
 		max_pkt_length = MIN(max_pkt_length,
 		    ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r3)]);
 	}
@@ -691,7 +709,8 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
 	 * need to potentially update our maximum packet length
 	 * and size_bin if we're doing 11n rates.
 	 */
-	max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an, best_rix);
+	max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an, best_rix,
+	    is_aggr);
 	if (max_pkt_len > 0) {
 #if 0
 		device_printf(sc->sc_dev,
@@ -769,9 +788,9 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
 			int cur_rix = sn->current_rix[size_bin];
 			int cur_att = sn->stats[size_bin][cur_rix].average_tx_time;
 			/*
-			 * If the node is HT, upgrade it if the MCS rate without
-			 * the stream is higher and the average tx time is
-			 * within 10% of the current rate. It can fail a little.
+			 * If the node is HT, it if the rate isn't the
+			 * same and the average tx time is within 10%
+			 * of the current rate. It can fail a little.
 			 *
 			 * This is likely not optimal!
 			 */
@@ -780,7 +799,6 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_nod
 			    MCS(cur_rix), cur_att, MCS(best_rix), average_tx_time);
 #endif
 			if ((best_rix != cur_rix) &&
-			    ((MCS(best_rix) & 0x7) >= (MCS(cur_rix) & 0x7)) &&
 			    (average_tx_time * 9) <= (cur_att * 10)) {
 				IEEE80211_NOTE(an->an_node.ni_vap,
 				    IEEE80211_MSG_RATECTL, &an->an_node,
@@ -864,7 +882,7 @@ done:
  */
 void
 ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
-    uint8_t rix0, struct ath_rc_series *rc)
+    uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
 {
 	struct sample_node *sn = ATH_NODE_SAMPLE(an);
 	const struct txschedule *sched = &sn->sched[rix0];
@@ -881,8 +899,13 @@ ath_rate_getxtxrates(struct ath_softc *sc, struct ath_
 
 	rc[0].tries = sched->t0;
 	rc[1].tries = sched->t1;
-	rc[2].tries = sched->t2;
-	rc[3].tries = sched->t3;
+
+	if (is_aggr) {
+		rc[2].tries = rc[3].tries = 0;
+	} else {
+		rc[2].tries = sched->t2;
+		rc[3].tries = sched->t3;
+	}
 }
 
 void
@@ -940,8 +963,14 @@ update_stats(struct ath_softc *sc, struct ath_node *an
 	if (status != 0)
 		nbad = nframes;
 
-	tt = calc_usecs_unicast_packet(sc, size, rix0, short_tries,
-		MIN(tries0, tries) - 1, is_ht40);
+	/*
+	 * Ignore short tries count as contributing to failure.
+	 * Right now there's no way to know if it's part of any
+	 * given rate attempt, and outside of the RTS/CTS management
+	 * rate, it doesn't /really/ help.
+	 */
+	tt = calc_usecs_unicast_packet(sc, size, rix0,
+	    0 /* short_tries */, MIN(tries0, tries) - 1, is_ht40);
 	tries_so_far = tries0;
 
 	if (sn->stats[size_bin][rix0].total_packets < ssc->smoothing_minpackets) {

Modified: head/sys/dev/ath/if_ath_tx.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx.c	Sat May 16 04:52:29 2020	(r361105)
+++ head/sys/dev/ath/if_ath_tx.c	Sat May 16 05:07:45 2020	(r361106)
@@ -1401,7 +1401,7 @@ ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_
 
 	if (bf->bf_state.bfs_ismrr && try0 != ATH_TXMAXTRY)
 		ath_rate_getxtxrates(sc, ATH_NODE(bf->bf_node), rix,
-		    bf->bf_state.bfs_rc);
+		    is_aggr, bf->bf_state.bfs_rc);
 	ATH_NODE_UNLOCK(ATH_NODE(bf->bf_node));
 
 	sc->sc_txrix = rix;	/* for LED blinking */

Modified: head/sys/dev/ath/if_athrate.h
==============================================================================
--- head/sys/dev/ath/if_athrate.h	Sat May 16 04:52:29 2020	(r361105)
+++ head/sys/dev/ath/if_athrate.h	Sat May 16 05:07:45 2020	(r361106)
@@ -125,7 +125,7 @@ void	ath_rate_newassoc(struct ath_softc *, struct ath_
  * Return the four TX rate index and try counts for the current data packet.
  */
 void	ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
-		uint8_t rix0, struct ath_rc_series *rc);
+		uint8_t rix0, int is_aggr, struct ath_rc_series *rc);
 
 /*
  * Return the transmit info for a data packet.  If multi-rate state


More information about the svn-src-all mailing list