diff options
| author | knakahara <knakahara@NetBSD.org> | 2016-11-18 06:50:04 +0000 |
|---|---|---|
| committer | knakahara <knakahara@NetBSD.org> | 2016-11-18 06:50:04 +0000 |
| commit | 3e0f109d2b57bc45d946dcf0131db2c009183bd9 (patch) | |
| tree | d40f11df40edd3615c552adc7b5a96e9ee3f2b72 /sys/netinet6/udp6_usrreq.c | |
| parent | 225fe2a511b806f5d3c9592e462fef5e13369338 (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/udp6_usrreq.c')
| -rw-r--r-- | sys/netinet6/udp6_usrreq.c | 9 |
1 files changed, 7 insertions, 2 deletions
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; } |
