Author: adrian
Date: Thu Sep 24 17:23:41 2015
New Revision: 288178
URL: https://svnweb.freebsd.org/changeset/base/288178

Log:
  Fix up error path handling after the recent churn.
  
  * Don't free the mbuf in the tx path - it uses the transmit path now,
    so the caller frees the mbuf.
  * Don't decrement the node ref upon error - that's up to the caller to
    do as well.
  
  Tested:
  
  * Intel 5300 3x3 wifi, station mode
  
  Noticed by: <[email protected]>

Modified:
  head/sys/dev/iwn/if_iwn.c

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c   Thu Sep 24 16:56:44 2015        (r288177)
+++ head/sys/dev/iwn/if_iwn.c   Thu Sep 24 17:23:41 2015        (r288178)
@@ -4368,7 +4368,6 @@ iwn_tx_data(struct iwn_softc *sc, struct
                struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac];
 
                if (!IEEE80211_AMPDU_RUNNING(tap)) {
-                       m_freem(m);
                        return EINVAL;
                }
 
@@ -4420,7 +4419,6 @@ iwn_tx_data(struct iwn_softc *sc, struct
                /* Retrieve key for TX. */
                k = ieee80211_crypto_encap(ni, m);
                if (k == NULL) {
-                       m_freem(m);
                        return ENOBUFS;
                }
                /* 802.11 header may have moved. */
@@ -4551,7 +4549,6 @@ iwn_tx_data(struct iwn_softc *sc, struct
                if (error != EFBIG) {
                        device_printf(sc->sc_dev,
                            "%s: can't map mbuf (error %d)\n", __func__, error);
-                       m_freem(m);
                        return error;
                }
                /* Too many DMA segments, linearize mbuf. */
@@ -4559,7 +4556,6 @@ iwn_tx_data(struct iwn_softc *sc, struct
                if (m1 == NULL) {
                        device_printf(sc->sc_dev,
                            "%s: could not defrag mbuf\n", __func__);
-                       m_freem(m);
                        return ENOBUFS;
                }
                m = m1;
@@ -4569,7 +4565,6 @@ iwn_tx_data(struct iwn_softc *sc, struct
                if (error != 0) {
                        device_printf(sc->sc_dev,
                            "%s: can't map mbuf (error %d)\n", __func__, error);
-                       m_freem(m);
                        return error;
                }
        }
@@ -4755,7 +4750,6 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
                if (error != EFBIG) {
                        device_printf(sc->sc_dev,
                            "%s: can't map mbuf (error %d)\n", __func__, error);
-                       m_freem(m);
                        return error;
                }
                /* Too many DMA segments, linearize mbuf. */
@@ -4763,7 +4757,6 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
                if (m1 == NULL) {
                        device_printf(sc->sc_dev,
                            "%s: could not defrag mbuf\n", __func__);
-                       m_freem(m);
                        return ENOBUFS;
                }
                m = m1;
@@ -4773,7 +4766,6 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
                if (error != 0) {
                        device_printf(sc->sc_dev,
                            "%s: can't map mbuf (error %d)\n", __func__, error);
-                       m_freem(m);
                        return error;
                }
        }
@@ -4869,6 +4861,9 @@ iwn_xmit_task(void *arg0, int pending)
        IWN_UNLOCK(sc);
 }
 
+/*
+ * raw frame xmit - free node/reference if failed.
+ */
 static int
 iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
     const struct ieee80211_bpf_params *params)
@@ -4931,6 +4926,9 @@ iwn_raw_xmit(struct ieee80211_node *ni, 
        return error;
 }
 
+/*
+ * transmit - don't free mbuf if failed; don't free node ref if failed.
+ */
 static int
 iwn_transmit(struct ieee80211com *ic, struct mbuf *m)
 {
@@ -4938,6 +4936,8 @@ iwn_transmit(struct ieee80211com *ic, st
        struct ieee80211_node *ni;
        int error;
 
+       ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+
        IWN_LOCK(sc);
        if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0 || sc->sc_beacon_wait) {
                IWN_UNLOCK(sc);
@@ -4949,11 +4949,9 @@ iwn_transmit(struct ieee80211com *ic, st
                return (ENOBUFS);
        }
 
-       ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
        error = iwn_tx_data(sc, m, ni);
        if (error) {
                if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
-               ieee80211_free_node(ni);
        } else
                sc->sc_tx_timer = 5;
        IWN_UNLOCK(sc);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to