commit 851b048ac918a05e66b2fa902a9d958ca6d1e1a5 Author: Ryota Ozaki Date: Tue Apr 14 13:06:48 2015 +0900 Use refcount(9) diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index 3915a91..9333aa5 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -601,7 +601,7 @@ bstp_input(struct bridge_softc *sc, struct bridge_iflist *bif, struct mbuf *m) uint16_t len; #ifdef BRIDGE_MPSAFE - KASSERT(bif->bif_refs > 0); + KASSERT(refcount_referenced_p(&bif->bif_refcount)); #endif eh = mtod(m, struct ether_header *); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 41472a9..b662746 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -102,6 +102,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.97 2015/01/08 10:47:44 ozaki-r Exp $ #include #include #include +#include #include #include @@ -773,10 +774,8 @@ bridge_try_hold_bif(struct bridge_iflist *bif) { #ifdef BRIDGE_MPSAFE if (bif != NULL) { - if (bif->bif_waiting) + if (refcount_inc(&bif->bif_refcount) != 0) bif = NULL; - else - atomic_inc_32(&bif->bif_refs); } #endif return bif; @@ -791,14 +790,8 @@ 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); - if (__predict_false(refs == 0 && bif->bif_waiting)) { - BRIDGE_INTR_LOCK(sc); - cv_broadcast(&sc->sc_iflist_cv); - BRIDGE_INTR_UNLOCK(sc); - } + refcount_dec_broadcast(&bif->bif_refcount, sc->sc_iflist_intr_lock, + &sc->sc_iflist_cv); #else (void)sc; (void)bif; @@ -828,15 +821,11 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif) BRIDGE_UNLOCK(sc); #ifdef BRIDGE_MPSAFE - BRIDGE_INTR_LOCK(sc); - bif->bif_waiting = true; - membar_sync(); - while (bif->bif_refs > 0) { - aprint_debug("%s: cv_wait on iflist\n", __func__); - cv_wait(&sc->sc_iflist_cv, sc->sc_iflist_intr_lock); - } - bif->bif_waiting = false; - BRIDGE_INTR_UNLOCK(sc); + mutex_enter(sc->sc_iflist_intr_lock); + refcount_dec_drain(&bif->bif_refcount, sc->sc_iflist_intr_lock, + &sc->sc_iflist_cv); + mutex_exit(sc->sc_iflist_intr_lock); + refcount_fini(&bif->bif_refcount); #endif kmem_free(bif, sizeof(*bif)); @@ -890,8 +879,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg) bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY; bif->bif_path_cost = BSTP_DEFAULT_PATH_COST; - bif->bif_refs = 0; - bif->bif_waiting = false; + refcount_init(&bif->bif_refcount); BRIDGE_LOCK(sc); @@ -926,8 +914,8 @@ bridge_ioctl_del(struct bridge_softc *sc, void *arg) BRIDGE_LOCK(sc); /* - * Don't use bridge_lookup_member. We want to get a member - * with bif_refs == 0. + * Don't use bridge_lookup_member to get a member + * without incrementing refcount. */ LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { ifs = bif->bif_ifp; diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h index 4bdecab..0f41e6e9 100644 --- a/sys/net/if_bridgevar.h +++ b/sys/net/if_bridgevar.h @@ -79,6 +79,7 @@ #include #include #include +#include /* * Commands used in the SIOCSDRVSPEC ioctl. Note the lookup of the @@ -264,8 +265,7 @@ struct bridge_iflist { uint8_t bif_priority; struct ifnet *bif_ifp; /* member if */ uint32_t bif_flags; /* member if flags */ - uint32_t bif_refs; /* reference count */ - bool bif_waiting; /* waiting for released */ + struct refcount bif_refcount; /* reference count */ }; /*