]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
net80211: separate mbuf cleanup from ieee80211_fragment()
authoradrian <adrian@FreeBSD.org>
Mon, 12 Oct 2015 03:27:08 +0000 (03:27 +0000)
committeradrian <adrian@FreeBSD.org>
Mon, 12 Oct 2015 03:27:08 +0000 (03:27 +0000)
* Create ieee80211_free_mbuf() which frees a list of mbufs.
* Use it in the fragment transmit path and ath / uath transmit paths.
* Call it in xmit_pkt() if the transmission fails; otherwise fragments
  may be leaked.

This should be a big no-op.

Submitted by: <s3erios@gmail.com>
Differential Revision: https://reviews.freebsd.org/D3769

sys/dev/ath/if_ath.c
sys/dev/ath/if_ath_tx.c
sys/dev/ath/if_ath_tx.h
sys/dev/usb/wlan/if_uath.c
sys/net80211/ieee80211_freebsd.c
sys/net80211/ieee80211_output.c
sys/net80211/ieee80211_proto.h

index 8ba09585ebb29fea748229bc34722c76670b22c4..4166bb73d69744b0ac6613d4c66a59ec2b785128 100644 (file)
@@ -3262,7 +3262,7 @@ ath_transmit(struct ieee80211com *ic, struct mbuf *m)
                 * XXXGL: is mbuf valid after ath_txfrag_setup? If yes,
                 * we shouldn't free it but return back.
                 */
-               ath_freetx(m);
+               ieee80211_free_mbuf(m);
                m = NULL;
                goto bad;
        }
@@ -3356,7 +3356,7 @@ reclaim:
                            __func__,
                            ieee80211_state_name[ni->ni_vap->iv_state]);
                        /* XXX dmamap */
-                       ath_freetx(next);
+                       ieee80211_free_mbuf(next);
                        goto reclaim;
                }
                m = next;
index bee632001480fbbe4667e6289b0d06f9b5aedbe6..27a17d2fdcc213dcefdd6db51fdc188d06505eb8 100644 (file)
@@ -283,22 +283,6 @@ ath_txfrag_setup(struct ath_softc *sc, ath_bufhead *frags,
        return !TAILQ_EMPTY(frags);
 }
 
-/*
- * Reclaim mbuf resources.  For fragmented frames we
- * need to claim each frag chained with m_nextpkt.
- */
-void
-ath_freetx(struct mbuf *m)
-{
-       struct mbuf *next;
-
-       do {
-               next = m->m_nextpkt;
-               m->m_nextpkt = NULL;
-               m_freem(m);
-       } while ((m = next) != NULL);
-}
-
 static int
 ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
 {
@@ -317,7 +301,7 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
                bf->bf_nseg = ATH_MAX_SCATTER + 1;
        } else if (error != 0) {
                sc->sc_stats.ast_tx_busdma++;
-               ath_freetx(m0);
+               ieee80211_free_mbuf(m0);
                return error;
        }
        /*
@@ -329,7 +313,7 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
                sc->sc_stats.ast_tx_linear++;
                m = m_collapse(m0, M_NOWAIT, ATH_MAX_SCATTER);
                if (m == NULL) {
-                       ath_freetx(m0);
+                       ieee80211_free_mbuf(m0);
                        sc->sc_stats.ast_tx_nombuf++;
                        return ENOMEM;
                }
@@ -339,14 +323,14 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
                                             BUS_DMA_NOWAIT);
                if (error != 0) {
                        sc->sc_stats.ast_tx_busdma++;
-                       ath_freetx(m0);
+                       ieee80211_free_mbuf(m0);
                        return error;
                }
                KASSERT(bf->bf_nseg <= ATH_MAX_SCATTER,
                    ("too many segments after defrag; nseg %u", bf->bf_nseg));
        } else if (bf->bf_nseg == 0) {          /* null packet, discard */
                sc->sc_stats.ast_tx_nodata++;
-               ath_freetx(m0);
+               ieee80211_free_mbuf(m0);
                return EIO;
        }
        DPRINTF(sc, ATH_DEBUG_XMIT, "%s: m %p len %u\n",
@@ -1581,7 +1565,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
        /* Handle encryption twiddling if needed */
        if (! ath_tx_tag_crypto(sc, ni, m0, iswep, isfrag, &hdrlen,
            &pktlen, &keyix)) {
-               ath_freetx(m0);
+               ieee80211_free_mbuf(m0);
                return EIO;
        }
 
@@ -1693,7 +1677,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
                    wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
                /* XXX statistic */
                /* XXX free tx dmamap */
-               ath_freetx(m0);
+               ieee80211_free_mbuf(m0);
                return EIO;
        }
 
@@ -1749,7 +1733,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
                    "%s: discard frame, ACK required w/ TDMA\n", __func__);
                sc->sc_stats.ast_tdma_ack++;
                /* XXX free tx dmamap */
-               ath_freetx(m0);
+               ieee80211_free_mbuf(m0);
                return EIO;
        }
 #endif
@@ -2133,7 +2117,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
        if (! ath_tx_tag_crypto(sc, ni,
            m0, params->ibp_flags & IEEE80211_BPF_CRYPTO, 0,
            &hdrlen, &pktlen, &keyix)) {
-               ath_freetx(m0);
+               ieee80211_free_mbuf(m0);
                return EIO;
        }
        /* packet header may have moved, reset our local pointer */
index 281dbcb0daef11fb726e057c699e521794f51eac..19f7707a24312fd48aea2423b0cb66c6cdc48db2 100644 (file)
@@ -85,7 +85,6 @@
  */
 #define        ATH_AGGR_MAXSIZE        65530
 
-extern void ath_freetx(struct mbuf *m);
 extern void ath_tx_node_flush(struct ath_softc *sc, struct ath_node *an);
 extern void ath_tx_txq_drain(struct ath_softc *sc, struct ath_txq *txq);
 extern void ath_txfrag_cleanup(struct ath_softc *sc, ath_bufhead *frags,
index 39fa71b286388324bbf1b5f98f89484d085def49..292bb9f6626ed6b2cb41053ca4099eaac210030a 100644 (file)
@@ -1663,22 +1663,6 @@ uath_txfrag_setup(struct uath_softc *sc, uath_datahead *frags,
        return !STAILQ_EMPTY(frags);
 }
 
-/*
- * Reclaim mbuf resources.  For fragmented frames we need to claim each frag
- * chained with m_nextpkt.
- */
-static void
-uath_freetx(struct mbuf *m)
-{
-       struct mbuf *next;
-
-       do {
-               next = m->m_nextpkt;
-               m->m_nextpkt = NULL;
-               m_freem(m);
-       } while ((m = next) != NULL);
-}
-
 static int
 uath_transmit(struct ieee80211com *ic, struct mbuf *m)   
 {
@@ -1735,7 +1719,7 @@ uath_start(struct uath_softc *sc)
                    !uath_txfrag_setup(sc, &frags, m, ni)) {
                        DPRINTF(sc, UATH_DEBUG_XMIT,
                            "%s: out of txfrag buffers\n", __func__);
-                       uath_freetx(m);
+                       ieee80211_free_mbuf(m);
                        goto bad;
                }
                sc->sc_seqnum = 0;
@@ -1770,7 +1754,7 @@ uath_start(struct uath_softc *sc)
                                    "%s: flush fragmented packet, state %s\n",
                                    __func__,
                                    ieee80211_state_name[ni->ni_vap->iv_state]);
-                               uath_freetx(next);
+                               ieee80211_free_mbuf(next);
                                goto reclaim;
                        }
                        m = next;
index 6fdfb5cd31c8ec3fa9af15be7ec42a500330a606..5b2c103aaa210221c570909891f5707d22bb7f6e 100644 (file)
@@ -545,7 +545,7 @@ ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
        IEEE80211_TX_LOCK_ASSERT(ic);
        error = ic->ic_transmit(ic, m);
        if (error)
-               m_freem(m);
+               ieee80211_free_mbuf(m);
        return (error);
 }
 
index 19af613982e27b3b2cb8f5c032a9e3915457fe49..149b726ce1fbf1b876e8af57f49a0d2135bfa7ae 100644 (file)
@@ -1583,6 +1583,21 @@ bad:
 #undef MC01
 }
 
+void
+ieee80211_free_mbuf(struct mbuf *m)
+{
+       struct mbuf *next;
+
+       if (m == NULL)
+               return;
+
+       do {
+               next = m->m_nextpkt;
+               m->m_nextpkt = NULL;
+               m_freem(m);
+       } while ((m = next) != NULL);
+}
+
 /*
  * Fragment the frame according to the specified mtu.
  * The size of the 802.11 header (w/o padding) is provided
@@ -1597,7 +1612,7 @@ ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
 {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_frame *wh, *whf;
-       struct mbuf *m, *prev, *next;
+       struct mbuf *m, *prev;
        u_int totalhdrsize, fragno, fragsize, off, remainder, payload;
        u_int hdrspace;
 
@@ -1692,11 +1707,7 @@ ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
        return 1;
 bad:
        /* reclaim fragments but leave original frame for caller to free */
-       for (m = m0->m_nextpkt; m != NULL; m = next) {
-               next = m->m_nextpkt;
-               m->m_nextpkt = NULL;            /* XXX paranoid */
-               m_freem(m);
-       }
+       ieee80211_free_mbuf(m0->m_nextpkt);
        m0->m_nextpkt = NULL;
        return 0;
 }
index 43058632d11637586b9454b83628d5a2f86e7d0b..38bd3d60259574598141349fd2ac7eca66afedfa 100644 (file)
@@ -93,6 +93,7 @@ struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int,
                struct ieee80211_key *, struct mbuf *);
 struct mbuf *ieee80211_encap(struct ieee80211vap *, struct ieee80211_node *,
                struct mbuf *);
+void   ieee80211_free_mbuf(struct mbuf *);
 int    ieee80211_send_mgmt(struct ieee80211_node *, int, int);
 struct ieee80211_appie;
 int    ieee80211_send_probereq(struct ieee80211_node *ni,