Source-Changes-HG archive

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

[src/netbsd-8]: src/sys Pull up following revision(s) (requested by knahakara...



details:   https://anonhg.NetBSD.org/src/rev/391857c535c2
branches:  netbsd-8
changeset: 434347:391857c535c2
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Oct 24 08:47:24 2017 +0000

description:
Pull up following revision(s) (requested by knahakara in ticket #303):
        sys/net/if_gif.c: 1.129-1.130
        sys/net/if_gif.h: 1.26-1.27
        sys/netinet/in_gif.c: 1.88
        sys/netinet6/in6_gif.c: 1.86
add lock for percpu route like l2tp(4).
--
add lock for sclist to exclude ifconfig gifX add/delete and ifconfig gifX tunnel
--
update locking notes.

diffstat:

 sys/net/if_gif.c       |  62 ++++++++++++++++++++++++++++++++++++++++---------
 sys/net/if_gif.h       |  22 +++++++++++++++--
 sys/netinet/in_gif.c   |  12 +++++++--
 sys/netinet6/in6_gif.c |  12 +++++++--
 4 files changed, 87 insertions(+), 21 deletions(-)

diffs (300 lines):

diff -r f9fabb5a4d46 -r 391857c535c2 sys/net/if_gif.c
--- a/sys/net/if_gif.c  Tue Oct 24 08:38:58 2017 +0000
+++ b/sys/net/if_gif.c  Tue Oct 24 08:47:24 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_gif.c,v 1.126.2.2 2017/08/09 05:51:50 snj Exp $     */
+/*     $NetBSD: if_gif.c,v 1.126.2.3 2017/10/24 08:47:24 snj Exp $     */
 /*     $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $    */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.126.2.2 2017/08/09 05:51:50 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.126.2.3 2017/10/24 08:47:24 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -96,7 +96,14 @@
 /*
  * gif global variable definitions
  */
-static LIST_HEAD(, gif_softc) gif_softc_list;
+LIST_HEAD(gif_sclist, gif_softc);
+static struct {
+       struct gif_sclist list;
+       kmutex_t lock;
+} gif_softcs __cacheline_aligned;
+
+static void    gif_ro_init_pc(void *, void *, struct cpu_info *);
+static void    gif_ro_fini_pc(void *, void *, struct cpu_info *);
 
 static void    gifattach0(struct gif_softc *);
 static int     gif_output(struct ifnet *, struct mbuf *,
@@ -205,7 +212,8 @@
 gifinit(void)
 {
 
-       LIST_INIT(&gif_softc_list);
+       mutex_init(&gif_softcs.lock, MUTEX_DEFAULT, IPL_NONE);
+       LIST_INIT(&gif_softcs.list);
        if_clone_attach(&gif_cloner);
 
        gif_sysctl_setup();
@@ -216,8 +224,11 @@
 {
        int error = 0;
 
-       if (!LIST_EMPTY(&gif_softc_list))
+       mutex_enter(&gif_softcs.lock);
+       if (!LIST_EMPTY(&gif_softcs.list)) {
+               mutex_exit(&gif_softcs.lock);
                error = EBUSY;
+       }
 
        if (error == 0) {
                if_clone_detach(&gif_cloner);
@@ -238,8 +249,12 @@
 
        gifattach0(sc);
 
-       sc->gif_ro_percpu = percpu_alloc(sizeof(struct route));
-       LIST_INSERT_HEAD(&gif_softc_list, sc, gif_list);
+       sc->gif_ro_percpu = percpu_alloc(sizeof(struct gif_ro));
+       percpu_foreach(sc->gif_ro_percpu, gif_ro_init_pc, NULL);
+
+       mutex_enter(&gif_softcs.lock);
+       LIST_INSERT_HEAD(&gif_softcs.list, sc, gif_list);
+       mutex_exit(&gif_softcs.lock);
        return (0);
 }
 
@@ -270,12 +285,30 @@
        bpf_attach(&sc->gif_if, DLT_NULL, sizeof(u_int));
 }
 
+static void
+gif_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
+{
+       struct gif_ro *gro = p;
+
+       mutex_init(&gro->gr_lock, MUTEX_DEFAULT, IPL_NONE);
+}
+
+static void
+gif_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
+{
+       struct gif_ro *gro = p;
+
+       rtcache_free(&gro->gr_ro);
+
+       mutex_destroy(&gro->gr_lock);
+}
+
 void
 gif_rtcache_free_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
 {
-       struct route *ro = p;
+       struct gif_ro *gro = p;
 
-       rtcache_free(ro);
+       rtcache_free(&gro->gr_ro);
 }
 
 static int
@@ -288,8 +321,10 @@
        gif_delete_tunnel(&sc->gif_if);
        bpf_detach(ifp);
        if_detach(ifp);
-       percpu_foreach(sc->gif_ro_percpu, gif_rtcache_free_pc, NULL);
-       percpu_free(sc->gif_ro_percpu, sizeof(struct route));
+
+       percpu_foreach(sc->gif_ro_percpu, gif_ro_fini_pc, NULL);
+       percpu_free(sc->gif_ro_percpu, sizeof(struct gif_ro));
+
        kmem_free(sc, sizeof(struct gif_softc));
 
        return (0);
@@ -969,7 +1004,8 @@
                return error;
        }
 
-       LIST_FOREACH(sc2, &gif_softc_list, gif_list) {
+       mutex_enter(&gif_softcs.lock);
+       LIST_FOREACH(sc2, &gif_softcs.list, gif_list) {
                if (sc2 == sc)
                        continue;
                if (!sc2->gif_pdst || !sc2->gif_psrc)
@@ -978,12 +1014,14 @@
                if (sockaddr_cmp(sc2->gif_pdst, dst) == 0 &&
                    sockaddr_cmp(sc2->gif_psrc, src) == 0) {
                        /* continue to use the old configureation. */
+                       mutex_exit(&gif_softcs.lock);
                        error =  EADDRNOTAVAIL;
                        goto out;
                }
 
                /* XXX both end must be valid? (I mean, not 0.0.0.0) */
        }
+       mutex_exit(&gif_softcs.lock);
 
        nsrc = sockaddr_dup(src, M_WAITOK);
        ndst = sockaddr_dup(dst, M_WAITOK);
diff -r f9fabb5a4d46 -r 391857c535c2 sys/net/if_gif.h
--- a/sys/net/if_gif.h  Tue Oct 24 08:38:58 2017 +0000
+++ b/sys/net/if_gif.h  Tue Oct 24 08:47:24 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_gif.h,v 1.25 2016/12/14 11:19:15 knakahara Exp $    */
+/*     $NetBSD: if_gif.h,v 1.25.8.1 2017/10/24 08:47:24 snj Exp $      */
 /*     $KAME: if_gif.h,v 1.23 2001/07/27 09:21:42 itojun Exp $ */
 
 /*
@@ -49,11 +49,16 @@
 
 struct encaptab;
 
+struct gif_ro {
+       struct route gr_ro;
+       kmutex_t gr_lock;
+};
+
 struct gif_softc {
        struct ifnet    gif_if;    /* common area - must be at the top */
        struct sockaddr *gif_psrc; /* Physical src addr */
        struct sockaddr *gif_pdst; /* Physical dst addr */
-       percpu_t *gif_ro_percpu;
+       percpu_t *gif_ro_percpu;   /* struct gif_ro */
        int             gif_flags;
        const struct encaptab *encap_cookie4;
        const struct encaptab *encap_cookie6;
@@ -76,6 +81,17 @@
 
 /*
  * Locking notes:
- * - All members of struct si_sync are protected by si_lock (an adaptive mutex)
+ * + gif_softc_list is protected by gif_softcs.lock (an adaptive mutex)
+ *       gif_softc_list is list of all gif_softcs. It is used by ioctl
+ *       context only.
+ * + Members of struct gif_softc except for gif_ro_percpu are protected by
+ *   - encap_lock for writer
+ *   - stopping processing when writer begin to run
+ *     for reader(Tx and Rx processing)
+ * + Each CPU's gif_ro.gr_ro of gif_ro_percpu are protected by
+ *   percpu'ed gif_ro.gr_lock.
+ *
+ * Locking order:
+ *     - encap_lock => gif_softcs.lock
  */
 #endif /* !_NET_IF_GIF_H_ */
diff -r f9fabb5a4d46 -r 391857c535c2 sys/netinet/in_gif.c
--- a/sys/netinet/in_gif.c      Tue Oct 24 08:38:58 2017 +0000
+++ b/sys/netinet/in_gif.c      Tue Oct 24 08:47:24 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_gif.c,v 1.87 2017/01/06 03:25:13 knakahara Exp $    */
+/*     $NetBSD: in_gif.c,v 1.87.8.1 2017/10/24 08:47:24 snj Exp $      */
 /*     $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.87 2017/01/06 03:25:13 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.87.8.1 2017/10/24 08:47:24 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -84,6 +84,7 @@
 {
        struct rtentry *rt;
        struct route *ro;
+       struct gif_ro *gro;
        struct gif_softc *sc = ifp->if_softc;
        struct sockaddr_in *sin_src = satosin(sc->gif_psrc);
        struct sockaddr_in *sin_dst = satosin(sc->gif_pdst);
@@ -166,8 +167,11 @@
                return ENOBUFS;
        bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip));
 
-       ro = percpu_getref(sc->gif_ro_percpu);
+       gro = percpu_getref(sc->gif_ro_percpu);
+       mutex_enter(&gro->gr_lock);
+       ro = &gro->gr_ro;
        if ((rt = rtcache_lookup(ro, sc->gif_pdst)) == NULL) {
+               mutex_exit(&gro->gr_lock);
                percpu_putref(sc->gif_ro_percpu);
                m_freem(m);
                return ENETUNREACH;
@@ -177,6 +181,7 @@
        if (rt->rt_ifp == ifp) {
                rtcache_unref(rt, ro);
                rtcache_free(ro);
+               mutex_exit(&gro->gr_lock);
                percpu_putref(sc->gif_ro_percpu);
                m_freem(m);
                return ENETUNREACH;     /*XXX*/
@@ -184,6 +189,7 @@
        rtcache_unref(rt, ro);
 
        error = ip_output(m, NULL, ro, 0, NULL, NULL);
+       mutex_exit(&gro->gr_lock);
        percpu_putref(sc->gif_ro_percpu);
        return (error);
 }
diff -r f9fabb5a4d46 -r 391857c535c2 sys/netinet6/in6_gif.c
--- a/sys/netinet6/in6_gif.c    Tue Oct 24 08:38:58 2017 +0000
+++ b/sys/netinet6/in6_gif.c    Tue Oct 24 08:47:24 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_gif.c,v 1.85 2017/01/16 15:44:47 christos Exp $    */
+/*     $NetBSD: in6_gif.c,v 1.85.6.1 2017/10/24 08:47:24 snj Exp $     */
 /*     $KAME: in6_gif.c,v 1.62 2001/07/29 04:27:25 itojun Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.85 2017/01/16 15:44:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.85.6.1 2017/10/24 08:47:24 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -87,6 +87,7 @@
 {
        struct rtentry *rt;
        struct route *ro;
+       struct gif_ro *gro;
        struct gif_softc *sc = ifp->if_softc;
        struct sockaddr_in6 *sin6_src = satosin6(sc->gif_psrc);
        struct sockaddr_in6 *sin6_dst = satosin6(sc->gif_pdst);
@@ -172,9 +173,12 @@
        ip6->ip6_flow &= ~ntohl(0xff00000);
        ip6->ip6_flow |= htonl((u_int32_t)otos << 20);
 
-       ro = percpu_getref(sc->gif_ro_percpu);
+       gro = percpu_getref(sc->gif_ro_percpu);
+       mutex_enter(&gro->gr_lock);
+       ro = &gro->gr_ro;
        rt = rtcache_lookup(ro, sc->gif_pdst);
        if (rt == NULL) {
+               mutex_exit(&gro->gr_lock);
                percpu_putref(sc->gif_ro_percpu);
                m_freem(m);
                return ENETUNREACH;
@@ -184,6 +188,7 @@
        if (rt->rt_ifp == ifp) {
                rtcache_unref(rt, ro);
                rtcache_free(ro);
+               mutex_exit(&gro->gr_lock);
                percpu_putref(sc->gif_ro_percpu);
                m_freem(m);
                return ENETUNREACH;     /* XXX */
@@ -200,6 +205,7 @@
 #else
        error = ip6_output(m, 0, ro, 0, NULL, NULL, NULL);
 #endif
+       mutex_exit(&gro->gr_lock);
        percpu_putref(sc->gif_ro_percpu);
        return (error);
 }



Home | Main Index | Thread Index | Old Index