- Defer bridge callouts to BRIDGE_CFGPORT using dropable priority message.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 14 Nov 2008 12:48:06 +0000 (12:48 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 14 Nov 2008 12:48:06 +0000 (12:48 +0000)
- Remove unnecessary callout_stop(); bridge_stop() has already done those.

sys/net/bridge/bridgestp.c
sys/net/bridge/if_bridge.c
sys/net/bridge/if_bridgevar.h

index 45d3023..5f87898 100644 (file)
@@ -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 <sys/lock.h>
 #include <sys/thread.h>
 #include <sys/thread2.h>
+#include <sys/msgport2.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -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) {
index 7e608b6..33d18de 100644 (file)
@@ -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 $
  */
 
 /*
  */
 #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);
 }
index 012fc6d..0f955f4 100644 (file)
@@ -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 *);