From e9d2206066eab74c7d53a7ed7124b84c85e4ab03 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 14 Nov 2008 12:48:06 +0000 Subject: [PATCH] - Defer bridge callouts to BRIDGE_CFGPORT using dropable priority message. - Remove unnecessary callout_stop(); bridge_stop() has already done those. --- sys/net/bridge/bridgestp.c | 45 +++++++++++++++++++++++++- sys/net/bridge/if_bridge.c | 59 ++++++++++++++++++++++++++++++----- sys/net/bridge/if_bridgevar.h | 8 ++++- 3 files changed, 103 insertions(+), 9 deletions(-) diff --git a/sys/net/bridge/bridgestp.c b/sys/net/bridge/bridgestp.c index 45d3023273..5f878989a2 100644 --- a/sys/net/bridge/bridgestp.c +++ b/sys/net/bridge/bridgestp.c @@ -31,7 +31,7 @@ * $OpenBSD: bridgestp.c,v 1.5 2001/03/22 03:48:29 jason Exp $ * $NetBSD: bridgestp.c,v 1.5 2003/11/28 08:56:48 keihan Exp $ * $FreeBSD: src/sys/net/bridgestp.c,v 1.7 2005/10/11 02:58:32 thompsa Exp $ - * $DragonFly: src/sys/net/bridge/bridgestp.c,v 1.5 2008/06/14 07:58:46 sephe Exp $ + * $DragonFly: src/sys/net/bridge/bridgestp.c,v 1.6 2008/11/14 12:48:06 sephe Exp $ */ /* @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -825,6 +826,8 @@ bstp_initialization(struct bridge_softc *sc) struct bridge_iflist *bif, *mif; u_char *e_addr; + KKASSERT(&curthread->td_msgport == BRIDGE_CFGPORT); + mif = NULL; LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { if ((bif->bif_flags & IFBIF_STP) == 0) @@ -891,6 +894,9 @@ void bstp_stop(struct bridge_softc *sc) { struct bridge_iflist *bif; + struct lwkt_msg *lmsg; + + KKASSERT(&curthread->td_msgport == BRIDGE_CFGPORT); LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { bstp_set_port_state(bif, BSTP_IFSTATE_DISABLED); @@ -905,6 +911,13 @@ bstp_stop(struct bridge_softc *sc) bstp_timer_stop(&sc->sc_tcn_timer); bstp_timer_stop(&sc->sc_hello_timer); + crit_enter(); + lmsg = &sc->sc_bstptimemsg.nm_lmsg; + if ((lmsg->ms_flags & MSGF_DONE) == 0) { + /* Pending to be processed; drop it */ + lwkt_dropmsg(lmsg); + } + crit_exit(); } static void @@ -1079,8 +1092,38 @@ static void bstp_tick(void *arg) { struct bridge_softc *sc = arg; + struct lwkt_msg *lmsg; + + KKASSERT(mycpuid == BRIDGE_CFGCPU); + + crit_enter(); + + if (callout_pending(&sc->sc_bstpcallout) || + !callout_active(&sc->sc_bstpcallout)) { + crit_exit(); + return; + } + callout_deactivate(&sc->sc_bstpcallout); + + lmsg = &sc->sc_bstptimemsg.nm_lmsg; + KKASSERT(lmsg->ms_flags & MSGF_DONE); + lwkt_sendmsg(BRIDGE_CFGPORT, lmsg); + + crit_exit(); +} + +void +bstp_tick_handler(struct netmsg *nmsg) +{ + struct bridge_softc *sc = nmsg->nm_lmsg.u.ms_resultp; struct bridge_iflist *bif; + KKASSERT(&curthread->td_msgport == BRIDGE_CFGPORT); + crit_enter(); + /* Reply ASAP */ + lwkt_replymsg(&nmsg->nm_lmsg, 0); + crit_exit(); + lwkt_serialize_enter(sc->sc_ifp->if_serializer); LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { diff --git a/sys/net/bridge/if_bridge.c b/sys/net/bridge/if_bridge.c index 7e608b62a2..33d18de8ef 100644 --- a/sys/net/bridge/if_bridge.c +++ b/sys/net/bridge/if_bridge.c @@ -66,7 +66,7 @@ * $OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp $ * $NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc Exp $ * $FreeBSD: src/sys/net/if_bridge.c,v 1.26 2005/10/13 23:05:55 thompsa Exp $ - * $DragonFly: src/sys/net/bridge/if_bridge.c,v 1.47 2008/11/13 11:30:25 sephe Exp $ + * $DragonFly: src/sys/net/bridge/if_bridge.c,v 1.48 2008/11/14 12:48:06 sephe Exp $ */ /* @@ -176,8 +176,6 @@ */ #define BRIDGE_IFCAPS_MASK IFCAP_TXCSUM -#define BRIDGE_CFGPORT cpu_portfn(0) - eventhandler_tag bridge_detach_cookie = NULL; extern struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *); @@ -202,6 +200,7 @@ static int bridge_output(struct ifnet *, struct mbuf *); static void bridge_forward(struct bridge_softc *, struct mbuf *m); +static void bridge_timer_handler(struct netmsg *); static void bridge_timer(void *); static void bridge_broadcast(struct bridge_softc *, struct ifnet *, @@ -448,7 +447,14 @@ bridge_clone_create(struct if_clone *ifc, int unit) bridge_rtable_init(sc); callout_init(&sc->sc_brcallout); + netmsg_init(&sc->sc_brtimemsg, &netisr_adone_rport, + MSGF_DROPABLE | MSGF_PRIORITY, bridge_timer_handler); + sc->sc_brtimemsg.nm_lmsg.u.ms_resultp = sc; + callout_init(&sc->sc_bstpcallout); + netmsg_init(&sc->sc_bstptimemsg, &netisr_adone_rport, + MSGF_DROPABLE | MSGF_PRIORITY, bstp_tick_handler); + sc->sc_bstptimemsg.nm_lmsg.u.ms_resultp = sc; LIST_INIT(&sc->sc_iflist); LIST_INIT(&sc->sc_spanlist); @@ -529,9 +535,6 @@ bridge_clone_destroy(struct ifnet *ifp) bridge_stop(ifp); ifp->if_flags &= ~IFF_UP; - callout_stop(&sc->sc_brcallout); - callout_stop(&sc->sc_bstpcallout); - lwkt_serialize_exit(ifp->if_serializer); netmsg_init(&nmsg, &curthread->td_msgport, 0, bridge_delete_dispatch); @@ -821,11 +824,21 @@ static int bridge_ioctl_stop(struct bridge_softc *sc, void *arg __unused) { struct ifnet *ifp = sc->sc_ifp; + struct lwkt_msg *lmsg; if ((ifp->if_flags & IFF_RUNNING) == 0) return 0; callout_stop(&sc->sc_brcallout); + + crit_enter(); + lmsg = &sc->sc_brtimemsg.nm_lmsg; + if ((lmsg->ms_flags & MSGF_DONE) == 0) { + /* Pending to be processed; drop it */ + lwkt_dropmsg(lmsg); + } + crit_exit(); + bstp_stop(sc); ifp->if_flags &= ~IFF_RUNNING; @@ -2209,14 +2222,46 @@ static void bridge_timer(void *arg) { struct bridge_softc *sc = arg; + struct lwkt_msg *lmsg; + + KKASSERT(mycpuid == BRIDGE_CFGCPU); + + crit_enter(); + + if (callout_pending(&sc->sc_brcallout) || + !callout_active(&sc->sc_brcallout)) { + crit_exit(); + return; + } + callout_deactivate(&sc->sc_brcallout); + + lmsg = &sc->sc_brtimemsg.nm_lmsg; + KKASSERT(lmsg->ms_flags & MSGF_DONE); + lwkt_sendmsg(BRIDGE_CFGPORT, lmsg); + + crit_exit(); +} + +static void +bridge_timer_handler(struct netmsg *nmsg) +{ + struct bridge_softc *sc = nmsg->nm_lmsg.u.ms_resultp; + + KKASSERT(&curthread->td_msgport == BRIDGE_CFGPORT); + + crit_enter(); + /* Reply ASAP */ + lwkt_replymsg(&nmsg->nm_lmsg, 0); + crit_exit(); lwkt_serialize_enter(sc->sc_ifp->if_serializer); bridge_rtage(sc); - if (sc->sc_ifp->if_flags & IFF_RUNNING) + if (sc->sc_ifp->if_flags & IFF_RUNNING) { callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz, bridge_timer, sc); + } lwkt_serialize_exit(sc->sc_ifp->if_serializer); } diff --git a/sys/net/bridge/if_bridgevar.h b/sys/net/bridge/if_bridgevar.h index 012fc6d3d0..0f955f417a 100644 --- a/sys/net/bridge/if_bridgevar.h +++ b/sys/net/bridge/if_bridgevar.h @@ -66,7 +66,7 @@ * $OpenBSD: if_bridge.h,v 1.14 2001/03/22 03:48:29 jason Exp $ * $NetBSD: if_bridgevar.h,v 1.4 2003/07/08 07:13:50 itojun Exp $ * $FreeBSD: src/sys/net/if_bridgevar.h,v 1.4 2005/07/06 01:24:45 thompsa Exp $ - * $DragonFly: src/sys/net/bridge/if_bridgevar.h,v 1.4 2008/06/14 07:58:46 sephe Exp $ + * $DragonFly: src/sys/net/bridge/if_bridgevar.h,v 1.5 2008/11/14 12:48:06 sephe Exp $ */ /* @@ -290,7 +290,9 @@ struct bridge_softc { uint32_t sc_brtcnt; /* cur. # of addresses */ uint32_t sc_brttimeout; /* rt timeout in seconds */ struct callout sc_brcallout; /* bridge callout */ + struct netmsg sc_brtimemsg; /* bridge callout msg */ struct callout sc_bstpcallout; /* STP callout */ + struct netmsg sc_bstptimemsg; /* STP callout msg */ LIST_HEAD(, bridge_iflist) sc_iflist; /* member interface list */ LIST_HEAD(, bridge_rtnode) *sc_rthash; /* our forwarding table */ LIST_HEAD(, bridge_rtnode) sc_rtlist; /* list version of above */ @@ -300,6 +302,9 @@ struct bridge_softc { }; #define sc_if sc_arp.ac_if +#define BRIDGE_CFGCPU 0 +#define BRIDGE_CFGPORT cpu_portfn(BRIDGE_CFGCPU) + extern const uint8_t bstp_etheraddr[]; void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp, int); @@ -311,6 +316,7 @@ void bstp_linkstate(struct ifnet *, int); void bstp_stop(struct bridge_softc *); struct mbuf *bstp_input(struct bridge_softc *, struct bridge_iflist *, struct mbuf *); +void bstp_tick_handler(struct netmsg *); void bridge_enqueue(struct ifnet *, struct mbuf *); -- 2.41.0