carp: Lockless MPSAFE step 4 of many
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 4 Apr 2012 12:07:22 +0000 (20:07 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 4 Apr 2012 12:07:22 +0000 (20:07 +0800)
Dispatch "stop" method from if_ioctl to netisr0 for further processing

sys/netinet/ip_carp.c

index 33f87dc..ff41dc9 100644 (file)
@@ -251,6 +251,7 @@ static void carp_multicast6_cleanup(struct carp_softc *);
 #endif
 static void    carp_stop(struct carp_softc *, int);
 static void    carp_suspend(struct carp_softc *, int);
+static void    carp_ioctl_stop(struct carp_softc *);
 
 static void    carp_ifaddr(void *, struct ifnet *, enum ifaddr_event,
                            struct ifaddr *);
@@ -259,6 +260,7 @@ static void carp_ifdetach(void *, struct ifnet *);
 static void    carp_ifdetach_dispatch(netmsg_t);
 static void    carp_clone_destroy_dispatch(netmsg_t);
 static void    carp_init_dispatch(netmsg_t);
+static void    carp_ioctl_stop_dispatch(netmsg_t);
 
 static MALLOC_DEFINE(M_CARP, "CARP", "CARP interfaces");
 
@@ -1896,6 +1898,8 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr, struct ucred *cr)
        char devname[IFNAMSIZ];
        int error = 0;
 
+       ASSERT_IFNET_SERIALIZED_ALL(ifp);
+
        carp_gettok();
 
        ifa = (struct ifaddr *)addr;
@@ -1909,7 +1913,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr, struct ucred *cr)
                        if ((ifp->if_flags & IFF_RUNNING) == 0)
                                carp_init(sc);
                } else if (ifp->if_flags & IFF_RUNNING) {
-                       carp_stop(sc, 0);
+                       carp_ioctl_stop(sc);
                }
                break;
 
@@ -2046,6 +2050,39 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr, struct ucred *cr)
 }
 
 static void
+carp_ioctl_stop_dispatch(netmsg_t msg)
+{
+       struct netmsg_carp *cmsg = (struct netmsg_carp *)msg;
+       struct carp_softc *sc = cmsg->nc_softc;
+
+       carp_gettok();
+       carp_stop(sc, 0);
+       carp_reltok();
+
+       lwkt_replymsg(&cmsg->base.lmsg, 0);
+}
+
+static void
+carp_ioctl_stop(struct carp_softc *sc)
+{
+       struct ifnet *ifp = &sc->arpcom.ac_if;
+       struct netmsg_carp cmsg;
+
+       ASSERT_IFNET_SERIALIZED_ALL(ifp);
+
+       ifnet_deserialize_all(ifp);
+
+       bzero(&cmsg, sizeof(cmsg));
+       netmsg_init(&cmsg.base, NULL, &curthread->td_msgport, 0,
+           carp_ioctl_stop_dispatch);
+       cmsg.nc_softc = sc;
+
+       lwkt_domsg(cpu_portfn(0), &cmsg.base.lmsg, 0);
+
+       ifnet_serialize_all(ifp);
+}
+
+static void
 carp_init_dispatch(netmsg_t msg)
 {
        struct netmsg_carp *cmsg = (struct netmsg_carp *)msg;