summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorknakahara <knakahara@NetBSD.org>2016-11-18 06:50:04 +0000
committerknakahara <knakahara@NetBSD.org>2016-11-18 06:50:04 +0000
commit3e0f109d2b57bc45d946dcf0131db2c009183bd9 (patch)
treed40f11df40edd3615c552adc7b5a96e9ee3f2b72 /sys/netinet6
parent225fe2a511b806f5d3c9592e462fef5e13369338 (diff)
fix: "ifconfig destory" can stalls when "ifconfig" is done parallel.
This problem occurs only if NET_MPSAFE on. ifconfig destroy side: kernel entry point is ifioctl => if_clone_destroy. pr_purgeif() acquires softnet_lock, and then ifa_remove() calls pserialize_perform() holding softnet_lock. ifconfig side: kernel entry point is socreate. pr_attach()(udp_attach_wrapper()) calls sosetlock(). In this call path, sosetlock() try to acquire softnet_lock. These can cause dead lock.
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/dccp6_usrreq.c9
-rw-r--r--sys/netinet6/in6.c8
-rw-r--r--sys/netinet6/mld6.c9
-rw-r--r--sys/netinet6/raw_ip6.c9
-rw-r--r--sys/netinet6/sctp6_usrreq.c9
-rw-r--r--sys/netinet6/udp6_usrreq.c9
6 files changed, 41 insertions, 12 deletions
diff --git a/sys/netinet6/dccp6_usrreq.c b/sys/netinet6/dccp6_usrreq.c
index 3d7823cf450..03ca05760c6 100644
--- a/sys/netinet6/dccp6_usrreq.c
+++ b/sys/netinet6/dccp6_usrreq.c
@@ -1,5 +1,5 @@
/* $KAME: dccp6_usrreq.c,v 1.13 2005/07/27 08:42:56 nishida Exp $ */
-/* $NetBSD: dccp6_usrreq.c,v 1.8 2016/04/26 08:44:45 ozaki-r Exp $ */
+/* $NetBSD: dccp6_usrreq.c,v 1.9 2016/11/18 06:50:04 knakahara Exp $ */
/*
* Copyright (C) 2003 WIDE Project.
@@ -31,11 +31,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dccp6_usrreq.c,v 1.8 2016/04/26 08:44:45 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dccp6_usrreq.c,v 1.9 2016/11/18 06:50:04 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#include "opt_dccp.h"
+#include "opt_net_mpsafe.h"
#endif
#include <sys/param.h>
@@ -318,11 +319,15 @@ dccp6_purgeif(struct socket *so, struct ifnet *ifp)
int s;
s = splsoftnet();
+#ifndef NET_MPSAFE
mutex_enter(softnet_lock);
+#endif
in6_pcbpurgeif0(&dccpbtable, ifp);
in6_purgeif(ifp);
in6_pcbpurgeif(&dccpbtable, ifp);
+#ifndef NET_MPSAFE
mutex_exit(softnet_lock);
+#endif
splx(s);
return 0;
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index bac4d7dbfc9..50f5d386df3 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in6.c,v 1.221 2016/10/18 07:30:31 ozaki-r Exp $ */
+/* $NetBSD: in6.c,v 1.222 2016/11/18 06:50:04 knakahara 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.221 2016/10/18 07:30:31 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.222 2016/11/18 06:50:04 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -2376,8 +2376,12 @@ in6_lltable_free_entry(struct lltable *llt, struct llentry *lle)
lltable_unlink_entry(llt, lle);
}
+#ifdef NET_MPSAFE
+ callout_halt(&lle->lle_timer, NULL);
+#else
KASSERT(mutex_owned(softnet_lock));
callout_halt(&lle->lle_timer, softnet_lock);
+#endif
LLE_REMREF(lle);
llentry_free(lle);
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index a3e27ed71b7..63672920f95 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mld6.c,v 1.74 2016/08/01 03:15:31 ozaki-r Exp $ */
+/* $NetBSD: mld6.c,v 1.75 2016/11/18 06:50:04 knakahara Exp $ */
/* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */
/*
@@ -102,10 +102,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.74 2016/08/01 03:15:31 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.75 2016/11/18 06:50:04 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
+#include "opt_net_mpsafe.h"
#endif
#include <sys/param.h>
@@ -789,7 +790,11 @@ in6_delmulti(struct in6_multi *in6m)
/* Tell mld_timeo we're halting the timer */
in6m->in6m_timer = IN6M_TIMER_UNDEF;
+#ifdef NET_MPSAFE
+ callout_halt(&in6m->in6m_timer_ch, NULL);
+#else
callout_halt(&in6m->in6m_timer_ch, softnet_lock);
+#endif
callout_destroy(&in6m->in6m_timer_ch);
free(in6m, M_IPMADDR);
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 182ae210088..fea1f67a340 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $NetBSD: raw_ip6.c,v 1.152 2016/10/31 04:16:25 ozaki-r Exp $ */
+/* $NetBSD: raw_ip6.c,v 1.153 2016/11/18 06:50:04 knakahara Exp $ */
/* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */
/*
@@ -62,10 +62,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.152 2016/10/31 04:16:25 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.153 2016/11/18 06:50:04 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_ipsec.h"
+#include "opt_net_mpsafe.h"
#endif
#include <sys/param.h>
@@ -935,11 +936,15 @@ static int
rip6_purgeif(struct socket *so, struct ifnet *ifp)
{
+#ifndef NET_MPSAFE
mutex_enter(softnet_lock);
+#endif
in6_pcbpurgeif0(&raw6cbtable, ifp);
in6_purgeif(ifp);
in6_pcbpurgeif(&raw6cbtable, ifp);
+#ifndef NET_MPSAFE
mutex_exit(softnet_lock);
+#endif
return 0;
}
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 13f405acef4..2b9b0eb700a 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -1,5 +1,5 @@
/* $KAME: sctp6_usrreq.c,v 1.38 2005/08/24 08:08:56 suz Exp $ */
-/* $NetBSD: sctp6_usrreq.c,v 1.8 2016/08/01 03:15:31 ozaki-r Exp $ */
+/* $NetBSD: sctp6_usrreq.c,v 1.9 2016/11/18 06:50:04 knakahara Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
@@ -33,12 +33,13 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sctp6_usrreq.c,v 1.8 2016/08/01 03:15:31 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sctp6_usrreq.c,v 1.9 2016/11/18 06:50:04 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_sctp.h"
+#include "opt_net_mpsafe.h"
#endif /* _KERNEL_OPT */
#include <sys/param.h>
@@ -1301,9 +1302,13 @@ sctp6_purgeif(struct socket *so, struct ifnet *ifp)
}
}
+#ifndef NET_MPSAFE
mutex_enter(softnet_lock);
+#endif
in6_purgeif(ifp);
+#ifndef NET_MPSAFE
mutex_exit(softnet_lock);
+#endif
return 0;
}
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 3fc3b6e8513..417ee6d9625 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -1,4 +1,4 @@
-/* $NetBSD: udp6_usrreq.c,v 1.125 2016/11/15 20:50:28 mlelstv Exp $ */
+/* $NetBSD: udp6_usrreq.c,v 1.126 2016/11/18 06:50:04 knakahara Exp $ */
/* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */
/*
@@ -62,12 +62,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.125 2016/11/15 20:50:28 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.126 2016/11/18 06:50:04 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#include "opt_inet_csum.h"
#include "opt_ipsec.h"
+#include "opt_net_mpsafe.h"
#endif
#include <sys/param.h>
@@ -911,11 +912,15 @@ static int
udp6_purgeif(struct socket *so, struct ifnet *ifp)
{
+#ifndef NET_MPSAFE
mutex_enter(softnet_lock);
+#endif
in6_pcbpurgeif0(&udbtable, ifp);
in6_purgeif(ifp);
in6_pcbpurgeif(&udbtable, ifp);
+#ifndef NET_MPSAFE
mutex_exit(softnet_lock);
+#endif
return 0;
}