Source-Changes-HG archive

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

[src/trunk]: src/sys/net Apply psref(9) to bridge(4)



details:   https://anonhg.NetBSD.org/src/rev/1260cb3b12f5
branches:  trunk
changeset: 344775:1260cb3b12f5
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Tue Apr 19 07:10:22 2016 +0000

description:
Apply psref(9) to bridge(4)

Note that there is an issue that ioctls for an interface and a destruction
of the interface can run in parallel and it causes race conditions on
bridge as well (it rarely happens). The issue will be addressed in the
interface common code (if.c).

diffstat:

 sys/net/bridgestp.c    |   40 +++------
 sys/net/if_bridge.c    |  202 +++++++++++++++++++++++-------------------------
 sys/net/if_bridgevar.h |   32 +++++--
 3 files changed, 132 insertions(+), 142 deletions(-)

diffs (truncated from 792 to 300 lines):

diff -r f0070258b9bc -r 1260cb3b12f5 sys/net/bridgestp.c
--- a/sys/net/bridgestp.c       Tue Apr 19 07:03:12 2016 +0000
+++ b/sys/net/bridgestp.c       Tue Apr 19 07:10:22 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bridgestp.c,v 1.21 2016/04/11 05:40:47 ozaki-r Exp $   */
+/*     $NetBSD: bridgestp.c,v 1.22 2016/04/19 07:10:22 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.21 2016/04/11 05:40:47 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.22 2016/04/19 07:10:22 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -341,8 +341,7 @@
 {
        struct bridge_iflist *bif;
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bstp_designated_port(sc, bif) &&
@@ -416,8 +415,7 @@
 {
        struct bridge_iflist *root_port = NULL, *bif;
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bstp_designated_port(sc, bif))
@@ -475,8 +473,7 @@
 {
        struct bridge_iflist *bif;
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bstp_designated_port(sc, bif))
@@ -515,8 +512,7 @@
 {
        struct bridge_iflist *bif;
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bif == sc->sc_root_port) {
@@ -793,8 +789,7 @@
 
        struct bridge_iflist *bif;
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bif->bif_designated_bridge == sc->sc_bridge_id)
@@ -833,8 +828,7 @@
 
        BRIDGE_LOCK(sc);
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bif->bif_ifp->if_type != IFT_ETHER)
@@ -888,8 +882,7 @@
 
        BRIDGE_LOCK(sc);
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if (bif->bif_flags & IFBIF_STP)
                        bstp_enable_port(sc, bif);
                else
@@ -909,8 +902,7 @@
        struct bridge_iflist *bif;
 
        BRIDGE_LOCK(sc);
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                bstp_set_port_state(bif, BSTP_IFSTATE_DISABLED);
                bstp_timer_stop(&bif->bif_hold_timer);
                bstp_timer_stop(&bif->bif_message_age_timer);
@@ -982,8 +974,7 @@
 
        root = bstp_root_bridge(sc);
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bstp_designated_port(sc, bif))
@@ -1076,8 +1067,7 @@
        s = splnet();
        BRIDGE_LOCK(sc);
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                /*
@@ -1100,8 +1090,7 @@
            sc->sc_topology_change_time))
                bstp_topology_change_timer_expiry(sc);
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bstp_timer_expired(&bif->bif_message_age_timer,
@@ -1109,8 +1098,7 @@
                        bstp_message_age_timer_expiry(sc, bif);
        }
 
-       PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
                if ((bif->bif_flags & IFBIF_STP) == 0)
                        continue;
                if (bstp_timer_expired(&bif->bif_forward_delay_timer,
diff -r f0070258b9bc -r 1260cb3b12f5 sys/net/if_bridge.c
--- a/sys/net/if_bridge.c       Tue Apr 19 07:03:12 2016 +0000
+++ b/sys/net/if_bridge.c       Tue Apr 19 07:10:22 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bridge.c,v 1.114 2016/04/19 07:03:12 ozaki-r Exp $  */
+/*     $NetBSD: if_bridge.c,v 1.115 2016/04/19 07:10:22 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.114 2016/04/19 07:03:12 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.115 2016/04/19 07:10:22 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_bridge_ipf.h"
@@ -214,6 +214,8 @@
                                } while (0)
 #endif
 
+struct psref_class *bridge_psref_class __read_mostly;
+
 int    bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
 
 static struct pool bridge_rtnode_pool;
@@ -256,13 +258,18 @@
 static void    bridge_rtnode_destroy(struct bridge_rtnode *);
 
 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
-                                                 const char *name);
+                                                 const char *name,
+                                                 struct psref *);
 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
-                                                    struct ifnet *ifp);
-static void    bridge_release_member(struct bridge_softc *, struct bridge_iflist *);
+                                                    struct ifnet *ifp,
+                                                    struct psref *);
+static void    bridge_release_member(struct bridge_softc *, struct bridge_iflist *,
+                                      struct psref *);
 static void    bridge_delete_member(struct bridge_softc *,
                                     struct bridge_iflist *);
-static struct bridge_iflist *bridge_try_hold_bif(struct bridge_iflist *);
+static void    bridge_acquire_member(struct bridge_softc *sc,
+                                      struct bridge_iflist *,
+                                      struct psref *);
 
 static int     bridge_ioctl_add(struct bridge_softc *, void *);
 static int     bridge_ioctl_del(struct bridge_softc *, void *);
@@ -371,6 +378,8 @@
        pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode),
            0, 0, 0, "brtpl", NULL, IPL_NET);
 
+       bridge_psref_class = psref_class_create("bridge", IPL_SOFTNET);
+
        if_clone_attach(&bridge_cloner);
 }
 
@@ -409,10 +418,9 @@
        callout_init(&sc->sc_brcallout, 0);
        callout_init(&sc->sc_bstpcallout, 0);
 
-       PSLIST_INIT(&sc->sc_iflist);
-       sc->sc_iflist_psz = pserialize_create();
-       sc->sc_iflist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
-       cv_init(&sc->sc_iflist_cv, "if_bridge_cv");
+       mutex_init(&sc->sc_iflist_psref.bip_lock, MUTEX_DEFAULT, IPL_NONE);
+       PSLIST_INIT(&sc->sc_iflist_psref.bip_iflist);
+       sc->sc_iflist_psref.bip_psz = pserialize_create();
 
        if_initname(ifp, ifc->ifc_name, unit);
        ifp->if_softc = sc;
@@ -453,13 +461,13 @@
 
        BRIDGE_LOCK(sc);
        for (;;) {
-               bif = PSLIST_WRITER_FIRST(&sc->sc_iflist, struct bridge_iflist,
+               bif = PSLIST_WRITER_FIRST(&sc->sc_iflist_psref.bip_iflist, struct bridge_iflist,
                    bif_next);
                if (bif == NULL)
                        break;
                bridge_delete_member(sc, bif);
        }
-       PSLIST_DESTROY(&sc->sc_iflist);
+       PSLIST_DESTROY(&sc->sc_iflist_psref.bip_iflist);
        BRIDGE_UNLOCK(sc);
 
        splx(s);
@@ -469,12 +477,8 @@
        /* Tear down the routing table. */
        bridge_rtable_fini(sc);
 
-       cv_destroy(&sc->sc_iflist_cv);
-
-       if (sc->sc_iflist_psz)
-               pserialize_destroy(sc->sc_iflist_psz);
-       if (sc->sc_iflist_lock)
-               mutex_obj_free(sc->sc_iflist_lock);
+       pserialize_destroy(sc->sc_iflist_psref.bip_psz);
+       mutex_destroy(&sc->sc_iflist_psref.bip_lock);
 
        workqueue_destroy(sc->sc_rtage_wq);
 
@@ -622,7 +626,7 @@
  *     Lookup a bridge member interface.
  */
 static struct bridge_iflist *
-bridge_lookup_member(struct bridge_softc *sc, const char *name)
+bridge_lookup_member(struct bridge_softc *sc, const char *name, struct psref *psref)
 {
        struct bridge_iflist *bif;
        struct ifnet *ifp;
@@ -630,13 +634,13 @@
 
        BRIDGE_PSZ_RENTER(s);
 
-       PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
-           bif_next) {
+       BRIDGE_IFLIST_READER_FOREACH(bif, sc) {
                ifp = bif->bif_ifp;
                if (strcmp(ifp->if_xname, name) == 0)
                        break;
        }
-       bif = bridge_try_hold_bif(bif);
+       if (bif != NULL)
+               bridge_acquire_member(sc, bif, psref);
 
        BRIDGE_PSZ_REXIT(s);
 
@@ -649,7 +653,8 @@
  *     Lookup a bridge member interface by ifnet*.
  */
 static struct bridge_iflist *
-bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
+bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp,
+    struct psref *psref)
 {
        struct bridge_iflist *bif;
        int s;
@@ -657,24 +662,22 @@
        BRIDGE_PSZ_RENTER(s);
 
        bif = member_ifp->if_bridgeif;
-       bif = bridge_try_hold_bif(bif);
+       if (bif != NULL) {
+               psref_acquire(psref, &bif->bif_psref,
+                   bridge_psref_class);
+       }
 
        BRIDGE_PSZ_REXIT(s);
 
        return bif;
 }
 
-static struct bridge_iflist *
-bridge_try_hold_bif(struct bridge_iflist *bif)
+static void
+bridge_acquire_member(struct bridge_softc *sc, struct bridge_iflist *bif,
+    struct psref *psref)
 {
 



Home | Main Index | Thread Index | Old Index