From owner-p4-projects@FreeBSD.ORG Wed May 18 17:00:53 2005 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 27F2316A4D1; Wed, 18 May 2005 17:00:53 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EFD9616A4CE for ; Wed, 18 May 2005 17:00:52 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id C101443D79 for ; Wed, 18 May 2005 17:00:52 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j4IH0qeA051009 for ; Wed, 18 May 2005 17:00:52 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j4IH0q1i051006 for perforce@freebsd.org; Wed, 18 May 2005 17:00:52 GMT (envelope-from sam@freebsd.org) Date: Wed, 18 May 2005 17:00:52 GMT Message-Id: <200505181700.j4IH0q1i051006@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 77139 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 May 2005 17:00:54 -0000 http://perforce.freebsd.org/chv.cgi?CH=77139 Change 77139 by sam@sam_ebb on 2005/05/18 17:00:06 move ps q drain+age to routines Affected files ... .. //depot/projects/vap/sys/net80211/ieee80211_freebsd.h#6 edit .. //depot/projects/vap/sys/net80211/ieee80211_node.c#7 edit Differences ... ==== //depot/projects/vap/sys/net80211/ieee80211_freebsd.h#6 (text+ko) ==== @@ -78,14 +78,14 @@ mtx_init(&(_ni)->ni_savedq.ifq_mtx, _name, "802.11 ps queue", MTX_DEF);\ (_ni)->ni_savedq.ifq_maxlen = IEEE80211_PS_MAX_QUEUE; \ } while (0) -#define IEEE80211_NODE_SAVEQ_DESTROY(_ni) \ +#define IEEE80211_NODE_SAVEQ_DESTROY(_ni) \ mtx_destroy(&(_ni)->ni_savedq.ifq_mtx) -#define IEEE80211_NODE_SAVEQ_QLEN(_ni) \ +#define IEEE80211_NODE_SAVEQ_QLEN(_ni) \ _IF_QLEN(&(_ni)->ni_savedq) -#define IEEE80211_NODE_SAVEQ_LOCK(_ni) do { \ +#define IEEE80211_NODE_SAVEQ_LOCK(_ni) do { \ IF_LOCK(&(_ni)->ni_savedq); \ } while (0) -#define IEEE80211_NODE_SAVEQ_UNLOCK(_ni) do { \ +#define IEEE80211_NODE_SAVEQ_UNLOCK(_ni) do { \ IF_UNLOCK(&(_ni)->ni_savedq); \ } while (0) #define IEEE80211_NODE_SAVEQ_DEQUEUE(_ni, _m, _qlen) do { \ @@ -94,16 +94,6 @@ (_qlen) = IEEE80211_NODE_SAVEQ_QLEN(_ni); \ IEEE80211_NODE_SAVEQ_UNLOCK(_ni); \ } while (0) -#define IEEE80211_NODE_SAVEQ_DRAIN(_ni, _qlen) do { \ - IEEE80211_NODE_SAVEQ_LOCK(_ni); \ - (_qlen) = IEEE80211_NODE_SAVEQ_QLEN(_ni); \ - _IF_DRAIN(&(_ni)->ni_savedq); \ - IEEE80211_NODE_SAVEQ_UNLOCK(_ni); \ -} while (0) -/* XXX could be optimized */ -#define _IEEE80211_NODE_SAVEQ_DEQUEUE_HEAD(_ni, _m) do { \ - _IF_DEQUEUE(&(_ni)->ni_savedq, m); \ -} while (0) #define _IEEE80211_NODE_SAVEQ_ENQUEUE(_ni, _m, _qlen, _age) do {\ (_m)->m_nextpkt = NULL; \ if ((_ni)->ni_savedq.ifq_tail != NULL) { \ ==== //depot/projects/vap/sys/net80211/ieee80211_node.c#7 (text+ko) ==== @@ -66,6 +66,8 @@ static void node_cleanup(struct ieee80211_node *); static void node_free(struct ieee80211_node *); static u_int8_t node_getrssi(const struct ieee80211_node *); +static int node_saveq_drain(struct ieee80211_node *); +static int node_saveq_age(struct ieee80211_node *); static void _ieee80211_free_node(struct ieee80211_node *); @@ -518,7 +520,7 @@ { #define N(a) (sizeof(a)/sizeof(a[0])) struct ieee80211vap *vap = ni->ni_vap; - int i, qlen; + int i; /* NB: preserve ni_table */ if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) { @@ -539,8 +541,7 @@ /* * Drain power save queue and, if needed, clear TIM. */ - IEEE80211_NODE_SAVEQ_DRAIN(ni, qlen); - if (qlen != 0 && vap->iv_set_tim != NULL) + if (node_saveq_drain(ni) != 0 && vap->iv_set_tim != NULL) vap->iv_set_tim(ni, 0); ni->ni_associd = 0; @@ -592,6 +593,73 @@ } /* + * Clear any frames queued on a node's power save queue. + * The number of frames that were present is returned. + */ +static int +node_saveq_drain(struct ieee80211_node *ni) +{ + struct mbuf *m; + int qlen; + + IEEE80211_NODE_SAVEQ_LOCK(ni); + qlen = IEEE80211_NODE_SAVEQ_QLEN(ni); + for (;;) { + _IF_DEQUEUE(&ni->ni_savedq, m); + if (m == NULL) + break; + m_freem(m); + } + IEEE80211_NODE_SAVEQ_UNLOCK(ni); + + return qlen; +} + +/* + * Age frames on the power save queue. The aging interval is + * 4 times the listen interval specified by the station. This + * number is factored into the age calculations when the frame + * is placed on the queue. We store ages as time differences + * so we can check and/or adjust only the head of the list. + * If a frame's age exceeds the threshold then discard it. + * The number of frames discarded is returned so the caller + * can check if it needs to adjust the tim. + */ +static int +node_saveq_age(struct ieee80211_node *ni) +{ + int discard = 0; + + /* XXX racey but good 'nuf? */ + if (IEEE80211_NODE_SAVEQ_QLEN(ni) != 0) { +#ifdef IEEE80211_DEBUG + struct ieee80211vap *vap = ni->ni_vap; +#endif + struct mbuf *m; + + IEEE80211_NODE_SAVEQ_LOCK(ni); + while (IF_POLL(&ni->ni_savedq, m) != NULL && + M_AGE_GET(m) < IEEE80211_INACT_WAIT) { + IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, + "discard frame, age %u", M_AGE_GET(m)); + + /* XXX could be optimized */ + _IF_DEQUEUE(&ni->ni_savedq, m); + m_freem(m); + discard++; + } + if (m != NULL) + M_AGE_SUB(m, IEEE80211_INACT_WAIT); + IEEE80211_NODE_SAVEQ_UNLOCK(ni); + + IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, + "discard %u frames for age", discard); + IEEE80211_NODE_STAT_ADD(ni, ps_discard, discard); + } + return discard; +} + +/* * Create an entry in the specified node table. The node * is setup with the mac address, an initial reference count, * and some basic parameters obtained from global state. @@ -1136,41 +1204,11 @@ if (ni->ni_associd != 0) { struct ieee80211vap *vap = ni->ni_vap; /* - * Age frames on the power save queue. The - * aging interval is 4 times the listen - * interval specified by the station. This - * number is factored into the age calculations - * when the frame is placed on the queue. We - * store ages as time differences we can check - * and/or adjust only the head of the list. + * Age frames on the power save queue. */ - if (IEEE80211_NODE_SAVEQ_QLEN(ni) != 0) { - struct mbuf *m; - int discard = 0; - - IEEE80211_NODE_SAVEQ_LOCK(ni); - while (IF_POLL(&ni->ni_savedq, m) != NULL && - M_AGE_GET(m) < IEEE80211_INACT_WAIT) { -IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, "discard frame, age %u", M_AGE_GET(m));/*XXX*/ - _IEEE80211_NODE_SAVEQ_DEQUEUE_HEAD(ni, m); - m_freem(m); - discard++; - } - if (m != NULL) - M_AGE_SUB(m, IEEE80211_INACT_WAIT); - IEEE80211_NODE_SAVEQ_UNLOCK(ni); - - if (discard != 0) { - IEEE80211_NOTE(vap, - IEEE80211_MSG_POWER, ni, - "discard %u frames for age", - discard); - IEEE80211_NODE_STAT_ADD(ni, - ps_discard, discard); - if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) - vap->iv_set_tim(ni, 0); - } - } + if (node_saveq_age(ni) != 0 && + IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) + vap->iv_set_tim(ni, 0); /* * Probe the station before time it out. We * send a null data frame which may not be