Use pslist(9) in bridge(4)
This adds missing memory barriers to list operations for pserialize.
This commit is contained in:
parent
dd3c4fc3e5
commit
814cd05c8b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bridgestp.c,v 1.19 2016/02/15 01:11:41 ozaki-r Exp $ */
|
||||
/* $NetBSD: bridgestp.c,v 1.20 2016/04/11 02:04:14 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
|
||||
|
@ -40,7 +40,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.19 2016/02/15 01:11:41 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.20 2016/04/11 02:04:14 ozaki-r Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -341,7 +341,8 @@ bstp_config_bpdu_generation(struct bridge_softc *sc)
|
|||
{
|
||||
struct bridge_iflist *bif;
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bstp_designated_port(sc, bif) &&
|
||||
|
@ -415,7 +416,8 @@ bstp_root_selection(struct bridge_softc *sc)
|
|||
{
|
||||
struct bridge_iflist *root_port = NULL, *bif;
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bstp_designated_port(sc, bif))
|
||||
|
@ -473,7 +475,8 @@ bstp_designated_port_selection(struct bridge_softc *sc)
|
|||
{
|
||||
struct bridge_iflist *bif;
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bstp_designated_port(sc, bif))
|
||||
|
@ -512,7 +515,8 @@ bstp_port_state_selection(struct bridge_softc *sc)
|
|||
{
|
||||
struct bridge_iflist *bif;
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bif == sc->sc_root_port) {
|
||||
|
@ -789,7 +793,8 @@ bstp_designated_for_some_port(struct bridge_softc *sc)
|
|||
|
||||
struct bridge_iflist *bif;
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bif->bif_designated_bridge == sc->sc_bridge_id)
|
||||
|
@ -828,7 +833,8 @@ bstp_initialization(struct bridge_softc *sc)
|
|||
|
||||
BRIDGE_LOCK(sc);
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bif->bif_ifp->if_type != IFT_ETHER)
|
||||
|
@ -882,7 +888,8 @@ bstp_initialization(struct bridge_softc *sc)
|
|||
|
||||
BRIDGE_LOCK(sc);
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if (bif->bif_flags & IFBIF_STP)
|
||||
bstp_enable_port(sc, bif);
|
||||
else
|
||||
|
@ -902,7 +909,8 @@ bstp_stop(struct bridge_softc *sc)
|
|||
struct bridge_iflist *bif;
|
||||
|
||||
BRIDGE_LOCK(sc);
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_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);
|
||||
|
@ -974,7 +982,8 @@ bstp_set_bridge_priority(struct bridge_softc *sc, uint64_t new_bridge_id)
|
|||
|
||||
root = bstp_root_bridge(sc);
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bstp_designated_port(sc, bif))
|
||||
|
@ -1067,7 +1076,8 @@ bstp_tick(void *arg)
|
|||
s = splnet();
|
||||
BRIDGE_LOCK(sc);
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
/*
|
||||
|
@ -1090,7 +1100,8 @@ bstp_tick(void *arg)
|
|||
sc->sc_topology_change_time))
|
||||
bstp_topology_change_timer_expiry(sc);
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bstp_timer_expired(&bif->bif_message_age_timer,
|
||||
|
@ -1098,7 +1109,8 @@ bstp_tick(void *arg)
|
|||
bstp_message_age_timer_expiry(sc, bif);
|
||||
}
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
if ((bif->bif_flags & IFBIF_STP) == 0)
|
||||
continue;
|
||||
if (bstp_timer_expired(&bif->bif_forward_delay_timer,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_bridge.c,v 1.111 2016/03/28 04:38:04 ozaki-r Exp $ */
|
||||
/* $NetBSD: if_bridge.c,v 1.112 2016/04/11 02:04:14 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.111 2016/03/28 04:38:04 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.112 2016/04/11 02:04:14 ozaki-r Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_bridge_ipf.h"
|
||||
|
@ -399,7 +399,7 @@ bridge_clone_create(struct if_clone *ifc, int unit)
|
|||
callout_init(&sc->sc_brcallout, 0);
|
||||
callout_init(&sc->sc_bstpcallout, 0);
|
||||
|
||||
LIST_INIT(&sc->sc_iflist);
|
||||
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);
|
||||
|
@ -447,8 +447,14 @@ bridge_clone_destroy(struct ifnet *ifp)
|
|||
bridge_stop(ifp, 1);
|
||||
|
||||
BRIDGE_LOCK(sc);
|
||||
while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
|
||||
for (;;) {
|
||||
bif = PSLIST_WRITER_FIRST(&sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next);
|
||||
if (bif == NULL)
|
||||
break;
|
||||
bridge_delete_member(sc, bif);
|
||||
}
|
||||
PSLIST_DESTROY(&sc->sc_iflist);
|
||||
BRIDGE_UNLOCK(sc);
|
||||
|
||||
splx(s);
|
||||
|
@ -619,7 +625,8 @@ bridge_lookup_member(struct bridge_softc *sc, const char *name)
|
|||
|
||||
BRIDGE_PSZ_RENTER(s);
|
||||
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
ifp = bif->bif_ifp;
|
||||
if (strcmp(ifp->if_xname, name) == 0)
|
||||
break;
|
||||
|
@ -705,7 +712,8 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
|
|||
ifs->if_bridge = NULL;
|
||||
ifs->if_bridgeif = NULL;
|
||||
|
||||
LIST_REMOVE(bif, bif_next);
|
||||
PSLIST_WRITER_REMOVE(bif, bif_next);
|
||||
PSLIST_ENTRY_DESTROY(bif, bif_next);
|
||||
|
||||
BRIDGE_PSZ_PERFORM(sc);
|
||||
|
||||
|
@ -777,12 +785,13 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
|||
bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
|
||||
bif->bif_refs = 0;
|
||||
bif->bif_waiting = false;
|
||||
PSLIST_ENTRY_INIT(bif, bif_next);
|
||||
|
||||
BRIDGE_LOCK(sc);
|
||||
|
||||
ifs->if_bridge = sc;
|
||||
ifs->if_bridgeif = bif;
|
||||
LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
|
||||
PSLIST_WRITER_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
|
||||
ifs->_if_input = bridge_input;
|
||||
|
||||
BRIDGE_UNLOCK(sc);
|
||||
|
@ -814,7 +823,8 @@ bridge_ioctl_del(struct bridge_softc *sc, void *arg)
|
|||
* Don't use bridge_lookup_member. We want to get a member
|
||||
* with bif_refs == 0.
|
||||
*/
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_WRITER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
ifs = bif->bif_ifp;
|
||||
if (strcmp(ifs->if_xname, name) == 0)
|
||||
break;
|
||||
|
@ -939,7 +949,8 @@ bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
|
|||
retry:
|
||||
BRIDGE_LOCK(sc);
|
||||
count = 0;
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next)
|
||||
count++;
|
||||
BRIDGE_UNLOCK(sc);
|
||||
|
||||
|
@ -959,7 +970,8 @@ retry:
|
|||
BRIDGE_LOCK(sc);
|
||||
|
||||
i = 0;
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next)
|
||||
i++;
|
||||
if (i > count) {
|
||||
/*
|
||||
|
@ -972,7 +984,8 @@ retry:
|
|||
}
|
||||
|
||||
i = 0;
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
struct ifbreq *breq = &breqs[i++];
|
||||
memset(breq, 0, sizeof(*breq));
|
||||
|
||||
|
@ -1463,7 +1476,8 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa,
|
|||
int ss;
|
||||
|
||||
BRIDGE_PSZ_RENTER(ss);
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist,
|
||||
struct bridge_iflist, bif_next) {
|
||||
bif = bridge_try_hold_bif(bif);
|
||||
if (bif == NULL)
|
||||
continue;
|
||||
|
@ -1489,7 +1503,8 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa,
|
|||
}
|
||||
}
|
||||
|
||||
if (LIST_NEXT(bif, bif_next) == NULL) {
|
||||
if (PSLIST_READER_NEXT(bif, struct bridge_iflist,
|
||||
bif_next) == NULL) {
|
||||
used = 1;
|
||||
mc = m;
|
||||
} else {
|
||||
|
@ -1787,7 +1802,8 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
|
|||
int s;
|
||||
|
||||
BRIDGE_PSZ_RENTER(s);
|
||||
LIST_FOREACH(_bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(_bif, &sc->sc_iflist,
|
||||
struct bridge_iflist, bif_next) {
|
||||
/* It is destined for us. */
|
||||
if (bridge_ourether(_bif, eh, 0)) {
|
||||
_bif = bridge_try_hold_bif(_bif);
|
||||
|
@ -1863,7 +1879,8 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
|
|||
bmcast = m->m_flags & (M_BCAST|M_MCAST);
|
||||
|
||||
BRIDGE_PSZ_RENTER(s);
|
||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||
PSLIST_READER_FOREACH(bif, &sc->sc_iflist, struct bridge_iflist,
|
||||
bif_next) {
|
||||
bif = bridge_try_hold_bif(bif);
|
||||
if (bif == NULL)
|
||||
continue;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_bridgevar.h,v 1.26 2016/02/15 01:11:41 ozaki-r Exp $ */
|
||||
/* $NetBSD: if_bridgevar.h,v 1.27 2016/04/11 02:04:14 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Wasabi Systems, Inc.
|
||||
|
@ -79,6 +79,7 @@
|
|||
#include <sys/queue.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/pslist.h>
|
||||
|
||||
/*
|
||||
* Commands used in the SIOCSDRVSPEC ioctl. Note the lookup of the
|
||||
|
@ -248,7 +249,7 @@ struct bstp_tcn_unit {
|
|||
* Bridge interface list entry.
|
||||
*/
|
||||
struct bridge_iflist {
|
||||
LIST_ENTRY(bridge_iflist) bif_next;
|
||||
struct pslist_entry bif_next;
|
||||
uint64_t bif_designated_root;
|
||||
uint64_t bif_designated_bridge;
|
||||
uint32_t bif_path_cost;
|
||||
|
@ -311,7 +312,7 @@ struct bridge_softc {
|
|||
uint32_t sc_brttimeout; /* rt timeout in seconds */
|
||||
callout_t sc_brcallout; /* bridge callout */
|
||||
callout_t sc_bstpcallout; /* STP callout */
|
||||
LIST_HEAD(, bridge_iflist) sc_iflist; /* member interface list */
|
||||
struct pslist_head sc_iflist; /* member interface list */
|
||||
kcondvar_t sc_iflist_cv;
|
||||
pserialize_t sc_iflist_psz;
|
||||
kmutex_t *sc_iflist_lock;
|
||||
|
|
Loading…
Reference in New Issue