if: Multiple TX queue support step 2 of many
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 13 Jan 2013 09:10:32 +0000 (17:10 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 13 Jan 2013 09:10:32 +0000 (17:10 +0800)
ifnet_{serialize,deserialize,tryserialize}_tx and hardware TX serializer
asserion macros now require subqueue, so the proper hardware TX queue's
serializer could be held, released and asserted.

20 files changed:
sys/net/altq/altq_cbq.c
sys/net/altq/altq_subr.c
sys/net/bridge/if_bridge.c
sys/net/gif/if_gif.c
sys/net/gre/if_gre.c
sys/net/if.c
sys/net/if_loop.c
sys/net/if_var.h
sys/net/ifq_var.h
sys/net/ppp/if_ppp.c
sys/net/sl/if_sl.c
sys/net/sppp/if_spppsubr.c
sys/net/stf/if_stf.c
sys/net/tun/if_tun.c
sys/net/vlan/if_vlan.c
sys/netgraph/fec/ng_fec.c
sys/netgraph/iface/ng_iface.c
sys/netgraph7/ng_fec.c
sys/netproto/atm/atm_if.c
sys/netproto/ipx/ipx_ip.c

index f0e52a3..24c2212 100644 (file)
@@ -614,10 +614,10 @@ cbqrestart(struct ifaltq *ifq)
                /* Release the altq lock to avoid deadlock */
                CBQ_UNLOCK(ifq);
 
-               ifnet_serialize_tx(ifp);
+               ifnet_serialize_tx(ifp, ifsq);
                if (ifp->if_start && !ifsq_is_oactive(ifsq))
                        (*ifp->if_start)(ifp, ifsq);
-               ifnet_deserialize_tx(ifp);
+               ifnet_deserialize_tx(ifp, ifsq);
 
                CBQ_LOCK(ifq);
        }
index 864f513..9cd3cf6 100644 (file)
@@ -342,16 +342,17 @@ tbr_timeout(void *arg)
        active = 0;
        crit_enter();
        for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
-               struct ifaltq_subque *ifsq =
-                   &ifp->if_snd.altq_subq[ALTQ_SUBQ_INDEX_DEFAULT];
+               struct ifaltq_subque *ifsq;
 
                if (ifp->if_snd.altq_tbr == NULL)
                        continue;
+
+               ifsq = &ifp->if_snd.altq_subq[ALTQ_SUBQ_INDEX_DEFAULT];
                active++;
                if (!ifsq_is_empty(ifsq) && ifp->if_start != NULL) {
-                       ifnet_serialize_tx(ifp);
+                       ifnet_serialize_tx(ifp, ifsq);
                        (*ifp->if_start)(ifp, ifsq);
-                       ifnet_deserialize_tx(ifp);
+                       ifnet_deserialize_tx(ifp, ifsq);
                }
        }
        crit_exit();
index 1389b33..3faaae0 100644 (file)
@@ -2302,7 +2302,7 @@ bridge_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
        struct bridge_softc *sc = ifp->if_softc;
 
        ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
-       ASSERT_IFNET_SERIALIZED_TX(ifp);
+       ASSERT_IFNET_SERIALIZED_TX(ifp, ifsq);
 
        ifsq_set_oactive(ifsq);
        for (;;) {
index 636c27b..c0ce39c 100644 (file)
@@ -395,11 +395,12 @@ int
 gif_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
           struct rtentry *rt)
 {
+       const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        error = gif_output_serialized(ifp, m, dst, rt);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
        return error;
 }
 
index 88287b6..73431a5 100644 (file)
@@ -399,11 +399,12 @@ static int
 gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
           struct rtentry *rt)
 {
+       const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        error = gre_output_serialized(ifp, m, dst, rt);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index f20b1c0..ee4f4b0 100644 (file)
@@ -332,14 +332,14 @@ ifsq_ifstart_dispatch(netmsg_t msg)
                return;
        }
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        if ((ifp->if_flags & IFF_RUNNING) && !ifsq_is_oactive(ifsq)) {
                ifp->if_start(ifp, ifsq);
                if ((ifp->if_flags & IFF_RUNNING) && !ifsq_is_oactive(ifsq))
                        running = 1;
        }
        need_sched = ifsq_ifstart_need_schedule(ifsq, running);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        if (need_sched) {
                /*
@@ -358,7 +358,7 @@ ifsq_devstart(struct ifaltq_subque *ifsq)
        struct ifnet *ifp = ifsq_get_ifp(ifsq);
        int running = 0;
 
-       ASSERT_IFNET_SERIALIZED_TX(ifp);
+       ASSERT_IFNET_SERIALIZED_TX(ifp, ifsq);
 
        ALTQ_SQ_LOCK(ifsq);
        if (ifsq_is_started(ifsq) || !ifsq_data_ready(ifsq)) {
@@ -2508,7 +2508,7 @@ ifsq_ifstart_try(struct ifaltq_subque *ifsq, int force_sched)
         * contention on ifnet's serializer, ifnet.if_start will
         * be scheduled on ifnet's CPU.
         */
-       if (!ifnet_tryserialize_tx(ifp)) {
+       if (!ifnet_tryserialize_tx(ifp, ifsq)) {
                /*
                 * ifnet serializer contention happened,
                 * ifnet.if_start is scheduled on ifnet's
@@ -2525,7 +2525,7 @@ ifsq_ifstart_try(struct ifaltq_subque *ifsq, int force_sched)
        }
        need_sched = ifsq_ifstart_need_schedule(ifsq, running);
 
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        if (need_sched) {
                /*
@@ -2585,7 +2585,7 @@ ifq_dispatch(struct ifnet *ifp, struct mbuf *m, struct altq_pktattr *pa)
        /* TODO find qid here */
        ifsq = &ifq->altq_subq[qid];
 
-       ASSERT_IFNET_NOT_SERIALIZED_TX(ifp);
+       ASSERT_IFNET_NOT_SERIALIZED_TX(ifp, ifsq);
 
        len = m->m_pkthdr.len;
        if (m->m_flags & M_MCAST)
index b90bbce..2599182 100644 (file)
@@ -226,10 +226,8 @@ rel:
         * a simplex interface).
         */
        if (ifq_is_enabled(&ifp->if_snd) && ifp->if_start == lo_altqstart) {
-               struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
                struct altq_pktattr pktattr;
                int32_t *afp;
-               int error;
 
                /*
                 * if the queueing discipline needs packet classification,
@@ -243,18 +241,7 @@ rel:
                afp = mtod(m, int32_t *);
                *afp = (int32_t)af;
 
-               /*
-                * A critical section is needed for subsystems protected by
-                * the MP lock, and the serializer is assumed to already
-                * be held for MPSAFE subsystems.
-                */
-               crit_enter();
-               error = ifsq_enqueue(ifsq, m, &pktattr);
-               ifnet_serialize_tx(ifp);
-               ifp->if_start(ifp, ifsq);
-               ifnet_deserialize_tx(ifp);
-               crit_exit();
-               return (error);
+               return ifq_dispatch(ifp, m, &pktattr);
        }
 #endif /* ALTQ */
 
index 5ec5b51..4fc3bc9 100644 (file)
@@ -138,7 +138,7 @@ enum ifnet_serialize {
        IFNET_SERIALIZE_TX_BASE = 0x10000000,
        IFNET_SERIALIZE_RX_BASE = 0x20000000
 };
-#define IFNET_SERIALIZE_TX     IFNET_SERIALIZE_TX_BASE
+#define IFNET_SERIALIZE_TX(i)  (IFNET_SERIALIZE_TX_BASE + (i))
 #define IFNET_SERIALIZE_RX(i)  (IFNET_SERIALIZE_RX_BASE + (i))
 
 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
@@ -362,10 +362,12 @@ EVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t);
 #define ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp) \
        (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_ALL, FALSE)
 
-#define ASSERT_IFNET_SERIALIZED_TX(ifp) \
-       (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_TX, TRUE)
-#define ASSERT_IFNET_NOT_SERIALIZED_TX(ifp) \
-       (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_TX, FALSE)
+#define ASSERT_IFNET_SERIALIZED_TX(ifp, ifsq) \
+       (ifp)->if_serialize_assert((ifp), \
+           IFNET_SERIALIZE_TX((ifsq)->ifsq_index), TRUE)
+#define ASSERT_IFNET_NOT_SERIALIZED_TX(ifp, ifsq) \
+       (ifp)->if_serialize_assert((ifp), \
+           IFNET_SERIALIZE_TX((ifsq)->ifsq_index), FALSE)
 
 #define ASSERT_IFNET_SERIALIZED_MAIN(ifp) \
        (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_MAIN, TRUE)
@@ -374,8 +376,8 @@ EVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t);
 #else
 #define ASSERT_IFNET_SERIALIZED_ALL(ifp)       ((void)0)
 #define ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp)   ((void)0)
-#define ASSERT_IFNET_SERIALIZED_TX(ifp)                ((void)0)
-#define ASSERT_IFNET_NOT_SERIALIZED_TX(ifp)    ((void)0)
+#define ASSERT_IFNET_SERIALIZED_TX(ifp, ifsq)  ((void)0)
+#define ASSERT_IFNET_NOT_SERIALIZED_TX(ifp, ifsq) ((void)0)
 #define ASSERT_IFNET_SERIALIZED_MAIN(ifp)      ((void)0)
 #define ASSERT_IFNET_NOT_SERIALIZED_MAIN(ifp)  ((void)0)
 #endif
@@ -399,21 +401,22 @@ ifnet_tryserialize_all(struct ifnet *_ifp)
 }
 
 static __inline void
-ifnet_serialize_tx(struct ifnet *_ifp)
+ifnet_serialize_tx(struct ifnet *_ifp, const struct ifaltq_subque *_ifsq)
 {
-       _ifp->if_serialize(_ifp, IFNET_SERIALIZE_TX);
+       _ifp->if_serialize(_ifp, IFNET_SERIALIZE_TX(_ifsq->ifsq_index));
 }
 
 static __inline void
-ifnet_deserialize_tx(struct ifnet *_ifp)
+ifnet_deserialize_tx(struct ifnet *_ifp, const struct ifaltq_subque *_ifsq)
 {
-       _ifp->if_deserialize(_ifp, IFNET_SERIALIZE_TX);
+       _ifp->if_deserialize(_ifp, IFNET_SERIALIZE_TX(_ifsq->ifsq_index));
 }
 
 static __inline int
-ifnet_tryserialize_tx(struct ifnet *_ifp)
+ifnet_tryserialize_tx(struct ifnet *_ifp, const struct ifaltq_subque *_ifsq)
 {
-       return _ifp->if_tryserialize(_ifp, IFNET_SERIALIZE_TX);
+       return _ifp->if_tryserialize(_ifp,
+           IFNET_SERIALIZE_TX(_ifsq->ifsq_index));
 }
 
 static __inline void
index d6c1e55..bd9f908 100644 (file)
@@ -357,7 +357,7 @@ ifq_handoff(struct ifnet *_ifp, struct mbuf *_m, struct altq_pktattr *_pa)
 
        _ifsq = &_ifp->if_snd.altq_subq[_qid];
 
-       ASSERT_IFNET_SERIALIZED_TX(_ifp);
+       ASSERT_IFNET_SERIALIZED_TX(_ifp, _ifsq);
        _error = ifsq_enqueue(_ifsq, _m, _pa);
        if (_error == 0) {
                _ifp->if_obytes += _m->m_pkthdr.len;
index c9119b2..66b1404 100644 (file)
@@ -711,8 +711,8 @@ pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
  * Called at splnet from pppwrite().
  */
 static int
-pppoutput_serialized(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
-                    struct rtentry *rtp)
+pppoutput_serialized(struct ifnet *ifp, struct ifaltq_subque *ifsq,
+    struct mbuf *m0, struct sockaddr *dst, struct rtentry *rtp)
 {
     struct ppp_softc *sc = &ppp_softc[ifp->if_dunit];
     int protocol, address, control;
@@ -877,9 +877,8 @@ pppoutput_serialized(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
                error = 0;
            }
        } else {
-           ASSERT_IFNET_SERIALIZED_TX(&sc->sc_if);
-           error = ifsq_enqueue(ifq_get_subq_default(&sc->sc_if.if_snd), m0,
-               &pktattr);
+           ASSERT_IFNET_SERIALIZED_TX(&sc->sc_if, ifsq);
+           error = ifsq_enqueue(ifsq, m0, &pktattr);
        }
        if (error) {
            crit_exit();
@@ -905,11 +904,12 @@ int
 pppoutput(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
          struct rtentry *rtp)
 {
+       struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
-       error = pppoutput_serialized(ifp, m0, dst, rtp);
-       ifnet_deserialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
+       error = pppoutput_serialized(ifp, ifsq, m0, dst, rtp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index 1e97b95..766806c 100644 (file)
@@ -459,8 +459,8 @@ sltioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct ucred *cred)
  * ordering gets trashed.  It can be done for all packets in slstart.
  */
 static int
-sloutput_serialized(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
-                   struct rtentry *rtp)
+sloutput_serialized(struct ifnet *ifp, struct ifaltq_subque *ifsq,
+    struct mbuf *m, struct sockaddr *dst, struct rtentry *rtp)
 {
        struct sl_softc *sc = &sl_softc[ifp->if_dunit];
        struct ip *ip;
@@ -507,8 +507,7 @@ sloutput_serialized(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
                        error = 0;
                }
        } else {
-               error = ifsq_enqueue(ifq_get_subq_default(&sc->sc_if.if_snd),
-                   m, &pktattr);
+               error = ifsq_enqueue(ifsq, m, &pktattr);
        }
        if (error) {
                sc->sc_if.if_oerrors++;
@@ -525,11 +524,12 @@ static int
 sloutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
         struct rtentry *rtp)
 {
+       struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
-       error = sloutput_serialized(ifp, m, dst, rtp);
-       ifnet_deserialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
+       error = sloutput_serialized(ifp, ifsq, m, dst, rtp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index aa0ee3f..6e915dc 100644 (file)
@@ -722,11 +722,10 @@ drop2:
  * Enqueue transmit packet.
  */
 static int
-sppp_output_serialized(struct ifnet *ifp, struct mbuf *m,
-                      struct sockaddr *dst, struct rtentry *rt)
+sppp_output_serialized(struct ifnet *ifp, struct ifaltq_subque *ifsq,
+    struct mbuf *m, struct sockaddr *dst, struct rtentry *rt)
 {
        struct sppp *sp = (struct sppp*) ifp;
-       struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        struct ppp_header *h;
        struct ifqueue *ifq = NULL;
        int rv = 0;
@@ -976,11 +975,12 @@ static int
 sppp_output(struct ifnet *ifp, struct mbuf *m,
            struct sockaddr *dst, struct rtentry *rt)
 {
+       struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
-       error = sppp_output_serialized(ifp, m, dst, rt);
-       ifnet_deserialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
+       error = sppp_output_serialized(ifp, ifsq, m, dst, rt);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index 7a8256f..b957ec3 100644 (file)
@@ -421,11 +421,12 @@ static int
 stf_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
           struct rtentry *rt)
 {
+       const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        error = stf_output_serialized(ifp, m, dst, rt);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index 94f6861..0846c62 100644 (file)
@@ -803,8 +803,8 @@ tunstart(struct ifnet *ifp, struct ifaltq_subque *ifsq)
                }
                if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
                        pgsigio(tp->tun_sigio, SIGIO, 0);
-               ifnet_deserialize_tx(ifp);
+               ifnet_deserialize_tx(ifp, ifsq);
                KNOTE(&tp->tun_rkq.ki_note, 0);
-               ifnet_serialize_tx(ifp);
+               ifnet_serialize_tx(ifp, ifsq);
        }
 }
index ba2e2ec..0e291ef 100644 (file)
@@ -505,7 +505,7 @@ vlan_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
        lwkt_port_t p_port;
 
        ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
-       ASSERT_IFNET_SERIALIZED_TX(ifp);
+       ASSERT_IFNET_SERIALIZED_TX(ifp, ifsq);
 
        if (ifp_p == NULL) {
                ifsq_purge(ifsq);
index 2c6d1c1..925ea9b 100644 (file)
@@ -842,11 +842,12 @@ static int
 ng_fec_output(struct ifnet *ifp, struct mbuf *m,
              struct sockaddr *dst, struct rtentry *rt0)
 {
+       const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        error = ng_fec_output_serialized(ifp, m, dst, rt0);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index 0040cfa..988ad91 100644 (file)
@@ -461,11 +461,12 @@ static int
 ng_iface_output(struct ifnet *ifp, struct mbuf *m,
                struct sockaddr *dst, struct rtentry *rt0)
 {
+       const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        error = ng_iface_output_serialized(ifp, m, dst, rt0);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index 90cee84..97c9c51 100644 (file)
@@ -1112,7 +1112,7 @@ ng_fec_choose_port(struct ng_fec_bundle *b,
  * transmission.
  */
 static void
-ng_fec_start(struct ifnet *ifp, struct ifaltq_subque *ifsq __unused)
+ng_fec_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
 {
        struct ng_fec_private   *priv;
        struct ng_fec_bundle    *b;
@@ -1139,9 +1139,9 @@ ng_fec_start(struct ifnet *ifp, struct ifaltq_subque *ifsq __unused)
        }
        ifp->if_opackets++;
 
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
        error = ifq_dispatch(oifp, m0, NULL);
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
 
        priv->if_error = error;
 }
index 6804716..2243c0e 100644 (file)
@@ -972,11 +972,12 @@ int
 atm_ifoutput(struct ifnet *ifp, KBuffer *m, struct sockaddr *dst,
             struct rtentry *rt)
 {
+       const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        error = atm_ifoutput_serialized(ifp, m, dst, rt);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }
index d73686c..613a41b 100644 (file)
@@ -60,6 +60,7 @@
 #include <sys/msgport2.h>
 
 #include <net/if.h>
+#include <net/ifq_var.h>
 #include <net/netisr.h>
 #include <net/route.h>
 
@@ -292,11 +293,12 @@ static int
 ipxipoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
            struct rtentry *rt)
 {
+       const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
        int error;
 
-       ifnet_serialize_tx(ifp);
+       ifnet_serialize_tx(ifp, ifsq);
        error = ipxipoutput_serialized(ifp, m, dst, rt);
-       ifnet_deserialize_tx(ifp);
+       ifnet_deserialize_tx(ifp, ifsq);
 
        return error;
 }