Module Name:    src
Committed By:   ozaki-r
Date:           Tue Oct 18 07:30:31 UTC 2016

Modified Files:
        src/sys/net: if.c if_ethersubr.c route.c
        src/sys/netinet: if_arp.c in.c ip_flow.c ip_input.c
        src/sys/netinet6: in6.c ip6_flow.c ip6_input.c nd6.c nd6_nbr.c

Log Message:
Don't hold global locks if NET_MPSAFE is enabled

If NET_MPSAFE is enabled, don't hold KERNEL_LOCK and softnet_lock in
part of the network stack such as IP forwarding paths. The aim of the
change is to make it easy to test the network stack without the locks
and reduce our local diffs.

By default (i.e., if NET_MPSAFE isn't enabled), the locks are held
as they used to be.

Reviewed by knakahara@


To generate a diff of this commit:
cvs rdiff -u -r1.358 -r1.359 src/sys/net/if.c
cvs rdiff -u -r1.228 -r1.229 src/sys/net/if_ethersubr.c
cvs rdiff -u -r1.174 -r1.175 src/sys/net/route.c
cvs rdiff -u -r1.230 -r1.231 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.186 -r1.187 src/sys/netinet/in.c
cvs rdiff -u -r1.76 -r1.77 src/sys/netinet/ip_flow.c
cvs rdiff -u -r1.343 -r1.344 src/sys/netinet/ip_input.c
cvs rdiff -u -r1.220 -r1.221 src/sys/netinet6/in6.c
cvs rdiff -u -r1.31 -r1.32 src/sys/netinet6/ip6_flow.c
cvs rdiff -u -r1.168 -r1.169 src/sys/netinet6/ip6_input.c
cvs rdiff -u -r1.208 -r1.209 src/sys/netinet6/nd6.c
cvs rdiff -u -r1.127 -r1.128 src/sys/netinet6/nd6_nbr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.358 src/sys/net/if.c:1.359
--- src/sys/net/if.c:1.358	Mon Oct  3 11:06:06 2016
+++ src/sys/net/if.c	Tue Oct 18 07:30:30 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.358 2016/10/03 11:06:06 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.359 2016/10/18 07:30: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.358 2016/10/03 11:06:06 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.359 2016/10/18 07:30:30 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -1622,12 +1622,12 @@ ifa_remove(struct ifnet *ifp, struct ifa
 	TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
 	IFADDR_WRITER_REMOVE(ifa);
 	IFADDR_ENTRY_DESTROY(ifa);
-#if notyet
+#ifdef NET_MPSAFE
 	pserialize_perform(ifnet_psz);
 #endif
 	IFNET_UNLOCK();
 
-#if notyet
+#ifdef NET_MPSAFE
 	psref_target_destroy(&ifa->ifa_psref, ifa_psref_class);
 #endif
 	ifafree(ifa);

Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.228 src/sys/net/if_ethersubr.c:1.229
--- src/sys/net/if_ethersubr.c:1.228	Mon Oct  3 11:06:06 2016
+++ src/sys/net/if_ethersubr.c	Tue Oct 18 07:30:30 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ethersubr.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $	*/
+/*	$NetBSD: if_ethersubr.c,v 1.229 2016/10/18 07:30:30 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.229 2016/10/18 07:30:30 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -246,17 +246,23 @@ ether_output(struct ifnet * const ifp0, 
 
 #ifdef INET
 	case AF_INET:
+#ifndef NET_MPSAFE
 		KERNEL_LOCK(1, NULL);
+#endif
 		if (m->m_flags & M_BCAST)
 			(void)memcpy(edst, etherbroadcastaddr, sizeof(edst));
 		else if (m->m_flags & M_MCAST)
 			ETHER_MAP_IP_MULTICAST(&satocsin(dst)->sin_addr, edst);
 		else if ((error = arpresolve(ifp, rt, m, dst, edst,
 		    sizeof(edst))) != 0) {
+#ifndef NET_MPSAFE
 			KERNEL_UNLOCK_ONE(NULL);
+#endif
 			return error == EWOULDBLOCK ? 0 : error;
 		}
+#ifndef NET_MPSAFE
 		KERNEL_UNLOCK_ONE(NULL);
+#endif
 		/* If broadcasting on a simplex interface, loopback a copy */
 		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
 			mcopy = m_copy(m, 0, (int)M_COPYALL);
@@ -884,7 +890,11 @@ ether_input(struct ifnet *ifp, struct mb
 	}
 
 	if (__predict_true(pktq)) {
+#ifdef NET_MPSAFE
+		const u_int h = curcpu()->ci_index;
+#else
 		const uint32_t h = pktq_rps_hash(m);
+#endif
 		if (__predict_false(!pktq_enqueue(pktq, m, h))) {
 			m_freem(m);
 		}

Index: src/sys/net/route.c
diff -u src/sys/net/route.c:1.174 src/sys/net/route.c:1.175
--- src/sys/net/route.c:1.174	Fri Aug  5 00:52:02 2016
+++ src/sys/net/route.c	Tue Oct 18 07:30:30 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: route.c,v 1.174 2016/08/05 00:52:02 ozaki-r Exp $	*/
+/*	$NetBSD: route.c,v 1.175 2016/10/18 07:30:30 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -93,10 +93,11 @@
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
 #include "opt_route.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.174 2016/08/05 00:52:02 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.175 2016/10/18 07:30:30 ozaki-r Exp $");
 
 #include <sys/param.h>
 #ifdef RTFLUSH_DEBUG
@@ -431,7 +432,7 @@ miss:
 	return NULL;
 }
 
-#ifdef DEBUG
+#if defined(DEBUG) && !defined(NET_MPSAFE)
 /*
  * Check the following constraint for each rtcache:
  *   if a rtcache holds a rtentry, the rtentry's refcnt is more than zero,
@@ -460,7 +461,7 @@ rtfree(struct rtentry *rt)
 	KASSERT(rt->rt_refcnt > 0);
 
 	rt->rt_refcnt--;
-#ifdef DEBUG
+#if defined(DEBUG) && !defined(NET_MPSAFE)
 	if (rt_getkey(rt) != NULL)
 		rtcache_check_rtrefcnt(rt_getkey(rt)->sa_family);
 #endif

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.230 src/sys/netinet/if_arp.c:1.231
--- src/sys/netinet/if_arp.c:1.230	Tue Oct 11 13:59:30 2016
+++ src/sys/netinet/if_arp.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.230 2016/10/11 13:59:30 roy Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.231 2016/10/18 07:30:31 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,11 +68,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.230 2016/10/11 13:59:30 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.231 2016/10/18 07:30:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
 #include "opt_inet.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #ifdef INET
@@ -918,8 +919,10 @@ arpintr(void)
 	int s;
 	int arplen;
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
 	for (;;) {
 		struct ifnet *rcvif;
 
@@ -971,8 +974,12 @@ badlen:
 		m_freem(m);
 	}
 out:
+#ifndef NET_MPSAFE
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#else
+	return; /* XXX gcc */
+#endif
 }
 
 /*
@@ -1532,7 +1539,11 @@ static void
 arp_dad_stoptimer(struct dadq *dp)
 {
 
+#ifdef NET_MPSAFE
+	callout_halt(&dp->dad_timer_ch, NULL);
+#else
 	callout_halt(&dp->dad_timer_ch, softnet_lock);
+#endif
 }
 
 static void

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.186 src/sys/netinet/in.c:1.187
--- src/sys/netinet/in.c:1.186	Sat Oct  1 17:17:20 2016
+++ src/sys/netinet/in.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.186 2016/10/01 17:17:20 roy Exp $	*/
+/*	$NetBSD: in.c,v 1.187 2016/10/18 07:30:31 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.186 2016/10/01 17:17:20 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.187 2016/10/18 07:30:31 ozaki-r Exp $");
 
 #include "arp.h"
 
@@ -99,6 +99,7 @@ __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.186
 #include "opt_inet.h"
 #include "opt_inet_conf.h"
 #include "opt_mrouting.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include <sys/param.h>
@@ -734,9 +735,13 @@ in_control(struct socket *so, u_long cmd
 {
 	int error;
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
+#endif
 	error = in_control0(so, cmd, data, ifp);
+#ifndef NET_MPSAFE
 	mutex_exit(softnet_lock);
+#endif
 
 	return error;
 }

Index: src/sys/netinet/ip_flow.c
diff -u src/sys/netinet/ip_flow.c:1.76 src/sys/netinet/ip_flow.c:1.77
--- src/sys/netinet/ip_flow.c:1.76	Mon Aug  1 10:22:53 2016
+++ src/sys/netinet/ip_flow.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_flow.c,v 1.76 2016/08/01 10:22:53 knakahara Exp $	*/
+/*	$NetBSD: ip_flow.c,v 1.77 2016/10/18 07:30:31 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -30,7 +30,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.76 2016/08/01 10:22:53 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.77 2016/10/18 07:30:31 ozaki-r Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_net_mpsafe.h"
+#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -471,9 +475,11 @@ ipflow_slowtimo_work(struct work *wk, vo
 	/* We can allow enqueuing another work at this point */
 	atomic_swap_uint(&ipflow_work_enqueued, 0);
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
-	mutex_enter(&ipflow_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
+	mutex_enter(&ipflow_lock);
 	for (ipf = TAILQ_FIRST(&ipflowlist); ipf != NULL; ipf = next_ipf) {
 		next_ipf = TAILQ_NEXT(ipf, ipf_list);
 		if (PRT_SLOW_ISEXPIRED(ipf->ipf_timer) ||
@@ -490,9 +496,11 @@ ipflow_slowtimo_work(struct work *wk, vo
 			ipf->ipf_uses = 0;
 		}
 	}
-	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(&ipflow_lock);
+#ifndef NET_MPSAFE
+	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 }
 
 void
@@ -513,17 +521,16 @@ ipflow_create(const struct route *ro, st
 	struct ipflow *ipf;
 	size_t hash;
 
+#ifndef NET_MPSAFE
+	KERNEL_LOCK(1, NULL);
+#endif
 	mutex_enter(&ipflow_lock);
 
 	/*
 	 * Don't create cache entries for ICMP messages.
 	 */
-	if (ip_maxflows == 0 || ip->ip_p == IPPROTO_ICMP) {
-		mutex_exit(&ipflow_lock);
-		return;
-	}
-
-	KERNEL_LOCK(1, NULL);
+	if (ip_maxflows == 0 || ip->ip_p == IPPROTO_ICMP)
+		goto out;
 
 	/*
 	 * See if an existing flow struct exists.  If so remove it from its
@@ -566,8 +573,10 @@ ipflow_create(const struct route *ro, st
 	IPFLOW_INSERT(hash, ipf);
 
  out:
-	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(&ipflow_lock);
+#ifndef NET_MPSAFE
+	KERNEL_UNLOCK_ONE(NULL);
+#endif
 }
 
 int
@@ -605,15 +614,19 @@ sysctl_net_inet_ip_maxflows(SYSCTLFN_ARG
 	if (error || newp == NULL)
 		return (error);
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
-	mutex_enter(&ipflow_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
+	mutex_enter(&ipflow_lock);
 
 	ipflow_reap(false);
 
-	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(&ipflow_lock);
+#ifndef NET_MPSAFE
+	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 
 	return (0);
 }
@@ -635,14 +648,15 @@ sysctl_net_inet_ip_hashsize(SYSCTLFN_ARG
 		/*
 		 * Can only fail due to malloc()
 		 */
+#ifndef NET_MPSAFE
 		mutex_enter(softnet_lock);
 		KERNEL_LOCK(1, NULL);
-
+#endif
 		error = ipflow_invalidate_all(tmp);
-
+#ifndef NET_MPSAFE
 		KERNEL_UNLOCK_ONE(NULL);
 		mutex_exit(softnet_lock);
-
+#endif
 	} else {
 		/*
 		 * EINVAL if not a power of 2

Index: src/sys/netinet/ip_input.c
diff -u src/sys/netinet/ip_input.c:1.343 src/sys/netinet/ip_input.c:1.344
--- src/sys/netinet/ip_input.c:1.343	Tue Oct 18 01:15:20 2016
+++ src/sys/netinet/ip_input.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.343 2016/10/18 01:15:20 ozaki-r Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.344 2016/10/18 07:30:31 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.343 2016/10/18 01:15:20 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.344 2016/10/18 07:30:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -101,6 +101,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v
 #include "opt_mrouting.h"
 #include "opt_mbuftrace.h"
 #include "opt_inet_csum.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include "arp.h"
@@ -294,9 +295,13 @@ static struct in_ifaddr	*ip_match_our_ad
 static struct in_ifaddr	*ip_match_our_address_broadcast(struct ifnet *,
 			    struct ip *);
 
-/* XXX: Not yet enabled. */
+#ifdef NET_MPSAFE
+#define	SOFTNET_LOCK()		mutex_enter(softnet_lock)
+#define	SOFTNET_UNLOCK()	mutex_exit(softnet_lock)
+#else
 #define	SOFTNET_LOCK()		KASSERT(mutex_owned(softnet_lock))
 #define	SOFTNET_UNLOCK()	KASSERT(mutex_owned(softnet_lock))
+#endif
 
 /*
  * IP initialization: fill in IP protocol switch table.
@@ -437,11 +442,15 @@ ipintr(void *arg __unused)
 
 	KASSERT(cpu_softintr_p());
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
+#endif
 	while ((m = pktq_dequeue(ip_pktq)) != NULL) {
 		ip_input(m);
 	}
+#ifndef NET_MPSAFE
 	mutex_exit(softnet_lock);
+#endif
 }
 
 /*
@@ -614,9 +623,7 @@ ip_input(struct mbuf *m)
 		struct in_addr odst = ip->ip_dst;
 		bool freed;
 
-		SOFTNET_LOCK();
 		freed = pfil_run_hooks(inet_pfil_hook, &m, ifp, PFIL_IN) != 0;
-		SOFTNET_UNLOCK();
 		if (freed || m == NULL) {
 			m = NULL;
 			goto out;
@@ -1334,11 +1341,8 @@ ip_forward(struct mbuf *m, int srcrt, st
 		return;
 	}
 
-	SOFTNET_LOCK();
-
 	if (ip->ip_ttl <= IPTTLDEC) {
 		icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
-		SOFTNET_UNLOCK();
 		return;
 	}
 
@@ -1348,7 +1352,6 @@ ip_forward(struct mbuf *m, int srcrt, st
 	if ((rt = rtcache_lookup(ro, &u.dst)) == NULL) {
 		percpu_putref(ipforward_rt_percpu);
 		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0);
-		SOFTNET_UNLOCK();
 		return;
 	}
 
@@ -1419,14 +1422,12 @@ ip_forward(struct mbuf *m, int srcrt, st
 	}
 
 	percpu_putref(ipforward_rt_percpu);
-	SOFTNET_UNLOCK();
 	return;
 
 redirect:
 error:
 	if (mcopy == NULL) {
 		percpu_putref(ipforward_rt_percpu);
-		SOFTNET_UNLOCK();
 		return;
 	}
 
@@ -1468,12 +1469,10 @@ error:
 		if (mcopy)
 			m_freem(mcopy);
 		percpu_putref(ipforward_rt_percpu);
-		SOFTNET_UNLOCK();
 		return;
 	}
 	icmp_error(mcopy, type, code, dest, destmtu);
 	percpu_putref(ipforward_rt_percpu);
-	SOFTNET_UNLOCK();
 }
 
 void

Index: src/sys/netinet6/in6.c
diff -u src/sys/netinet6/in6.c:1.220 src/sys/netinet6/in6.c:1.221
--- src/sys/netinet6/in6.c:1.220	Tue Sep 13 15:57:50 2016
+++ src/sys/netinet6/in6.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6.c,v 1.220 2016/09/13 15:57:50 christos Exp $	*/
+/*	$NetBSD: in6.c,v 1.221 2016/10/18 07:30:31 ozaki-r Exp $	*/
 /*	$KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $	*/
 
 /*
@@ -62,11 +62,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.220 2016/09/13 15:57:50 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.221 2016/10/18 07:30:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include <sys/param.h>
@@ -773,9 +774,13 @@ in6_control(struct socket *so, u_long cm
 	}
 
 	s = splnet();
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
+#endif
 	error = in6_control1(so , cmd, data, ifp);
+#ifndef NET_MPSAFE
 	mutex_exit(softnet_lock);
+#endif
 	splx(s);
 	return error;
 }

Index: src/sys/netinet6/ip6_flow.c
diff -u src/sys/netinet6/ip6_flow.c:1.31 src/sys/netinet6/ip6_flow.c:1.32
--- src/sys/netinet6/ip6_flow.c:1.31	Tue Aug 23 09:59:20 2016
+++ src/sys/netinet6/ip6_flow.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_flow.c,v 1.31 2016/08/23 09:59:20 knakahara Exp $	*/
+/*	$NetBSD: ip6_flow.c,v 1.32 2016/10/18 07:30:31 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -38,7 +38,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_flow.c,v 1.31 2016/08/23 09:59:20 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_flow.c,v 1.32 2016/10/18 07:30:31 ozaki-r Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_net_mpsafe.h"
+#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -505,9 +509,11 @@ ip6flow_slowtimo_work(struct work *wk, v
 	/* We can allow enqueuing another work at this point */
 	atomic_swap_uint(&ip6flow_work_enqueued, 0);
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
-	mutex_enter(&ip6flow_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
+	mutex_enter(&ip6flow_lock);
 
 	for (ip6f = TAILQ_FIRST(&ip6flowlist); ip6f != NULL; ip6f = next_ip6f) {
 		next_ip6f = TAILQ_NEXT(ip6f, ip6f_list);
@@ -523,9 +529,11 @@ ip6flow_slowtimo_work(struct work *wk, v
 		}
 	}
 
-	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(&ip6flow_lock);
+#ifndef NET_MPSAFE
+	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 }
 
 void
@@ -550,22 +558,21 @@ ip6flow_create(const struct route *ro, s
 	struct ip6flow *ip6f;
 	size_t hash;
 
-	mutex_enter(&ip6flow_lock);
-
 	ip6 = mtod(m, const struct ip6_hdr *);
 
+#ifndef NET_MPSAFE
+	KERNEL_LOCK(1, NULL);
+#endif
+	mutex_enter(&ip6flow_lock);
+
 	/*
 	 * If IPv6 Fast Forward is disabled, don't create a flow.
 	 * It can be disabled by setting net.inet6.ip6.maxflows to 0.
 	 *
 	 * Don't create a flow for ICMPv6 messages.
 	 */
-	if (ip6_maxflows == 0 || ip6->ip6_nxt == IPPROTO_IPV6_ICMP) {
-		mutex_exit(&ip6flow_lock);
-		return;
-	}
-
-	KERNEL_LOCK(1, NULL);
+	if (ip6_maxflows == 0 || ip6->ip6_nxt == IPPROTO_IPV6_ICMP)
+		goto out;
 
 	/*
 	 * See if an existing flow exists.  If so:
@@ -616,8 +623,10 @@ ip6flow_create(const struct route *ro, s
 	IP6FLOW_INSERT(hash, ip6f);
 
  out:
-	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(&ip6flow_lock);
+#ifndef NET_MPSAFE
+	KERNEL_UNLOCK_ONE(NULL);
+#endif
 }
 
 /*
@@ -660,13 +669,17 @@ sysctl_net_inet6_ip6_maxflows(SYSCTLFN_A
 	if (error || newp == NULL)
 		return (error);
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
 
 	ip6flow_reap(0);
 
+#ifndef NET_MPSAFE
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 
 	return (0);
 }
@@ -688,13 +701,15 @@ sysctl_net_inet6_ip6_hashsize(SYSCTLFN_A
 		/*
 		 * Can only fail due to malloc()
 		 */
+#ifndef NET_MPSAFE
 		mutex_enter(softnet_lock);
 		KERNEL_LOCK(1, NULL);
-
+#endif
 		error = ip6flow_invalidate_all(tmp);
-
+#ifndef NET_MPSAFE
 		KERNEL_UNLOCK_ONE(NULL);
 		mutex_exit(softnet_lock);
+#endif
 	} else {
 		/*
 		 * EINVAL if not a power of 2

Index: src/sys/netinet6/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.168 src/sys/netinet6/ip6_input.c:1.169
--- src/sys/netinet6/ip6_input.c:1.168	Wed Sep  7 15:41:44 2016
+++ src/sys/netinet6/ip6_input.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_input.c,v 1.168 2016/09/07 15:41:44 roy Exp $	*/
+/*	$NetBSD: ip6_input.c,v 1.169 2016/10/18 07:30:31 ozaki-r Exp $	*/
 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.168 2016/09/07 15:41:44 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.169 2016/10/18 07:30:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_gateway.h"
@@ -70,6 +70,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_input.c,
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
 #include "opt_compat_netbsd.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include <sys/param.h>
@@ -155,6 +156,14 @@ static int ip6_process_hopopts(struct mb
 static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
 static void sysctl_net_inet6_ip6_setup(struct sysctllog **);
 
+#ifdef NET_MPSAFE
+#define	SOFTNET_LOCK()		mutex_enter(softnet_lock)
+#define	SOFTNET_UNLOCK()	mutex_exit(softnet_lock)
+#else
+#define	SOFTNET_LOCK()		KASSERT(mutex_owned(softnet_lock))
+#define	SOFTNET_UNLOCK()	KASSERT(mutex_owned(softnet_lock))
+#endif
+
 /*
  * IP6 initialization: fill in IP6 protocol switch table.
  * All protocols not implemented in kernel go to raw IP6 protocol handler.
@@ -223,7 +232,9 @@ ip6intr(void *arg __unused)
 {
 	struct mbuf *m;
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
+#endif
 	while ((m = pktq_dequeue(ip6_pktq)) != NULL) {
 		struct psref psref;
 		struct ifnet *rcvif = m_get_rcvif_psref(m, &psref);
@@ -243,7 +254,9 @@ ip6intr(void *arg __unused)
 		ip6_input(m, rcvif);
 		m_put_rcvif_psref(rcvif, &psref);
 	}
+#ifndef NET_MPSAFE
 	mutex_exit(softnet_lock);
+#endif
 }
 
 void
@@ -360,9 +373,14 @@ ip6_input(struct mbuf *m, struct ifnet *
 	IP6_STATINC(IP6_STAT_NXTHIST + ip6->ip6_nxt);
 
 #ifdef ALTQ
-	if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) {
-		/* packet is dropped by traffic conditioner */
-		return;
+	if (altq_input != NULL) {
+		SOFTNET_LOCK();
+		if ((*altq_input)(m, AF_INET6) == 0) {
+			SOFTNET_UNLOCK();
+			/* packet is dropped by traffic conditioner */
+			return;
+		}
+		SOFTNET_UNLOCK();
 	}
 #endif
 
@@ -674,10 +692,18 @@ ip6_input(struct mbuf *m, struct ifnet *
 		 * ip6_mforward() returns a non-zero value, the packet
 		 * must be discarded, else it may be accepted below.
 		 */
-		if (ip6_mrouter && ip6_mforward(ip6, rcvif, m)) {
-			IP6_STATINC(IP6_STAT_CANTFORWARD);
-			m_freem(m);
-			return;
+		if (ip6_mrouter != NULL) {
+			int error;
+
+			SOFTNET_LOCK();
+			error = ip6_mforward(ip6, rcvif, m);
+			SOFTNET_UNLOCK();
+
+			if (error != 0) {
+				IP6_STATINC(IP6_STAT_CANTFORWARD);
+				m_freem(m);
+				return;
+			}
 		}
 		if (!ours) {
 			m_freem(m);
@@ -758,14 +784,20 @@ ip6_input(struct mbuf *m, struct ifnet *
 			 */
 			if ((inet6sw[ip_protox[nxt]].pr_flags
 			    & PR_LASTHDR) != 0) {
-				int error = ipsec6_input(m);
+				int error;
+
+				SOFTNET_LOCK();
+				error = ipsec6_input(m);
+				SOFTNET_UNLOCK();
 				if (error)
 					goto bad;
 			}
 		}
 #endif /* IPSEC */
 
+		SOFTNET_LOCK();
 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
+		SOFTNET_UNLOCK();
 	}
 	return;
  bad:

Index: src/sys/netinet6/nd6.c
diff -u src/sys/netinet6/nd6.c:1.208 src/sys/netinet6/nd6.c:1.209
--- src/sys/netinet6/nd6.c:1.208	Tue Oct 18 02:46:50 2016
+++ src/sys/netinet6/nd6.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.c,v 1.208 2016/10/18 02:46:50 ozaki-r Exp $	*/
+/*	$NetBSD: nd6.c,v 1.209 2016/10/18 07:30:31 ozaki-r Exp $	*/
 /*	$KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.208 2016/10/18 02:46:50 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.209 2016/10/18 07:30:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -443,8 +443,10 @@ nd6_llinfo_timer(void *arg)
 	bool send_ns = false;
 	const struct in6_addr *daddr6 = NULL;
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
 
 	LLE_WLOCK(ln);
 	if (ln->ln_ntick > 0) {
@@ -558,8 +560,10 @@ nd6_llinfo_timer(void *arg)
 out:
 	if (ln != NULL)
 		LLE_FREE_LOCKED(ln);
+#ifndef NET_MPSAFE
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 }
 
 /*
@@ -577,8 +581,10 @@ nd6_timer_work(struct work *wk, void *ar
 	callout_reset(&nd6_timer_ch, nd6_prune * hz,
 	    nd6_timer, NULL);
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
 
 	/* expire default router list */
 	
@@ -699,8 +705,10 @@ nd6_timer_work(struct work *wk, void *ar
 		}
 	}
 
+#ifndef NET_MPSAFE
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 }
 
 static void
@@ -2177,8 +2185,10 @@ nd6_slowtimo(void *ignored_arg)
 	struct ifnet *ifp;
 	int s;
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
 	callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
 	    nd6_slowtimo, NULL);
 
@@ -2199,8 +2209,10 @@ nd6_slowtimo(void *ignored_arg)
 	}
 	pserialize_read_exit(s);
 
+#ifndef NET_MPSAFE
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 }
 
 int

Index: src/sys/netinet6/nd6_nbr.c
diff -u src/sys/netinet6/nd6_nbr.c:1.127 src/sys/netinet6/nd6_nbr.c:1.128
--- src/sys/netinet6/nd6_nbr.c:1.127	Mon Aug  1 03:15:31 2016
+++ src/sys/netinet6/nd6_nbr.c	Tue Oct 18 07:30:31 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6_nbr.c,v 1.127 2016/08/01 03:15:31 ozaki-r Exp $	*/
+/*	$NetBSD: nd6_nbr.c,v 1.128 2016/10/18 07:30:31 ozaki-r Exp $	*/
 /*	$KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $	*/
 
 /*
@@ -31,10 +31,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.127 2016/08/01 03:15:31 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.128 2016/10/18 07:30:31 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include <sys/param.h>
@@ -1099,7 +1100,11 @@ static void
 nd6_dad_stoptimer(struct dadq *dp)
 {
 
+#ifdef NET_MPSAFE
+	callout_halt(&dp->dad_timer_ch, NULL);
+#else
 	callout_halt(&dp->dad_timer_ch, softnet_lock);
+#endif
 }
 
 /*
@@ -1224,8 +1229,10 @@ nd6_dad_timer(struct ifaddr *ifa)
 	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
 	struct dadq *dp;
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
+#endif
 	mutex_enter(&nd6_dad_lock);
 
 	/* Sanity check */
@@ -1321,8 +1328,10 @@ nd6_dad_timer(struct ifaddr *ifa)
 
 done:
 	mutex_exit(&nd6_dad_lock);
+#ifndef NET_MPSAFE
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
+#endif
 }
 
 void

Reply via email to