Source-Changes-HG archive

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

[src/trunk]: src/sys/net Use pserialize in bridge



details:   https://anonhg.NetBSD.org/src/rev/ca802958444d
branches:  trunk
changeset: 335246:ca802958444d
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Wed Dec 31 17:36:24 2014 +0000

description:
Use pserialize in bridge

This change enables lockless accesses to bridge member lists.
See locking notes in a comment to know how pserialize and
mutexes are used.

This change also provides support for softint-based interrupt
handling; pserialize readers can run in both HW interrupt and
softint contexts.

As usual, pserialize is used only when NET_MPSAFE on.

diffstat:

 sys/net/bridgestp.c    |   42 +++++++-------
 sys/net/if_bridge.c    |  145 +++++++++++++++++++++++++++++++-----------------
 sys/net/if_bridgevar.h |   54 +++++++++++++++++-
 3 files changed, 165 insertions(+), 76 deletions(-)

diffs (truncated from 596 to 300 lines):

diff -r 6da68ee4937b -r ca802958444d sys/net/bridgestp.c
--- a/sys/net/bridgestp.c       Wed Dec 31 17:10:45 2014 +0000
+++ b/sys/net/bridgestp.c       Wed Dec 31 17:36:24 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bridgestp.c,v 1.17 2014/07/14 02:34:36 ozaki-r Exp $   */
+/*     $NetBSD: bridgestp.c,v 1.18 2014/12/31 17:36:24 ozaki-r Exp $   */
 
 /*
  * Copyright (c) 2000 Jason L. Wright (jason%thought.net@localhost)
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.17 2014/07/14 02:34:36 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.18 2014/12/31 17:36:24 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -221,7 +221,7 @@
        struct bstp_cbpdu bpdu;
        int s;
 
-       KASSERT(BRIDGE_LOCKED(sc));
+       KASSERT(BRIDGE_INTR_LOCKED(sc));
 
        ifp = bif->bif_ifp;
 
@@ -276,11 +276,11 @@
 
        memcpy(mtod(m, char *) + sizeof(*eh), &bpdu, sizeof(bpdu));
 
-       BRIDGE_UNLOCK(sc);
+       BRIDGE_INTR_UNLOCK(sc);
        s = splnet();
        bridge_enqueue(sc, ifp, m, 0);
        splx(s);
-       BRIDGE_LOCK(sc);
+       BRIDGE_INTR_LOCK(sc);
 }
 
 static int
@@ -367,7 +367,7 @@
        struct mbuf *m;
        int s;
 
-       KASSERT(BRIDGE_LOCKED(sc));
+       KASSERT(BRIDGE_INTR_LOCKED(sc));
 
        KASSERT(bif != NULL);
        ifp = bif->bif_ifp;
@@ -396,11 +396,11 @@
 
        memcpy(mtod(m, char *) + sizeof(*eh), &bpdu, sizeof(bpdu));
 
-       BRIDGE_UNLOCK(sc);
+       BRIDGE_INTR_UNLOCK(sc);
        s = splnet();
        bridge_enqueue(sc, ifp, m, 0);
        splx(s);
-       BRIDGE_LOCK(sc);
+       BRIDGE_INTR_LOCK(sc);
 }
 
 static void
@@ -634,9 +634,9 @@
        case BSTP_MSGTYPE_TCN:
                tu.tu_message_type = tpdu.tbu_bpdutype;
 
-               BRIDGE_LOCK(sc);
+               BRIDGE_INTR_LOCK(sc);
                bstp_received_tcn_bpdu(sc, bif, &tu);
-               BRIDGE_UNLOCK(sc);
+               BRIDGE_INTR_UNLOCK(sc);
 
                break;
        case BSTP_MSGTYPE_CFG:
@@ -675,9 +675,9 @@
                cu.cu_topology_change =
                    (cpdu.cbu_flags & BSTP_FLAG_TC) ? 1 : 0;
 
-               BRIDGE_LOCK(sc);
+               BRIDGE_INTR_LOCK(sc);
                bstp_received_config_bpdu(sc, bif, &cu);
-               BRIDGE_UNLOCK(sc);
+               BRIDGE_INTR_UNLOCK(sc);
 
                break;
        default:
@@ -826,7 +826,7 @@
 
        mif = NULL;
 
-       BRIDGE_LOCK(sc);
+       BRIDGE_INTR_LOCK(sc);
 
        LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
@@ -848,7 +848,7 @@
        }
 
        if (mif == NULL) {
-               BRIDGE_UNLOCK(sc);
+               BRIDGE_INTR_UNLOCK(sc);
                bstp_stop(sc);
                return;
        }
@@ -862,7 +862,7 @@
            (((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[4]) << 8) |
            (((uint64_t)(uint8_t)CLLADDR(mif->bif_ifp->if_sadl)[5]) << 0);
 
-       BRIDGE_UNLOCK(sc);
+       BRIDGE_INTR_UNLOCK(sc);
 
        sc->sc_designated_root = sc->sc_bridge_id;
        sc->sc_root_path_cost = 0;
@@ -880,7 +880,7 @@
                callout_reset(&sc->sc_bstpcallout, hz,
                    bstp_tick, sc);
 
-       BRIDGE_LOCK(sc);
+       BRIDGE_INTR_LOCK(sc);
 
        LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
                if (bif->bif_flags & IFBIF_STP)
@@ -893,7 +893,7 @@
        bstp_config_bpdu_generation(sc);
        bstp_timer_start(&sc->sc_hello_timer, 0);
 
-       BRIDGE_UNLOCK(sc);
+       BRIDGE_INTR_UNLOCK(sc);
 }
 
 void
@@ -901,14 +901,14 @@
 {
        struct bridge_iflist *bif;
 
-       BRIDGE_LOCK(sc);
+       BRIDGE_INTR_LOCK(sc);
        LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
                bstp_set_port_state(bif, BSTP_IFSTATE_DISABLED);
                bstp_timer_stop(&bif->bif_hold_timer);
                bstp_timer_stop(&bif->bif_message_age_timer);
                bstp_timer_stop(&bif->bif_forward_delay_timer);
        }
-       BRIDGE_UNLOCK(sc);
+       BRIDGE_INTR_UNLOCK(sc);
 
        callout_stop(&sc->sc_bstpcallout);
 
@@ -1065,7 +1065,7 @@
        int s;
 
        s = splnet();
-       BRIDGE_LOCK(sc);
+       BRIDGE_INTR_LOCK(sc);
 
        LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
@@ -1113,7 +1113,7 @@
        if (sc->sc_if.if_flags & IFF_RUNNING)
                callout_reset(&sc->sc_bstpcallout, hz, bstp_tick, sc);
 
-       BRIDGE_UNLOCK(sc);
+       BRIDGE_INTR_UNLOCK(sc);
        splx(s);
 }
 
diff -r 6da68ee4937b -r ca802958444d sys/net/if_bridge.c
--- a/sys/net/if_bridge.c       Wed Dec 31 17:10:45 2014 +0000
+++ b/sys/net/if_bridge.c       Wed Dec 31 17:36:24 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bridge.c,v 1.94 2014/12/25 09:10:01 ozaki-r Exp $   */
+/*     $NetBSD: if_bridge.c,v 1.95 2014/12/31 17:36:24 ozaki-r Exp $   */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.94 2014/12/25 09:10:01 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.95 2014/12/31 17:36:24 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_bridge_ipf.h"
@@ -223,6 +223,7 @@
 static void    bridge_release_member(struct bridge_softc *, struct bridge_iflist *);
 static void    bridge_delete_member(struct bridge_softc *,
                                     struct bridge_iflist *);
+static struct bridge_iflist *bridge_try_hold_bif(struct bridge_iflist *);
 
 static int     bridge_ioctl_add(struct bridge_softc *, void *);
 static int     bridge_ioctl_del(struct bridge_softc *, void *);
@@ -368,8 +369,12 @@
 
        LIST_INIT(&sc->sc_iflist);
 #ifdef BRIDGE_MPSAFE
-       sc->sc_iflist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
+       sc->sc_iflist_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
+       sc->sc_iflist_psz = pserialize_create();
+       sc->sc_iflist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
 #else
+       sc->sc_iflist_intr_lock = NULL;
+       sc->sc_iflist_psz = NULL;
        sc->sc_iflist_lock = NULL;
 #endif
        cv_init(&sc->sc_iflist_cv, "if_bridge_cv");
@@ -422,10 +427,8 @@
 
        bridge_stop(ifp, 1);
 
-       BRIDGE_LOCK(sc);
        while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
                bridge_delete_member(sc, bif);
-       BRIDGE_UNLOCK(sc);
 
        mutex_enter(&bridge_list_lock);
        LIST_REMOVE(sc, sc_list);
@@ -443,6 +446,11 @@
        bridge_rtable_fini(sc);
 
        cv_destroy(&sc->sc_iflist_cv);
+       if (sc->sc_iflist_intr_lock)
+               mutex_obj_free(sc->sc_iflist_intr_lock);
+
+       if (sc->sc_iflist_psz)
+               pserialize_destroy(sc->sc_iflist_psz);
        if (sc->sc_iflist_lock)
                mutex_obj_free(sc->sc_iflist_lock);
 
@@ -674,25 +682,18 @@
 {
        struct bridge_iflist *bif;
        struct ifnet *ifp;
-
-       BRIDGE_LOCK(sc);
+       int s;
+
+       BRIDGE_PSZ_RENTER(s);
 
        LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
                ifp = bif->bif_ifp;
                if (strcmp(ifp->if_xname, name) == 0)
                        break;
        }
-
-#ifdef BRIDGE_MPSAFE
-       if (bif != NULL) {
-               if (bif->bif_waiting)
-                       bif = NULL;
-               else
-                       atomic_inc_32(&bif->bif_refs);
-       }
-#endif
-
-       BRIDGE_UNLOCK(sc);
+       bif = bridge_try_hold_bif(bif);
+
+       BRIDGE_PSZ_REXIT(s);
 
        return bif;
 }
@@ -706,11 +707,21 @@
 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
 {
        struct bridge_iflist *bif;
-
-       BRIDGE_LOCK(sc);
+       int s;
+
+       BRIDGE_PSZ_RENTER(s);
 
        bif = member_ifp->if_bridgeif;
-
+       bif = bridge_try_hold_bif(bif);
+
+       BRIDGE_PSZ_REXIT(s);
+
+       return bif;
+}
+
+static struct bridge_iflist *
+bridge_try_hold_bif(struct bridge_iflist *bif)
+{
 #ifdef BRIDGE_MPSAFE
        if (bif != NULL) {
                if (bif->bif_waiting)
@@ -719,9 +730,6 @@
                        atomic_inc_32(&bif->bif_refs);
        }
 #endif
-
-       BRIDGE_UNLOCK(sc);
-
        return bif;
 }
 
@@ -734,12 +742,13 @@
 bridge_release_member(struct bridge_softc *sc, struct bridge_iflist *bif)



Home | Main Index | Thread Index | Old Index