For bge(4), dc(4), lge(4), ndis(4), nge(4), pcn(4), re(4), sis(4), sk(4), ti(4)
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 29 Sep 2005 12:52:51 +0000 (12:52 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 29 Sep 2005 12:52:51 +0000 (12:52 +0000)
- Do not start tx engine or set if_timer, if there is nothing to be sent
- Let if_watchdog() kick if_start().  This may avoid a possible race (in the
  future) between testing/setting if_timer and calling if_watchdog().  Only
  bge(4), re(4), sk(4) and ti(4) require this change.  The rest drivers
  affected by this commit already have this in place.

Discussed-with: joerg
Reviewed-by: joerg
sys/dev/netif/bge/if_bge.c
sys/dev/netif/dc/if_dc.c
sys/dev/netif/lge/if_lge.c
sys/dev/netif/ndis/if_ndis.c
sys/dev/netif/nge/if_nge.c
sys/dev/netif/pcn/if_pcn.c
sys/dev/netif/re/if_re.c
sys/dev/netif/sis/if_sis.c
sys/dev/netif/sk/if_sk.c
sys/dev/netif/ti/if_ti.c

index ba76e3c..86ef202 100644 (file)
@@ -31,7 +31,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/bge/if_bge.c,v 1.3.2.29 2003/12/01 21:06:59 ambrisko Exp $
- * $DragonFly: src/sys/dev/netif/bge/if_bge.c,v 1.46 2005/08/22 18:29:52 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/bge/if_bge.c,v 1.47 2005/09/29 12:52:51 sephe Exp $
  *
  */
 
@@ -2376,6 +2376,7 @@ bge_start(struct ifnet *ifp)
        struct bge_softc *sc;
        struct mbuf *m_head = NULL;
        uint32_t prodidx = 0;
+       int need_trans;
 
        sc = ifp->if_softc;
 
@@ -2384,6 +2385,7 @@ bge_start(struct ifnet *ifp)
 
        prodidx = CSR_READ_4(sc, BGE_MBX_TX_HOST_PROD0_LO);
 
+       need_trans = 0;
        while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
                m_head = ifq_poll(&ifp->if_snd);
                if (m_head == NULL)
@@ -2416,10 +2418,14 @@ bge_start(struct ifnet *ifp)
                        break;
                }
                m_head = ifq_dequeue(&ifp->if_snd);
+               need_trans = 1;
 
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_trans)
+               return;
+
        /* Transmit */
        CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
        /* 5700 b2 errata */
@@ -2730,6 +2736,9 @@ bge_watchdog(struct ifnet *ifp)
        bge_init(sc);
 
        ifp->if_oerrors++;
+
+       if (!ifq_is_empty(&ifp->if_snd))
+               ifp->if_start(ifp);
 }
 
 /*
index d81b88b..0936304 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_dc.c,v 1.9.2.45 2003/06/08 14:31:53 mux Exp $
- * $DragonFly: src/sys/dev/netif/dc/if_dc.c,v 1.42 2005/09/08 10:26:20 sephe Exp $
+ * $DragonFly: src/sys/dev/netif/dc/if_dc.c,v 1.43 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -2916,7 +2916,7 @@ dc_start(struct ifnet *ifp)
 {
        struct dc_softc         *sc;
        struct mbuf *m_head = NULL, *m_new;
-       int did_defrag, idx;
+       int did_defrag, idx, need_trans;
 
        sc = ifp->if_softc;
 
@@ -2928,6 +2928,7 @@ dc_start(struct ifnet *ifp)
 
        idx = sc->dc_cdata.dc_tx_prod;
 
+       need_trans = 0;
        while(sc->dc_cdata.dc_tx_chain[idx] == NULL) {
                did_defrag = 0;
                m_head = ifq_poll(&ifp->if_snd);
@@ -2977,6 +2978,7 @@ dc_start(struct ifnet *ifp)
                m_new = ifq_dequeue(&ifp->if_snd);
                if (did_defrag)
                        m_freem(m_new);
+               need_trans = 1;
 
                /*
                 * If there's a BPF listener, bounce a copy of this frame
@@ -2990,6 +2992,9 @@ dc_start(struct ifnet *ifp)
                }
        }
 
+       if (!need_trans)
+               return;
+
        /* Transmit */
        sc->dc_cdata.dc_tx_prod = idx;
        if (!(sc->dc_flags & DC_TX_POLL))
@@ -2999,8 +3004,6 @@ dc_start(struct ifnet *ifp)
         * Set a timeout in case the chip goes out to lunch.
         */
        ifp->if_timer = 5;
-
-       return;
 }
 
 static void
index 606088c..3c0369d 100644 (file)
@@ -31,7 +31,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/lge/if_lge.c,v 1.5.2.2 2001/12/14 19:49:23 jlemon Exp $
- * $DragonFly: src/sys/dev/netif/lge/if_lge.c,v 1.29 2005/06/14 15:08:16 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/lge/if_lge.c,v 1.30 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -1106,6 +1106,7 @@ lge_start(struct ifnet *ifp)
        struct lge_softc *sc = ifp->if_softc;
        struct mbuf *m_head = NULL;
        uint32_t idx;
+       int need_timer;
 
        if (!sc->lge_link)
                return;
@@ -1115,6 +1116,7 @@ lge_start(struct ifnet *ifp)
        if (ifp->if_flags & IFF_OACTIVE)
                return;
 
+       need_timer = 0;
        while(sc->lge_ldata->lge_tx_list[idx].lge_mbuf == NULL) {
                if (CSR_READ_1(sc, LGE_TXCMDFREE_8BIT) == 0)
                        break;
@@ -1128,10 +1130,14 @@ lge_start(struct ifnet *ifp)
                        break;
                }
                m_head = ifq_dequeue(&ifp->if_snd);
+               need_timer = 1;
 
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_timer)
+               return;
+
        sc->lge_cdata.lge_tx_prod = idx;
 
        /*
index 4a2aa57..9aa61c2 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/if_ndis/if_ndis.c,v 1.65 2004/07/07 17:46:30 wpaul Exp $
- * $DragonFly: src/sys/dev/netif/ndis/if_ndis.c,v 1.7 2005/08/11 03:22:57 corecode Exp $
+ * $DragonFly: src/sys/dev/netif/ndis/if_ndis.c,v 1.8 2005/09/29 12:52:51 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -1248,6 +1248,11 @@ ndis_start(ifp)
                        break;
        }
 
+       if (pcnt == 0) {
+               NDIS_UNLOCK(sc);
+               return;
+       }
+
        if (sc->ndis_txpending == 0)
                ifp->if_flags |= IFF_OACTIVE;
 
index e363124..174c7ec 100644 (file)
@@ -31,7 +31,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/nge/if_nge.c,v 1.13.2.13 2003/02/05 22:03:57 mbr Exp $
- * $DragonFly: src/sys/dev/netif/nge/if_nge.c,v 1.29 2005/06/13 20:09:24 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/nge/if_nge.c,v 1.30 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -1604,6 +1604,7 @@ nge_start(struct ifnet *ifp)
        struct nge_softc *sc = ifp->if_softc;
        struct mbuf *m_head = NULL;
        uint32_t idx;
+       int need_trans;
 
        if (!sc->nge_link)
                return;
@@ -1613,6 +1614,7 @@ nge_start(struct ifnet *ifp)
        if (ifp->if_flags & IFF_OACTIVE)
                return;
 
+       need_trans = 0;
        while(sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) {
                m_head = ifq_poll(&ifp->if_snd);
                if (m_head == NULL)
@@ -1623,10 +1625,14 @@ nge_start(struct ifnet *ifp)
                        break;
                }
                m_head = ifq_dequeue(&ifp->if_snd);
+               need_trans = 1;
 
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_trans)
+               return;
+
        /* Transmit */
        sc->nge_cdata.nge_tx_prod = idx;
        NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_ENABLE);
index 2fe095b..a787dd1 100644 (file)
@@ -31,7 +31,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_pcn.c,v 1.5.2.10 2003/03/05 18:42:33 njl Exp $
- * $DragonFly: src/sys/dev/netif/pcn/if_pcn.c,v 1.22 2005/06/20 15:10:41 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/pcn/if_pcn.c,v 1.23 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -1012,6 +1012,7 @@ static void pcn_start(ifp)
        struct pcn_softc        *sc;
        struct mbuf             *m_head = NULL;
        u_int32_t               idx;
+       int need_trans;
 
        sc = ifp->if_softc;
 
@@ -1023,6 +1024,7 @@ static void pcn_start(ifp)
        if (ifp->if_flags & IFF_OACTIVE)
                return;
 
+       need_trans = 0;
        while(sc->pcn_cdata.pcn_tx_chain[idx] == NULL) {
                m_head = ifq_poll(&ifp->if_snd);
                if (m_head == NULL)
@@ -1033,10 +1035,14 @@ static void pcn_start(ifp)
                        break;
                }
                m_head = ifq_dequeue(&ifp->if_snd);
+               need_trans = 1;
 
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_trans)
+               return;
+
        /* Transmit */
        sc->pcn_cdata.pcn_tx_prod = idx;
        pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_TX|PCN_CSR_INTEN);
@@ -1045,8 +1051,6 @@ static void pcn_start(ifp)
         * Set a timeout in case the chip goes out to lunch.
         */
        ifp->if_timer = 5;
-
-       return;
 }
 
 void pcn_setfilt(ifp)
index 9db6dc5..2e72421 100644 (file)
@@ -33,7 +33,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/re/if_re.c,v 1.25 2004/06/09 14:34:01 naddy Exp $
- * $DragonFly: src/sys/dev/netif/re/if_re.c,v 1.14 2005/06/09 20:04:44 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/re/if_re.c,v 1.15 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -1808,12 +1808,13 @@ re_start(struct ifnet *ifp)
 {
        struct re_softc *sc = ifp->if_softc;
        struct mbuf *m_head = NULL, *m_head2;
-       int called_defrag, idx;
+       int called_defrag, idx, need_trans;
 
        crit_enter();
 
        idx = sc->re_ldata.re_tx_prodidx;
 
+       need_trans = 0;
        while (sc->re_ldata.re_tx_mbuf[idx] == NULL) {
                m_head = ifq_poll(&ifp->if_snd);
                if (m_head == NULL)
@@ -1831,6 +1832,7 @@ re_start(struct ifnet *ifp)
                m_head2 = ifq_dequeue(&ifp->if_snd);
                if (called_defrag)
                        m_freem(m_head2);
+               need_trans = 1;
 
                /*
                 * If there's a BPF listener, bounce a copy of this frame
@@ -1839,6 +1841,11 @@ re_start(struct ifnet *ifp)
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_trans) {
+               crit_exit();
+               return;
+       }
+
        /* Flush the TX descriptors */
        bus_dmamap_sync(sc->re_ldata.re_tx_list_tag,
                        sc->re_ldata.re_tx_list_map,
@@ -2145,6 +2152,9 @@ re_watchdog(struct ifnet *ifp)
 
        re_init(sc);
 
+       if (!ifq_is_empty(&ifp->if_snd))
+               ifp->if_start(ifp);
+
        crit_exit();
 }
 
index b14c01c..fdb9d77 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_sis.c,v 1.13.4.24 2003/03/05 18:42:33 njl Exp $
- * $DragonFly: src/sys/dev/netif/sis/if_sis.c,v 1.25 2005/08/29 10:19:52 sephe Exp $
+ * $DragonFly: src/sys/dev/netif/sis/if_sis.c,v 1.26 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -1829,6 +1829,7 @@ sis_start(struct ifnet *ifp)
        struct sis_softc *sc;
        struct mbuf *m_head = NULL;
        uint32_t idx;
+       int need_trans;
 
        sc = ifp->if_softc;
 
@@ -1840,6 +1841,7 @@ sis_start(struct ifnet *ifp)
        if (ifp->if_flags & IFF_OACTIVE)
                return;
 
+       need_trans = 0;
        while(sc->sis_ldata.sis_tx_list[idx].sis_mbuf == NULL) {
                m_head = ifq_poll(&ifp->if_snd);
                if (m_head == NULL)
@@ -1850,6 +1852,7 @@ sis_start(struct ifnet *ifp)
                        break;
                }
                m_head = ifq_dequeue(&ifp->if_snd);
+               need_trans = 1;
 
                /*
                 * If there's a BPF listener, bounce a copy of this frame
@@ -1858,6 +1861,9 @@ sis_start(struct ifnet *ifp)
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_trans)
+               return;
+
        /* Transmit */
        sc->sis_cdata.sis_tx_prod = idx;
        SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_ENABLE);
index cf77b1f..6a55cf7 100644 (file)
@@ -32,7 +32,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_sk.c,v 1.19.2.9 2003/03/05 18:42:34 njl Exp $
- * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.36 2005/06/14 11:27:28 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.37 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -1616,9 +1616,11 @@ sk_start(struct ifnet *ifp)
         struct sk_softc *sc = sc_if->sk_softc;
         struct mbuf *m_head = NULL;
         uint32_t idx;
+       int need_trans;
 
        idx = sc_if->sk_cdata.sk_tx_prod;
 
+       need_trans = 0;
        while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
                m_head = ifq_poll(&ifp->if_snd);
                if (m_head == NULL)
@@ -1634,10 +1636,14 @@ sk_start(struct ifnet *ifp)
                        break;
                }
                m_head = ifq_dequeue(&ifp->if_snd);
+               need_trans = 1;
 
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_trans)
+               return;
+
        /* Transmit */
        sc_if->sk_cdata.sk_tx_prod = idx;
        CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
@@ -1656,6 +1662,9 @@ sk_watchdog(struct ifnet *ifp)
 
        printf("sk%d: watchdog timeout\n", sc_if->sk_unit);
        sk_init(sc_if);
+
+       if (!ifq_is_empty(&ifp->if_snd))
+               ifp->if_start(ifp);
 }
 
 static void
index 4a7fb40..c55f72a 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_ti.c,v 1.25.2.14 2002/02/15 04:20:20 silby Exp $
- * $DragonFly: src/sys/dev/netif/ti/if_ti.c,v 1.34 2005/06/14 14:19:22 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/ti/if_ti.c,v 1.35 2005/09/29 12:52:51 sephe Exp $
  */
 
 /*
@@ -1911,9 +1911,11 @@ ti_start(struct ifnet *ifp)
        struct ti_softc *sc = ifp->if_softc;
        struct mbuf *m_head = NULL;
        uint32_t prodidx = 0;
+       int need_trans;
 
        prodidx = CSR_READ_4(sc, TI_MB_SENDPROD_IDX);
 
+       need_trans = 0;
        while(sc->ti_cdata.ti_tx_chain[prodidx] == NULL) {
                m_head = ifq_poll(&ifp->if_snd);
                if (m_head == NULL)
@@ -1945,11 +1947,15 @@ ti_start(struct ifnet *ifp)
                        ifp->if_flags |= IFF_OACTIVE;
                        break;
                }
-
                m_head = ifq_dequeue(&ifp->if_snd);
+               need_trans = 1;
+
                BPF_MTAP(ifp, m_head);
        }
 
+       if (!need_trans)
+               return;
+
        /* Transmit */
        CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, prodidx);
 
@@ -2252,6 +2258,9 @@ ti_watchdog(struct ifnet *ifp)
        ti_init(sc);
 
        ifp->if_oerrors++;
+
+       if (!ifq_is_empty(&ifp->if_snd))
+               ifp->if_start(ifp);
 }
 
 /*