Embed a netmsg in ifaddr_container, so IFAFREE could be non-blocking
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 17 Sep 2008 11:25:16 +0000 (11:25 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 17 Sep 2008 11:25:16 +0000 (11:25 +0000)
sys/net/if.c
sys/net/if_var.h

index 75c09ec..3408a02 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)if.c        8.3 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/net/if.c,v 1.185 2004/03/13 02:35:03 brooks Exp $
- * $DragonFly: src/sys/net/if.c,v 1.77 2008/08/17 06:01:50 sephe Exp $
+ * $DragonFly: src/sys/net/if.c,v 1.78 2008/09/17 11:25:16 sephe Exp $
  */
 
 #include "opt_compat.h"
@@ -2179,19 +2179,14 @@ ifa_create(int size, int flags)
        return ifa;
 }
 
-struct ifac_free_arg {
-       struct ifaddr   *ifa;
-       int             cpuid;
-};
-
 static void
 ifac_free_dispatch(struct netmsg *nmsg)
 {
-       struct lwkt_msg *msg = &nmsg->nm_lmsg;
-       struct ifac_free_arg *arg = msg->u.ms_resultp;
-       struct ifaddr *ifa = arg->ifa;
+       struct netmsg_ifaddr_free *fmsg = (struct netmsg_ifaddr_free *)nmsg;
+       struct ifaddr *ifa = fmsg->nm_ifaddr;
 
-       ifa->ifa_cpumask &= ~(1 << arg->cpuid);
+       KKASSERT(ifa->ifa_cpumask & (1 << fmsg->nm_cpuid));
+       ifa->ifa_cpumask &= ~(1 << fmsg->nm_cpuid);
        if (ifa->ifa_cpumask == 0) {
 #ifdef IFADDR_DEBUG
                kprintf("free ifa %p\n", ifa);
@@ -2199,15 +2194,13 @@ ifac_free_dispatch(struct netmsg *nmsg)
                kfree(ifa->ifa_containers, M_IFADDR);
                kfree(ifa, M_IFADDR);
        }
-       lwkt_replymsg(msg, 0);
+       /* Don't reply, 'nmsg' is embedded in ifaddr_container */
 }
 
 void
 ifac_free(struct ifaddr_container *ifac, int cpu_id)
 {
-       struct ifac_free_arg arg;
-       struct netmsg nmsg;
-       struct lwkt_msg *msg;
+       struct netmsg_ifaddr_free *fmsg;
 
        KKASSERT(ifac->ifa_magic == IFA_CONTAINER_MAGIC);
        KKASSERT(ifac->ifa_refcnt == 0);
@@ -2216,18 +2209,17 @@ ifac_free(struct ifaddr_container *ifac, int cpu_id)
 
        ifac->ifa_magic = IFA_CONTAINER_DEAD;
 
-       bzero(&arg, sizeof(arg));
-       arg.ifa = ifac->ifa;
-       arg.cpuid = cpu_id;
 #ifdef IFADDR_DEBUG_VERBOSE
-       kprintf("try free ifa %p cpu_id %d\n", ifac->ifa, arg.cpuid);
+       kprintf("try free ifa %p cpu_id %d\n", ifac->ifa, cpu_id);
 #endif
 
-       netmsg_init(&nmsg, &curthread->td_msgport, 0, ifac_free_dispatch);
-       msg = &nmsg.nm_lmsg;
-       msg->u.ms_resultp = &arg;
+       fmsg = &ifac->ifa_freemsg;
+       netmsg_init(&fmsg->nm_netmsg, &netisr_apanic_rport, 0,
+                   ifac_free_dispatch);
+       fmsg->nm_ifaddr = ifac->ifa;
+       fmsg->nm_cpuid = cpu_id;
 
-       ifa_domsg(msg, 0);
+       ifa_sendmsg(&fmsg->nm_netmsg.nm_lmsg, 0);
 }
 
 static void
@@ -2353,6 +2345,13 @@ ifnet_domsg(struct lwkt_msg *lmsg, int cpu)
        lwkt_domsg(ifnet_portfn(cpu), lmsg, 0);
 }
 
+void
+ifnet_sendmsg(struct lwkt_msg *lmsg, int cpu)
+{
+       KKASSERT(cpu < ncpus);
+       lwkt_sendmsg(ifnet_portfn(cpu), lmsg);
+}
+
 static void
 ifnetinit(void *dummy __unused)
 {
index 5c02d61..8316dfc 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     From: @(#)if.h  8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/net/if_var.h,v 1.18.2.16 2003/04/15 18:11:19 fjoe Exp $
- * $DragonFly: src/sys/net/if_var.h,v 1.67 2008/09/17 08:51:29 sephe Exp $
+ * $DragonFly: src/sys/net/if_var.h,v 1.68 2008/09/17 11:25:16 sephe Exp $
  */
 
 #ifndef        _NET_IF_VAR_H_
@@ -363,6 +363,16 @@ if_handoff(struct ifqueue *_ifq, struct mbuf *_m, struct ifnet *_ifp,
 
 #endif /* _KERNEL */
 
+#ifndef _NET_NETMSG_H_
+#include <net/netmsg.h>
+#endif
+
+struct netmsg_ifaddr_free {
+       struct netmsg   nm_netmsg;
+       struct ifaddr   *nm_ifaddr;
+       int             nm_cpuid;
+};
+
 struct in_ifaddr;
 
 struct in_ifaddr_container {
@@ -382,6 +392,7 @@ struct ifaddr_container {
        TAILQ_ENTRY(ifaddr_container)   ifa_link;   /* queue macro glue */
        u_int                   ifa_refcnt; /* references to this structure */
        uint32_t                ifa_listmask;   /* IFA_LIST_ */
+       struct netmsg_ifaddr_free ifa_freemsg;  /* Used by IFAFREE */
 
        /*
         * Protocol specific states
@@ -520,6 +531,7 @@ IFAFREE(struct ifaddr *_ifa)
 
 struct lwkt_port *ifnet_portfn(int);
 void   ifnet_domsg(struct lwkt_msg *, int);
+void   ifnet_sendmsg(struct lwkt_msg *, int);
 void   ifnet_forwardmsg(struct lwkt_msg *, int);
 
 static __inline void
@@ -528,6 +540,12 @@ ifa_domsg(struct lwkt_msg *_lmsg, int _cpu)
        ifnet_domsg(_lmsg, _cpu);
 }
 
+static __inline void
+ifa_sendmsg(struct lwkt_msg *_lmsg, int _cpu)
+{
+       ifnet_sendmsg(_lmsg, _cpu);
+}
+
 static __inline void
 ifa_forwardmsg(struct lwkt_msg *_lmsg, int _nextcpu)
 {