Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet6 backout the changes that establish a workqueue ...



details:   https://anonhg.NetBSD.org/src/rev/ad3cc7926ade
branches:  trunk
changeset: 747533:ad3cc7926ade
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Sep 19 13:11:02 2009 +0000

description:
backout the changes that establish a workqueue to synchronize the addresses
for arg and gre because they cause a race condition by calling ioctl() during
interface initialization. To make this work correctly we would need to
synchronize all interface init routines.

diffstat:

 sys/netinet6/in6.c          |    8 +-
 sys/netinet6/in6_ifattach.c |  145 +------------------------------------------
 sys/netinet6/in6_ifattach.h |    3 +-
 3 files changed, 7 insertions(+), 149 deletions(-)

diffs (255 lines):

diff -r 3e7cb60da7ba -r ad3cc7926ade sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Sat Sep 19 11:53:42 2009 +0000
+++ b/sys/netinet6/in6.c        Sat Sep 19 13:11:02 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.153 2009/09/11 22:06:29 dyoung Exp $ */
+/*     $NetBSD: in6.c,v 1.154 2009/09/19 13:11:02 christos Exp $       */
 /*     $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $   */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.153 2009/09/11 22:06:29 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.154 2009/09/19 13:11:02 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_pfil_hooks.h"
@@ -76,7 +76,6 @@
 #include <sys/socketvar.h>
 #include <sys/sockio.h>
 #include <sys/systm.h>
-#include <sys/once.h>
 #include <sys/proc.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
@@ -2239,11 +2238,8 @@
 void *
 in6_domifattach(struct ifnet *ifp)
 {
-       static ONCE_DECL(ifwqest);
        struct in6_ifextra *ext;
 
-       RUN_ONCE(&ifwqest, in6_ifaddrs_wq_establish);
-
        ext = malloc(sizeof(*ext), M_IFADDR, M_WAITOK|M_ZERO);
 
        ext->in6_ifstat = malloc(sizeof(struct in6_ifstat),
diff -r 3e7cb60da7ba -r ad3cc7926ade sys/netinet6/in6_ifattach.c
--- a/sys/netinet6/in6_ifattach.c       Sat Sep 19 11:53:42 2009 +0000
+++ b/sys/netinet6/in6_ifattach.c       Sat Sep 19 13:11:02 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_ifattach.c,v 1.84 2009/08/13 09:04:03 cegger Exp $ */
+/*     $NetBSD: in6_ifattach.c,v 1.85 2009/09/19 13:11:02 christos Exp $       */
 /*     $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $  */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.84 2009/08/13 09:04:03 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.85 2009/09/19 13:11:02 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -43,7 +43,6 @@
 #include <sys/syslog.h>
 #include <sys/md5.h>
 #include <sys/socketvar.h>
-#include <sys/workqueue.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -62,41 +61,12 @@
 
 #include <net/net_osdep.h>
 
-/* Record of an interface to add a link-local and possibly a loopback
- * IPv6 address to, processed on a workqueue(9) by in6_ifaddrs_worker.
- */
-struct in6_ifaddr_work {
-       struct work     iw_work;
-       struct ifindexgen {
-               int     ig_idx;         /* Interface index */
-               int     ig_gen;         /* Interface index generation */
-       }               iw_idxgen,      /* Identify of the interface
-                                        * to receive a link-local and
-                                        * possibly a loopback address.
-                                        */
-                       iw_alt_idxgen;  /* Optional identity of a second
-                                        * interface. If iw_alt_present
-                                        * is true, this field
-                                        * identifies a second interface
-                                        * whose EUI64 we use to derive
-                                        * the link-local address for
-                                        * the interface indicated by
-                                        * iw_idxgen.
-                                        */
-       bool            iw_alt_present; /* iff true, iw_alt_idxgen is valid. */ 
-};
-
 unsigned long in6_maxmtu = 0;
 
 int ip6_auto_linklocal = 1;    /* enable by default */
 
 callout_t in6_tmpaddrtimer_ch;
 
-static struct workqueue *in6_ifaddrs_wq = NULL;
-
-static void in6_ifaddrs_schedule(struct ifnet *, struct ifnet *);
-static void in6_ifaddrs_init(struct ifnet *, struct ifnet *);
-static void in6_ifaddrs_worker(struct work *, void *);
 
 #if 0
 static int get_hostid_ifid(struct ifnet *, struct in6_addr *);
@@ -782,6 +752,8 @@
 void
 in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
 {
+       struct in6_ifaddr *ia;
+       struct in6_addr in6;
 
        /* some of the interfaces are inherently not IPv6 capable */
        switch (ifp->if_type) {
@@ -840,26 +812,6 @@
                return;
        }
 
-       /* Assign addresses to ifp in another thread in order to
-        * avoid re-entering ifp->if_ioctl().
-        */
-       in6_ifaddrs_schedule(ifp, altifp);
-}
-
-/* in6_ifaddrs_init
- *
- * Add a link-local address to ifp, and if ifp is a loopback address,
- * add a loopback address to it, too.
- *
- * If altifp is not NULL, derive the link-local address of ifp from the
- * EUI64 of altifp.
- */
-void
-in6_ifaddrs_init(struct ifnet *ifp, struct ifnet *altifp)
-{
-       struct in6_addr in6;
-       struct in6_ifaddr *ia;
-
        /*
         * assign loopback address for loopback interface.
         * XXX multiple loopback interface case.
@@ -884,95 +836,6 @@
        }
 }
 
-/* getifp: helper for in6_ifaddrs_worker().
- *
- * Lookup an ifnet by ifindexgen, a pair consisting of an interface
- * index (if_index) and an interface-index generation number.
- */
-static struct ifnet *
-getifp(struct ifindexgen *ig)
-{
-       int ifindex = ig->ig_idx;
-       uint64_t ifindex_gen = ig->ig_gen;
-       struct ifnet *ifp;
-
-       if (ifindex2ifnet == NULL)
-               printf("%s: no ifindices in use\n", __func__);
-       else if (ifindex >= if_indexlim) {
-               printf("%s: ifindex %d >= limit %zu\n", __func__, ifindex,
-                   if_indexlim);
-       } else if ((ifp = ifindex2ifnet[ifindex]) == NULL)
-               printf("%s: ifindex %d not in use\n", __func__, ifindex);
-       else if (ifp->if_index_gen != ifindex_gen)
-               printf("%s: ifindex %d recycled\n", __func__, ifindex);
-       else
-               return ifp;
-       return NULL;
-}
-
-static void
-in6_ifaddrs_worker(struct work *wk, void *arg)
-{
-       struct in6_ifaddr_work *iw = (struct in6_ifaddr_work *)wk;
-       struct ifnet *altifp = NULL, *ifp;
-
-       if ((ifp = getifp(&iw->iw_idxgen)) != NULL &&
-           (!iw->iw_alt_present ||
-            (altifp = getifp(&iw->iw_alt_idxgen)) != NULL))
-               in6_ifaddrs_init(ifp, altifp);
-
-       kmem_free(iw, sizeof(*iw));
-}
-
-int
-in6_ifaddrs_wq_establish(void)
-{
-       int rc;
-
-       rc = workqueue_create(&in6_ifaddrs_wq, "in6ifaddr", in6_ifaddrs_worker,
-           NULL, PRI_KERNEL, IPL_NET, 0);
-
-       if (rc != 0) {
-               printf("%s: could not create inet6 ifaddrs workqueue.\n",
-                   __func__);
-       }
-       return rc;
-}
-
-/* in6_ifaddrs_schedule
- *
- * Schedule ifp for a kernel thread to add addresses.
- *
- * The kernel thread will assign a link-local address to ifp, and if ifp
- * is a loopback address, add a loopback address to it, too.
- *
- * If altifp is not NULL, derive the link-local address of ifp from the
- * EUI64 of altifp.
- */
-void
-in6_ifaddrs_schedule(struct ifnet *ifp, struct ifnet *altifp)
-{
-       struct in6_ifaddr_work *iw;
-       struct ifindexgen *ig, *alt_ig;
-
-       iw = kmem_zalloc(sizeof(*iw), KM_SLEEP);
-
-       ig = &iw->iw_idxgen;
-       alt_ig = &iw->iw_alt_idxgen;
-
-       KASSERT(ifp->if_index < if_indexlim);
-       ig->ig_idx = ifp->if_index;
-       ig->ig_gen = ifp->if_index_gen;
-       if (altifp != NULL) {
-               KASSERT(altifp->if_index < if_indexlim);
-               alt_ig->ig_idx = altifp->if_index;
-               alt_ig->ig_gen = altifp->if_index_gen;
-               iw->iw_alt_present = true;
-       }
-
-       workqueue_enqueue(in6_ifaddrs_wq, &iw->iw_work, NULL);
-}
-
 /*
  * NOTE: in6_ifdetach() does not support loopback if at this moment.
  * We don't need this function in bsdi, because interfaces are never removed
diff -r 3e7cb60da7ba -r ad3cc7926ade sys/netinet6/in6_ifattach.h
--- a/sys/netinet6/in6_ifattach.h       Sat Sep 19 11:53:42 2009 +0000
+++ b/sys/netinet6/in6_ifattach.h       Sat Sep 19 13:11:02 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_ifattach.h,v 1.12 2009/08/13 00:34:05 dyoung Exp $ */
+/*     $NetBSD: in6_ifattach.h,v 1.13 2009/09/19 13:11:02 christos Exp $       */
 /*     $KAME: in6_ifattach.h,v 1.8 2000/04/12 03:51:30 itojun Exp $    */
 
 /*
@@ -40,7 +40,6 @@
 void in6_tmpaddrtimer(void *);
 int in6_get_hw_ifid(struct ifnet *, struct in6_addr *);
 int in6_nigroup(struct ifnet *, const char *, int, struct sockaddr_in6 *);
-int in6_ifaddrs_wq_establish(void);
 #endif /* _KERNEL */
 
 #endif /* !_NETINET6_IN6_IFATTACH_H_ */



Home | Main Index | Thread Index | Old Index