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