Source-Changes-HG archive

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

[src/trunk]: src/sys Apply pserialize and psref to struct ifaddr and its vari...



details:   https://anonhg.NetBSD.org/src/rev/6afb643f2352
branches:  trunk
changeset: 346755:6afb643f2352
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon Aug 01 03:15:30 2016 +0000

description:
Apply pserialize and psref to struct ifaddr and its variants

This change makes struct ifaddr and its variants (in_ifaddr and in6_ifaddr)
MP-safe by using pserialize and psref. At this moment, pserialize_perform
and psref_target_destroy are disabled because (1) we don't need them
because of softnet_lock (2) they cause a deadlock because of softnet_lock.
So we'll enable them when we remove softnet_lock in the future.

diffstat:

 sys/arch/x86/x86/vmt.c                     |    7 +-
 sys/compat/common/uipc_syscalls_40.c       |   21 +-
 sys/compat/linux/common/linux_socket.c     |   23 +-
 sys/compat/linux32/common/linux32_socket.c |   23 +-
 sys/net/if.c                               |  244 ++++++++++++++++++++++++----
 sys/net/if.h                               |   19 +-
 sys/net/if_ethersubr.c                     |   34 ++-
 sys/net/if_fddisubr.c                      |   30 ++-
 sys/net/if_stf.c                           |   12 +-
 sys/net/if_tokensubr.c                     |   18 +-
 sys/net/route.c                            |  201 ++++++++++++++++-------
 sys/net/route.h                            |    7 +-
 sys/net/rtsock.c                           |   68 +++++--
 sys/netatalk/aarp.c                        |   58 ++++-
 sys/netatalk/at_control.c                  |    5 +-
 sys/netinet/if_arp.c                       |   49 ++++-
 sys/netinet/igmp.c                         |   27 ++-
 sys/netinet/in.c                           |  252 +++++++++++++++++++++++-----
 sys/netinet/in.h                           |    8 +-
 sys/netinet/in_gif.c                       |   11 +-
 sys/netinet/in_pcb.c                       |   62 +++++-
 sys/netinet/in_var.h                       |   68 +++++++-
 sys/netinet/ip_carp.c                      |   25 ++-
 sys/netinet/ip_icmp.c                      |   58 +++++-
 sys/netinet/ip_input.c                     |  108 ++++++++---
 sys/netinet/ip_mroute.c                    |   16 +-
 sys/netinet/ip_output.c                    |   54 ++++-
 sys/netinet/raw_ip.c                       |   16 +-
 sys/netinet6/icmp6.c                       |   65 +++++--
 sys/netinet6/in6.c                         |  244 +++++++++++++++++++++------
 sys/netinet6/in6_ifattach.c                |   33 ++-
 sys/netinet6/in6_pcb.c                     |   68 ++++--
 sys/netinet6/in6_src.c                     |   43 +++-
 sys/netinet6/in6_var.h                     |   62 ++++++-
 sys/netinet6/ip6_input.c                   |    9 +-
 sys/netinet6/ip6_output.c                  |   12 +-
 sys/netinet6/mld6.c                        |   60 +++++-
 sys/netinet6/nd6.c                         |   96 ++++++++--
 sys/netinet6/nd6_nbr.c                     |   42 +++-
 sys/netinet6/nd6_rtr.c                     |   92 +++++++++-
 sys/netinet6/raw_ip6.c                     |   28 ++-
 sys/netinet6/sctp6_usrreq.c                |    5 +-
 sys/netinet6/udp6_output.c                 |   26 ++-
 43 files changed, 1846 insertions(+), 563 deletions(-)

diffs (truncated from 6621 to 300 lines):

diff -r e4f26b1931a3 -r 6afb643f2352 sys/arch/x86/x86/vmt.c
--- a/sys/arch/x86/x86/vmt.c    Mon Aug 01 02:50:03 2016 +0000
+++ b/sys/arch/x86/x86/vmt.c    Mon Aug 01 03:15:30 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vmt.c,v 1.13 2016/07/07 09:32:01 ozaki-r Exp $ */
+/* $NetBSD: vmt.c,v 1.14 2016/08/01 03:15:30 ozaki-r Exp $ */
 /* $OpenBSD: vmt.c,v 1.11 2011/01/27 21:29:25 dtucker Exp $ */
 
 /*
@@ -801,15 +801,16 @@
                        sc->sc_rpc_error = 1;
                }
        } else if (strcmp(sc->sc_rpc_buf, "Set_Option broadcastIP 1") == 0) {
+               struct ifaddr *iface_addr = NULL;
                struct ifnet *iface;
                struct sockaddr_in *guest_ip;
                int s;
+               struct psref psref;
 
                /* find first available ipv4 address */
                guest_ip = NULL;
                s = pserialize_read_enter();
                IFNET_READER_FOREACH(iface) {
-                       struct ifaddr *iface_addr;
 
                        /* skip loopback */
                        if (strncmp(iface->if_xname, "lo", 2) == 0 &&
@@ -823,6 +824,7 @@
                                }
 
                                guest_ip = satosin(iface_addr->ifa_addr);
+                               ifa_acquire(iface_addr, &psref);
                                break;
                        }
                }
@@ -834,6 +836,7 @@
                                device_printf(sc->sc_dev, "unable to send guest IP address\n");
                                sc->sc_rpc_error = 1;
                        }
+                       ifa_release(iface_addr, &psref);
 
                        if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
                                device_printf(sc->sc_dev, "error sending broadcastIP response\n");
diff -r e4f26b1931a3 -r 6afb643f2352 sys/compat/common/uipc_syscalls_40.c
--- a/sys/compat/common/uipc_syscalls_40.c      Mon Aug 01 02:50:03 2016 +0000
+++ b/sys/compat/common/uipc_syscalls_40.c      Mon Aug 01 03:15:30 2016 +0000
@@ -1,9 +1,9 @@
-/*     $NetBSD: uipc_syscalls_40.c,v 1.11 2016/07/07 09:32:02 ozaki-r Exp $    */
+/*     $NetBSD: uipc_syscalls_40.c,v 1.12 2016/08/01 03:15:30 ozaki-r Exp $    */
 
 /* written by Pavel Cahyna, 2006. Public domain. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_40.c,v 1.11 2016/07/07 09:32:02 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_40.c,v 1.12 2016/08/01 03:15:30 ozaki-r Exp $");
 
 /*
  * System call interface to the socket abstraction.
@@ -34,7 +34,6 @@
 {
        struct oifconf *ifc = data;
        struct ifnet *ifp;
-       struct ifaddr *ifa;
        struct oifreq ifr, *ifrp = NULL;
        int space = 0, error = 0;
        const int sz = (int)sizeof(ifr);
@@ -51,8 +50,9 @@
        bound = curlwp_bind();
        s = pserialize_read_enter();
        IFNET_READER_FOREACH(ifp) {
+               struct ifaddr *ifa;
+
                psref_acquire(&psref, &ifp->if_psref, ifnet_psref_class);
-               pserialize_read_exit(s);
 
                (void)strncpy(ifr.ifr_name, ifp->if_xname,
                    sizeof(ifr.ifr_name));
@@ -74,6 +74,10 @@
 
                IFADDR_READER_FOREACH(ifa, ifp) {
                        struct sockaddr *sa = ifa->ifa_addr;
+                       struct psref psref_ifa;
+
+                       ifa_acquire(ifa, &psref_ifa);
+                       pserialize_read_exit(s);
 #ifdef COMPAT_OSOCK
                        if (cmd == OOSIOCGIFCONF) {
                                struct osockaddr *osa =
@@ -81,8 +85,11 @@
                                /*
                                 * If it does not fit, we don't bother with it
                                 */
-                               if (sa->sa_len > sizeof(*osa))
+                               if (sa->sa_len > sizeof(*osa)) {
+                                       s = pserialize_read_enter();
+                                       ifa_release(ifa, &psref_ifa);
                                        continue;
+                               }
                                memcpy(&ifr.ifr_addr, sa, sa->sa_len);
                                osa->sa_family = sa->sa_family;
                                if (space >= sz) {
@@ -112,12 +119,13 @@
                                                 (char *)&ifrp->ifr_addr);
                                }
                        }
+                       s = pserialize_read_enter();
+                       ifa_release(ifa, &psref_ifa);
                        if (error != 0)
                                goto release_exit;
                        space -= sz;
                }
 
-               s = pserialize_read_enter();
                psref_release(&psref, &ifp->if_psref, ifnet_psref_class);
        }
        pserialize_read_exit(s);
@@ -130,6 +138,7 @@
        return (0);
 
 release_exit:
+       pserialize_read_exit(s);
        psref_release(&psref, &ifp->if_psref, ifnet_psref_class);
        curlwp_bindx(bound);
        return error;
diff -r e4f26b1931a3 -r 6afb643f2352 sys/compat/linux/common/linux_socket.c
--- a/sys/compat/linux/common/linux_socket.c    Mon Aug 01 02:50:03 2016 +0000
+++ b/sys/compat/linux/common/linux_socket.c    Mon Aug 01 03:15:30 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_socket.c,v 1.131 2016/07/07 09:32:02 ozaki-r Exp $       */
+/*     $NetBSD: linux_socket.c,v 1.132 2016/08/01 03:15:30 ozaki-r Exp $       */
 
 /*-
  * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.131 2016/07/07 09:32:02 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.132 2016/08/01 03:15:30 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -1117,7 +1117,6 @@
        struct linux_ifreq ifr, *ifrp = NULL;
        struct linux_ifconf ifc;
        struct ifnet *ifp;
-       struct ifaddr *ifa;
        struct sockaddr *sa;
        struct osockaddr *osa;
        int space = 0, error;
@@ -1140,8 +1139,8 @@
        bound = curlwp_bind();
        s = pserialize_read_enter();
        IFNET_READER_FOREACH(ifp) {
+               struct ifaddr *ifa;
                psref_acquire(&psref, &ifp->if_psref, ifnet_psref_class);
-               pserialize_read_exit(s);
 
                (void)strncpy(ifr.ifr_name, ifp->if_xname,
                    sizeof(ifr.ifr_name));
@@ -1151,23 +1150,32 @@
                }
 
                IFADDR_READER_FOREACH(ifa, ifp) {
+                       struct psref psref_ifa;
+                       ifa_acquire(ifa, &psref_ifa);
+                       pserialize_read_exit(s);
+
                        sa = ifa->ifa_addr;
                        if (sa->sa_family != AF_INET ||
                            sa->sa_len > sizeof(*osa))
-                               continue;
+                               goto next;
                        memcpy(&ifr.ifr_addr, sa, sa->sa_len);
                        osa = (struct osockaddr *)&ifr.ifr_addr;
                        osa->sa_family = sa->sa_family;
                        if (space >= sz) {
                                error = copyout(&ifr, ifrp, sz);
-                               if (error != 0)
+                               if (error != 0) {
+                                       s = pserialize_read_enter();
+                                       ifa_release(ifa, &psref_ifa);
                                        goto release_exit;
+                               }
                                ifrp++;
                        }
                        space -= sz;
+               next:
+                       s = pserialize_read_enter();
+                       ifa_release(ifa, &psref_ifa);
                }
 
-               s = pserialize_read_enter();
                psref_release(&psref, &ifp->if_psref, ifnet_psref_class);
        }
        pserialize_read_exit(s);
@@ -1181,6 +1189,7 @@
        return copyout(&ifc, data, sizeof(ifc));
 
 release_exit:
+       pserialize_read_exit(s);
        psref_release(&psref, &ifp->if_psref, ifnet_psref_class);
        curlwp_bindx(bound);
        return error;
diff -r e4f26b1931a3 -r 6afb643f2352 sys/compat/linux32/common/linux32_socket.c
--- a/sys/compat/linux32/common/linux32_socket.c        Mon Aug 01 02:50:03 2016 +0000
+++ b/sys/compat/linux32/common/linux32_socket.c        Mon Aug 01 03:15:30 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux32_socket.c,v 1.25 2016/07/07 09:32:02 ozaki-r Exp $ */
+/*     $NetBSD: linux32_socket.c,v 1.26 2016/08/01 03:15:30 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: linux32_socket.c,v 1.25 2016/07/07 09:32:02 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_socket.c,v 1.26 2016/08/01 03:15:30 ozaki-r Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -418,7 +418,6 @@
        struct linux32_ifreq ifr, *ifrp = NULL;
        struct linux32_ifconf ifc;
        struct ifnet *ifp;
-       struct ifaddr *ifa;
        struct sockaddr *sa;
        struct osockaddr *osa;
        int space = 0, error;
@@ -441,8 +440,8 @@
        bound = curlwp_bind();
        s = pserialize_read_enter();
        IFNET_READER_FOREACH(ifp) {
+               struct ifaddr *ifa;
                psref_acquire(&psref, &ifp->if_psref, ifnet_psref_class);
-               pserialize_read_exit(s);
 
                (void)strncpy(ifr.ifr_name, ifp->if_xname,
                    sizeof(ifr.ifr_name));
@@ -452,23 +451,32 @@
                }
 
                IFADDR_READER_FOREACH(ifa, ifp) {
+                       struct psref psref_ifa;
+                       ifa_acquire(ifa, &psref_ifa);
+                       pserialize_read_exit(s);
+
                        sa = ifa->ifa_addr;
                        if (sa->sa_family != AF_INET ||
                            sa->sa_len > sizeof(*osa))
-                               continue;
+                               goto next;
                        memcpy(&ifr.ifr_addr, sa, sa->sa_len);
                        osa = (struct osockaddr *)&ifr.ifr_addr;
                        osa->sa_family = sa->sa_family;
                        if (space >= sz) {
                                error = copyout(&ifr, ifrp, sz);
-                               if (error != 0)
+                               if (error != 0) {
+                                       s = pserialize_read_enter();
+                                       ifa_release(ifa, &psref_ifa);
                                        goto release_exit;
+                               }
                                ifrp++;
                        }
                        space -= sz;
+               next:
+                       s = pserialize_read_enter();
+                       ifa_release(ifa, &psref_ifa);
                }
 
-               s = pserialize_read_enter();
                psref_release(&psref, &ifp->if_psref, ifnet_psref_class);
        }
        pserialize_read_exit(s);
@@ -482,6 +490,7 @@
        return copyout(&ifc, data, sizeof(ifc));
 
 release_exit:
+       pserialize_read_exit(s);
        psref_release(&psref, &ifp->if_psref, ifnet_psref_class);
        curlwp_bindx(bound);
        return error;
diff -r e4f26b1931a3 -r 6afb643f2352 sys/net/if.c
--- a/sys/net/if.c      Mon Aug 01 02:50:03 2016 +0000
+++ b/sys/net/if.c      Mon Aug 01 03:15:30 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.356 2016/07/22 07:13:56 knakahara Exp $       */
+/*     $NetBSD: if.c,v 1.357 2016/08/01 03:15:30 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.356 2016/07/22 07:13:56 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.357 2016/08/01 03:15:30 ozaki-r Exp $");
 



Home | Main Index | Thread Index | Old Index