Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net Remove BRIDGE_MPSAFE switch and enable MP-safe code ...



details:   https://anonhg.NetBSD.org/src/rev/f0070258b9bc
branches:  trunk
changeset: 344774:f0070258b9bc
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Tue Apr 19 07:03:12 2016 +0000

description:
Remove BRIDGE_MPSAFE switch and enable MP-safe code by default

We need to enable it by default because bridge_input now runs
in softint, but bridge_input w/o BRIDGE_MPSAFE was designed as
it runs in hardware interrupt.

Note that there remains a racy code in bridge_output; it will be
solved in the upcoming change (applying psref(9)).

diffstat:

 sys/net/if_bridge.c    |  137 +++++++++++++++++++++---------------------------
 sys/net/if_bridgevar.h |   27 +-------
 2 files changed, 66 insertions(+), 98 deletions(-)

diffs (truncated from 413 to 300 lines):

diff -r df3022ea6521 -r f0070258b9bc sys/net/if_bridge.c
--- a/sys/net/if_bridge.c       Tue Apr 19 06:57:37 2016 +0000
+++ b/sys/net/if_bridge.c       Tue Apr 19 07:03:12 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bridge.c,v 1.113 2016/04/11 05:40:47 ozaki-r Exp $  */
+/*     $NetBSD: if_bridge.c,v 1.114 2016/04/19 07:03:12 ozaki-r Exp $  */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -80,11 +80,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.113 2016/04/11 05:40:47 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.114 2016/04/19 07:03:12 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_bridge_ipf.h"
 #include "opt_inet.h"
+#include "opt_net_mpsafe.h"
 #endif /* _KERNEL_OPT */
 
 #include <sys/param.h>
@@ -191,13 +192,27 @@
                                if ((_sc)->sc_rtlist_psz != NULL) \
                                        pserialize_perform((_sc)->sc_rtlist_psz);
 
-#ifdef BRIDGE_MPSAFE
 #define BRIDGE_RT_RENTER(__s)  do { __s = pserialize_read_enter(); } while (0)
 #define BRIDGE_RT_REXIT(__s)   do { pserialize_read_exit(__s); } while (0)
-#else /* BRIDGE_MPSAFE */
-#define BRIDGE_RT_RENTER(__s)  do { __s = 0; } while (0)
-#define BRIDGE_RT_REXIT(__s)   do { (void)__s; } while (0)
-#endif /* BRIDGE_MPSAFE */
+
+
+#ifdef NET_MPSAFE
+#define DECLARE_LOCK_VARIABLE
+#define ACQUIRE_GLOBAL_LOCKS() do { } while (0)
+#define RELEASE_GLOBAL_LOCKS() do { } while (0)
+#else
+#define DECLARE_LOCK_VARIABLE  int __s
+#define ACQUIRE_GLOBAL_LOCKS() do {                                    \
+                                       KERNEL_LOCK(1, NULL);           \
+                                       mutex_enter(softnet_lock);      \
+                                       __s = splnet();                 \
+                               } while (0)
+#define RELEASE_GLOBAL_LOCKS() do {                                    \
+                                       splx(__s);                      \
+                                       mutex_exit(softnet_lock);       \
+                                       KERNEL_UNLOCK_ONE(NULL);        \
+                               } while (0)
+#endif
 
 int    bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
 
@@ -369,7 +384,7 @@
 {
        struct bridge_softc *sc;
        struct ifnet *ifp;
-       int error, flags;
+       int error;
 
        sc = kmem_zalloc(sizeof(*sc),  KM_SLEEP);
        ifp = &sc->sc_if;
@@ -386,13 +401,8 @@
        /* Initialize our routing table. */
        bridge_rtable_init(sc);
 
-#ifdef BRIDGE_MPSAFE
-       flags = WQ_MPSAFE;
-#else
-       flags = 0;
-#endif
        error = workqueue_create(&sc->sc_rtage_wq, "bridge_rtage",
-           bridge_rtage_work, sc, PRI_SOFTNET, IPL_SOFTNET, flags);
+           bridge_rtage_work, sc, PRI_SOFTNET, IPL_SOFTNET, WQ_MPSAFE);
        if (error)
                panic("%s: workqueue_create %d\n", __func__, error);
 
@@ -400,13 +410,8 @@
        callout_init(&sc->sc_bstpcallout, 0);
 
        PSLIST_INIT(&sc->sc_iflist);
-#ifdef BRIDGE_MPSAFE
        sc->sc_iflist_psz = pserialize_create();
        sc->sc_iflist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
-#else
-       sc->sc_iflist_psz = NULL;
-       sc->sc_iflist_lock = NULL;
-#endif
        cv_init(&sc->sc_iflist_cv, "if_bridge_cv");
 
        if_initname(ifp, ifc->ifc_name, unit);
@@ -662,14 +667,13 @@
 static struct bridge_iflist *
 bridge_try_hold_bif(struct bridge_iflist *bif)
 {
-#ifdef BRIDGE_MPSAFE
+
        if (bif != NULL) {
                if (bif->bif_waiting)
                        bif = NULL;
                else
                        atomic_inc_32(&bif->bif_refs);
        }
-#endif
        return bif;
 }
 
@@ -681,7 +685,6 @@
 static void
 bridge_release_member(struct bridge_softc *sc, struct bridge_iflist *bif)
 {
-#ifdef BRIDGE_MPSAFE
        uint32_t refs;
 
        refs = atomic_dec_uint_nv(&bif->bif_refs);
@@ -690,10 +693,6 @@
                cv_broadcast(&sc->sc_iflist_cv);
                BRIDGE_UNLOCK(sc);
        }
-#else
-       (void)sc;
-       (void)bif;
-#endif
 }
 
 /*
@@ -715,7 +714,6 @@
        PSLIST_WRITER_REMOVE(bif, bif_next);
        BRIDGE_PSZ_PERFORM(sc);
 
-#ifdef BRIDGE_MPSAFE
        bif->bif_waiting = true;
        membar_sync();
        while (bif->bif_refs > 0) {
@@ -723,7 +721,6 @@
                cv_wait(&sc->sc_iflist_cv, sc->sc_iflist_lock);
        }
        bif->bif_waiting = false;
-#endif
        BRIDGE_UNLOCK(sc);
 
        PSLIST_ENTRY_DESTROY(bif, bif_next);
@@ -1432,9 +1429,7 @@
        struct ether_header *eh;
        struct ifnet *dst_if;
        struct bridge_softc *sc;
-#ifndef BRIDGE_MPSAFE
        int s;
-#endif
 
        if (m->m_len < ETHER_HDR_LEN) {
                m = m_pullup(m, ETHER_HDR_LEN);
@@ -1445,10 +1440,6 @@
        eh = mtod(m, struct ether_header *);
        sc = ifp->if_bridge;
 
-#ifndef BRIDGE_MPSAFE
-       s = splnet();
-#endif
-
        /*
         * If bridge is down, but the original output interface is up,
         * go ahead and send out that interface.  Otherwise, the packet
@@ -1472,15 +1463,14 @@
                struct bridge_iflist *bif;
                struct mbuf *mc;
                int used = 0;
-               int ss;
-
-               BRIDGE_PSZ_RENTER(ss);
+
+               BRIDGE_PSZ_RENTER(s);
                PSLIST_READER_FOREACH(bif, &sc->sc_iflist,
                    struct bridge_iflist, bif_next) {
                        bif = bridge_try_hold_bif(bif);
                        if (bif == NULL)
                                continue;
-                       BRIDGE_PSZ_REXIT(ss);
+                       BRIDGE_PSZ_REXIT(s);
 
                        dst_if = bif->bif_ifp;
                        if ((dst_if->if_flags & IFF_RUNNING) == 0)
@@ -1514,18 +1504,21 @@
                                }
                        }
 
+#ifndef NET_MPSAFE
+                       s = splnet();
+#endif
                        bridge_enqueue(sc, dst_if, mc, 0);
+#ifndef NET_MPSAFE
+                       splx(s);
+#endif
 next:
                        bridge_release_member(sc, bif);
-                       BRIDGE_PSZ_RENTER(ss);
+                       BRIDGE_PSZ_RENTER(s);
                }
-               BRIDGE_PSZ_REXIT(ss);
+               BRIDGE_PSZ_REXIT(s);
 
                if (used == 0)
                        m_freem(m);
-#ifndef BRIDGE_MPSAFE
-               splx(s);
-#endif
                return (0);
        }
 
@@ -1536,17 +1529,17 @@
 
        if ((dst_if->if_flags & IFF_RUNNING) == 0) {
                m_freem(m);
-#ifndef BRIDGE_MPSAFE
-               splx(s);
-#endif
                return (0);
        }
 
+#ifndef NET_MPSAFE
+       s = splnet();
+#endif
        bridge_enqueue(sc, dst_if, m, 0);
-
-#ifndef BRIDGE_MPSAFE
+#ifndef NET_MPSAFE
        splx(s);
 #endif
+
        return (0);
 }
 
@@ -1575,24 +1568,10 @@
        struct bridge_iflist *bif;
        struct ifnet *src_if, *dst_if;
        struct ether_header *eh;
-#ifndef BRIDGE_MPSAFE
-       int s;
-
-       KERNEL_LOCK(1, NULL);
-       mutex_enter(softnet_lock);
-#endif
-
-       if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
-#ifndef BRIDGE_MPSAFE
-               mutex_exit(softnet_lock);
-               KERNEL_UNLOCK_ONE(NULL);
-#endif
+       DECLARE_LOCK_VARIABLE;
+
+       if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
                return;
-       }
-
-#ifndef BRIDGE_MPSAFE
-       s = splnet();
-#endif
 
        src_if = m->m_pkthdr.rcvif;
 
@@ -1711,16 +1690,12 @@
 
        bridge_release_member(sc, bif);
 
+       ACQUIRE_GLOBAL_LOCKS();
        bridge_enqueue(sc, dst_if, m, 1);
+       RELEASE_GLOBAL_LOCKS();
 out:
-#ifndef BRIDGE_MPSAFE
-       splx(s);
-       mutex_exit(softnet_lock);
-       KERNEL_UNLOCK_ONE(NULL);
-#else
        /* XXX gcc */
        return;
-#endif
 }
 
 static bool
@@ -1765,18 +1740,23 @@
        struct bridge_softc *sc = ifp->if_bridge;
        struct bridge_iflist *bif;
        struct ether_header *eh;
+       DECLARE_LOCK_VARIABLE;
 
        KASSERT(!cpu_intr_p());
 
        if (__predict_false(sc == NULL) ||
            (sc->sc_if.if_flags & IFF_RUNNING) == 0) {
+               ACQUIRE_GLOBAL_LOCKS();
                ether_input(ifp, m);
+               RELEASE_GLOBAL_LOCKS();
                return;
        }
 
        bif = bridge_lookup_member_if(sc, ifp);
        if (bif == NULL) {



Home | Main Index | Thread Index | Old Index