PERFORCE change 135072 for review

Sam Leffler sam at FreeBSD.org
Fri Feb 8 15:23:55 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=135072

Change 135072 by sam at sam_ebb on 2008/02/08 23:23:09

	track pps on ampdu-capable ac's and enable ampdu use when
	traffic crosses a threshold; we also provide access to these
	stats so drivers that want to maintain a cache of active BA
	streams can use them in making policy decisions

Affected files ...

.. //depot/projects/vap/sys/net80211/ieee80211_crypto_none.c#10 edit
.. //depot/projects/vap/sys/net80211/ieee80211_freebsd.c#17 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ht.c#9 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ht.h#7 edit
.. //depot/projects/vap/sys/net80211/ieee80211_output.c#28 edit
.. //depot/projects/vap/sys/net80211/ieee80211_var.h#25 edit

Differences ...

==== //depot/projects/vap/sys/net80211/ieee80211_crypto_none.c#10 (text+ko) ====

@@ -32,6 +32,7 @@
 #include "opt_wlan.h"
 
 #include <sys/param.h>
+#include <sys/kernel.h> 
 #include <sys/systm.h> 
 #include <sys/mbuf.h>   
 #include <sys/module.h>

==== //depot/projects/vap/sys/net80211/ieee80211_freebsd.c#17 (text+ko) ====

@@ -195,6 +195,22 @@
 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
 		"bmiss_max", CTLFLAG_RW, &vap->iv_bmiss_max, 0,
 		"consecutive beacon misses before scanning");
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+		"ampdu_mintraffic_bk", CTLFLAG_RW,
+		&vap->iv_ampdu_mintraffic[WME_AC_BK], 0,
+		"BK traffic tx aggr threshold (pps)");
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+		"ampdu_mintraffic_be", CTLFLAG_RW,
+		&vap->iv_ampdu_mintraffic[WME_AC_BE], 0,
+		"BE traffic tx aggr threshold (pps)");
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+		"ampdu_mintraffic_vo", CTLFLAG_RW,
+		&vap->iv_ampdu_mintraffic[WME_AC_VO], 0,
+		"VO traffic tx aggr threshold (pps)");
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+		"ampdu_mintraffic_vi", CTLFLAG_RW,
+		&vap->iv_ampdu_mintraffic[WME_AC_VI], 0,
+		"VI traffic tx aggr threshold (pps)");
 	vap->iv_sysctl = ctx;
 }
 

==== //depot/projects/vap/sys/net80211/ieee80211_ht.c#9 (text+ko) ====

@@ -135,6 +135,11 @@
 	vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_NA;
 	vap->iv_ampdu_limit = vap->iv_ampdu_rxmax;
 	vap->iv_amsdu_limit = vap->iv_htcaps & IEEE80211_HTCAP_MAXAMSDU;
+	/* tx aggregation traffic thresholds */
+	vap->iv_ampdu_mintraffic[WME_AC_BK] = 128;
+	vap->iv_ampdu_mintraffic[WME_AC_BE] = 64;
+	vap->iv_ampdu_mintraffic[WME_AC_VO] = 32;
+	vap->iv_ampdu_mintraffic[WME_AC_VI] = 32;
 
 	if (vap->iv_htcaps & IEEE80211_HTC_HT) {
 		/*
@@ -781,6 +786,8 @@
 			 */
 			ic->ic_addba_stop(ni, &ni->ni_tx_ampdu[i]);
 			IEEE80211_TAPQ_DESTROY(tap);
+			tap->txa_lastsample = 0;
+			tap->txa_avgpps = 0;
 			/* NB: clearing NAK means we may re-send ADDBA */ 
 			tap->txa_flags &=
 			    ~(IEEE80211_AGGR_SETUP | IEEE80211_AGGR_NAK);
@@ -1532,6 +1539,11 @@
 	int tid, dialogtoken;
 	static int tokens = 0;	/* XXX */
 
+	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni,
+	    "%s: enable AMPDU on %s, avgpps %d pkts %d",
+	    __func__, ieee80211_wme_acnames[tap->txa_ac],
+	    tap->txa_avgpps, tap->txa_pkts);
+
 	/* XXX locking */
 	if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) {
 		/* do deferred setup of state */

==== //depot/projects/vap/sys/net80211/ieee80211_ht.h#7 (text+ko) ====

@@ -46,6 +46,9 @@
 #define	IEEE80211_AGGR_NAK		0x0010	/* peer NAK'd ADDBA request */
 	uint8_t		txa_ac;
 	uint8_t		txa_token;	/* dialog token */
+	int		txa_lastsample;	/* ticks @ last traffic sample */
+	int		txa_pkts;	/* packets over last sample interval */
+	int		txa_avgpps;	/* filtered traffic over window */
 	int		txa_qbytes;	/* data queued (bytes) */
 	short		txa_qframes;	/* data queued (frames) */
 	ieee80211_seq	txa_seqstart;
@@ -67,6 +70,65 @@
 	(((tap)->txa_flags & \
 	 (IEEE80211_AGGR_RUNNING|IEEE80211_AGGR_XCHGPEND|IEEE80211_AGGR_NAK)) != 0)
 
+/*
+ * Traffic estimator support.  We estimate packets/sec for
+ * each AC that is setup for AMPDU or will potentially be
+ * setup for AMPDU.  The traffic rate can be used to decide
+ * when AMPDU should be setup (according to a threshold)
+ * and is available for drivers to do things like cache
+ * eviction when only a limited number of BA streams are
+ * available and more streams are requested than available.
+ */
+
+static void __inline
+ieee80211_txampdu_update_pps(struct ieee80211_tx_ampdu *tap)
+{
+	/* NB: scale factor of 2 was picked heuristically */
+	tap->txa_avgpps = ((tap->txa_avgpps << 2) -
+	     tap->txa_avgpps + tap->txa_pkts) >> 2;
+}
+
+/*
+ * Count a packet towards the pps estimate.
+ */
+static void __inline
+ieee80211_txampdu_count_packet(struct ieee80211_tx_ampdu *tap)
+{
+	/* XXX bound loop/do more crude estimate? */
+	while (ticks - tap->txa_lastsample >= hz) {
+		ieee80211_txampdu_update_pps(tap);
+		/* reset to start new sample interval */
+		tap->txa_pkts = 0;
+		if (tap->txa_avgpps == 0) {
+			tap->txa_lastsample = ticks;
+			break;
+		}
+		tap->txa_lastsample += hz;
+	}
+	tap->txa_pkts++;
+}
+
+/*
+ * Get the current pps estimate.  If the average is out of
+ * date due to lack of traffic then we decay the estimate
+ * to account for the idle time.
+ */
+static int __inline
+ieee80211_txampdu_getpps(struct ieee80211_tx_ampdu *tap)
+{
+	/* XXX bound loop/do more crude estimate? */
+	while (ticks - tap->txa_lastsample >= hz) {
+		ieee80211_txampdu_update_pps(tap);
+		tap->txa_pkts = 0;
+		if (tap->txa_avgpps == 0) {
+			tap->txa_lastsample = ticks;
+			break;
+		}
+		tap->txa_lastsample += hz;
+	}
+	return tap->txa_avgpps;
+}
+
 struct ieee80211_rx_ampdu {
 	int		rxa_flags;
 	int		rxa_qbytes;	/* data queued (bytes) */
@@ -106,7 +168,7 @@
 void	ieee80211_ht_wds_init(struct ieee80211_node *);
 void	ieee80211_ht_node_join(struct ieee80211_node *);
 void	ieee80211_ht_node_leave(struct ieee80211_node *);
-void	ieee80211_htinfo_update(struct ieee80211com *, int protmode);
+void	ieee80211_htprot_update(struct ieee80211com *, int protmode);
 void	ieee80211_ht_timeout(struct ieee80211com *);
 void	ieee80211_parse_htcap(struct ieee80211_node *, const uint8_t *);
 void	ieee80211_parse_htinfo(struct ieee80211_node *, const uint8_t *);

==== //depot/projects/vap/sys/net80211/ieee80211_output.c#28 (text+ko) ====

@@ -1013,8 +1013,8 @@
 		/*
 		 * Check if A-MPDU tx aggregation is setup or if we
 		 * should try to enable it.  The sta must be associated
-		 * with HT and A-MPDU enabled for use.  On the first
-		 * frame that goes out We issue an ADDBA request and
+		 * with HT and A-MPDU enabled for use.  When traffic
+		 * passes a threshold we issue an ADDBA request and
 		 * wait for a reply.  The frame being encapsulated
 		 * will go out w/o using A-MPDU, or possibly it might
 		 * be collected by the driver and held/retransmit.
@@ -1026,12 +1026,14 @@
 		    (vap->iv_flags_ext & IEEE80211_FEXT_AMPDU_TX)) {
 			struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac];
 
+			ieee80211_txampdu_count_packet(tap);
 			if (IEEE80211_AMPDU_RUNNING(tap)) {
 				/*
 				 * Operational, mark frame for aggregation.
 				 */
 				qos[0] |= IEEE80211_QOS_ACKPOLICY_BA;
-			} else if (!IEEE80211_AMPDU_REQUESTED(tap)) {
+			} else if (!IEEE80211_AMPDU_REQUESTED(tap) &&
+			    tap->txa_avgpps >= vap->iv_ampdu_mintraffic[tap->txa_ac]) {
 				/*
 				 * Not negotiated yet, request service.
 				 */

==== //depot/projects/vap/sys/net80211/ieee80211_var.h#25 (text+ko) ====

@@ -325,6 +325,7 @@
 	int			iv_ampdu_density;/* A-MPDU density */
 	int			iv_ampdu_limit;	/* A-MPDU tx limit (bytes) */
 	int			iv_amsdu_limit;	/* A-MSDU tx limit (bytes) */
+	u_int			iv_ampdu_mintraffic[WME_NUM_AC];
 
 	uint32_t		*iv_aid_bitmap;	/* association id map */
 	uint16_t		iv_max_aid;


More information about the p4-projects mailing list