From owner-svn-src-all@FreeBSD.ORG Tue Jan 15 17:50:08 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 7AE7ACFE; Tue, 15 Jan 2013 17:50:08 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 5D95DB27; Tue, 15 Jan 2013 17:50:08 +0000 (UTC) Received: from svn.freebsd.org (svn.FreeBSD.org [8.8.178.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0FHo89A019667; Tue, 15 Jan 2013 17:50:08 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0FHo88B019659; Tue, 15 Jan 2013 17:50:08 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201301151750.r0FHo88B019659@svn.freebsd.org> From: Adrian Chadd Date: Tue, 15 Jan 2013 17:50:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r245464 - head/sys/net80211 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jan 2013 17:50:08 -0000 Author: adrian Date: Tue Jan 15 17:50:07 2013 New Revision: 245464 URL: http://svnweb.freebsd.org/changeset/base/245464 Log: Remove the use of the ifnet send queue and if_start() in the power save queue code. Instead, use if_transmit() directly - and handle the cases where frame transmission fails. I don't necessarily like this and I think at this point the M_ENCAP check, node freeing upon fail and the actual if_transmit() call should be done in methods in ieee80211_freebsd.c, but I digress slightly.. This removes one of the last few uses of if_start() and the ifnet if_snd queue. The last major offender is ieee80211_output.c, where ieee80211_start() implements if_start() and uses the ifnet queue directly. (There's a couple of gotchas here, where the if_start pointer is compared to ieee80211_start(), but that's a later problem.) Modified: head/sys/net80211/ieee80211_power.c Modified: head/sys/net80211/ieee80211_power.c ============================================================================== --- head/sys/net80211/ieee80211_power.c Tue Jan 15 17:17:54 2013 (r245463) +++ head/sys/net80211/ieee80211_power.c Tue Jan 15 17:50:07 2013 (r245464) @@ -416,6 +416,8 @@ pwrsave_flushq(struct ieee80211_node *ni struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_psq_head *qhead; struct ifnet *parent, *ifp; + struct mbuf *parent_q = NULL, *ifp_q = NULL; + struct mbuf *m; IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, "flush ps queue, %u packets queued", psq->psq_len); @@ -427,8 +429,7 @@ pwrsave_flushq(struct ieee80211_node *ni parent = vap->iv_ic->ic_ifp; /* XXX need different driver interface */ /* XXX bypasses q max and OACTIVE */ - IF_PREPEND_LIST(&parent->if_snd, qhead->head, qhead->tail, - qhead->len); + parent_q = qhead->head; qhead->head = qhead->tail = NULL; qhead->len = 0; } else @@ -439,8 +440,7 @@ pwrsave_flushq(struct ieee80211_node *ni ifp = vap->iv_ifp; /* XXX need different driver interface */ /* XXX bypasses q max and OACTIVE */ - IF_PREPEND_LIST(&ifp->if_snd, qhead->head, qhead->tail, - qhead->len); + ifp_q = qhead->head; qhead->head = qhead->tail = NULL; qhead->len = 0; } else @@ -450,10 +450,34 @@ pwrsave_flushq(struct ieee80211_node *ni /* NB: do this outside the psq lock */ /* XXX packets might get reordered if parent is OACTIVE */ - if (parent != NULL) - if_start(parent); - if (ifp != NULL) - if_start(ifp); + /* parent frames, should be encapsulated */ + if (parent != NULL) { + while (parent_q != NULL) { + m = parent_q; + parent_q = m->m_nextpkt; + /* must be encapsulated */ + KASSERT((m->m_flags & M_ENCAP), + ("%s: parentq with non-M_ENCAP frame!\n", + __func__)); + /* + * For encaped frames, we need to free the node + * reference upon failure. + */ + if (parent->if_transmit(parent, m) != 0) + ieee80211_free_node(ni); + } + } + + /* VAP frames, aren't encapsulated */ + if (ifp != NULL) { + while (ifp_q != NULL) { + m = ifp_q; + ifp_q = m->m_nextpkt; + KASSERT((!(m->m_flags & M_ENCAP)), + ("%s: vapq with M_ENCAP frame!\n", __func__)); + (void) ifp->if_transmit(ifp, m); + } + } } /*