Record number of valid ifaddr containers in ifaddr, so we could use
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 11 Nov 2008 13:48:01 +0000 (13:48 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 11 Nov 2008 13:48:01 +0000 (13:48 +0000)
atomic_fetchadd_int() to avoid N->0 race instead of using thread based
serialization.  Remove the netmsg embedded in ifaddr_container; it is
no longer needed/used.

sys/net/if.c
sys/net/if_var.h

index 808be96..25b56ca 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.81 2008/10/03 00:26:21 hasso Exp $
+ * $DragonFly: src/sys/net/if.c,v 1.82 2008/11/11 13:48:01 sephe Exp $
  */
 
 #include "opt_compat.h"
@@ -74,6 +74,7 @@
 #include <net/netisr.h>
 #include <net/netmsg2.h>
 
+#include <machine/atomic.h>
 #include <machine/stdarg.h>
 #include <machine/smp.h>
 
@@ -2173,7 +2174,7 @@ ifa_create(int size, int flags)
 
        ifa->ifa_containers = kmalloc(ncpus * sizeof(struct ifaddr_container),
                                      M_IFADDR, M_WAITOK | M_ZERO);
-       ifa->ifa_cpumask = smp_active_mask;
+       ifa->ifa_ncnt = ncpus;
        for (i = 0; i < ncpus; ++i) {
                struct ifaddr_container *ifac = &ifa->ifa_containers[i];
 
@@ -2187,28 +2188,10 @@ ifa_create(int size, int flags)
        return ifa;
 }
 
-static void
-ifac_free_dispatch(struct netmsg *nmsg)
-{
-       struct netmsg_ifaddr_free *fmsg = (struct netmsg_ifaddr_free *)nmsg;
-       struct ifaddr *ifa = fmsg->nm_ifaddr;
-
-       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);
-#endif
-               kfree(ifa->ifa_containers, M_IFADDR);
-               kfree(ifa, M_IFADDR);
-       }
-       /* Don't reply, 'nmsg' is embedded in ifaddr_container */
-}
-
 void
 ifac_free(struct ifaddr_container *ifac, int cpu_id)
 {
-       struct netmsg_ifaddr_free *fmsg;
+       struct ifaddr *ifa = ifac->ifa;
 
        KKASSERT(ifac->ifa_magic == IFA_CONTAINER_MAGIC);
        KKASSERT(ifac->ifa_refcnt == 0);
@@ -2221,13 +2204,15 @@ ifac_free(struct ifaddr_container *ifac, int cpu_id)
        kprintf("try free ifa %p cpu_id %d\n", ifac->ifa, cpu_id);
 #endif
 
-       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_sendmsg(&fmsg->nm_netmsg.nm_lmsg, 0);
+       KASSERT(ifa->ifa_ncnt > 0 && ifa->ifa_ncnt <= ncpus,
+               ("invalid # of ifac, %d\n", ifa->ifa_ncnt));
+       if (atomic_fetchadd_int(&ifa->ifa_ncnt, -1) == 1) {
+#ifdef IFADDR_DEBUG
+               kprintf("free ifa %p\n", ifa);
+#endif
+               kfree(ifa->ifa_containers, M_IFADDR);
+               kfree(ifa, M_IFADDR);
+       }
 }
 
 static void
index 8316dfc..f804abf 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.68 2008/09/17 11:25:16 sephe Exp $
+ * $DragonFly: src/sys/net/if_var.h,v 1.69 2008/11/11 13:48:01 sephe Exp $
  */
 
 #ifndef        _NET_IF_VAR_H_
@@ -363,16 +363,6 @@ 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 {
@@ -392,7 +382,6 @@ 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
@@ -424,7 +413,7 @@ struct ifaddr {
        void    (*ifa_rtrequest)        /* check or clean routes (+ or -)'d */
                (int, struct rtentry *, struct rt_addrinfo *);
        u_short ifa_flags;              /* mostly rt_flags for cloning */
-       cpumask_t ifa_cpumask;
+       int     ifa_ncnt;               /* # of valid ifaddr_container */
        int     ifa_metric;             /* cost of going out this interface */
 #ifdef notdef
        struct  rtentry *ifa_rt;        /* XXXX for ROUTETOIF ????? */