Module Name:    src
Committed By:   knakahara
Date:           Fri Nov 18 06:50:04 UTC 2016

Modified Files:
        src/sys/netinet: tcp_usrreq.c udp_usrreq.c
        src/sys/netinet6: dccp6_usrreq.c in6.c mld6.c raw_ip6.c sctp6_usrreq.c
            udp6_usrreq.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.212 -r1.213 src/sys/netinet/tcp_usrreq.c
cvs rdiff -u -r1.228 -r1.229 src/sys/netinet/udp_usrreq.c
cvs rdiff -u -r1.8 -r1.9 src/sys/netinet6/dccp6_usrreq.c \
    src/sys/netinet6/sctp6_usrreq.c
cvs rdiff -u -r1.221 -r1.222 src/sys/netinet6/in6.c
cvs rdiff -u -r1.74 -r1.75 src/sys/netinet6/mld6.c
cvs rdiff -u -r1.152 -r1.153 src/sys/netinet6/raw_ip6.c
cvs rdiff -u -r1.125 -r1.126 src/sys/netinet6/udp6_usrreq.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/netinet/tcp_usrreq.c
diff -u src/sys/netinet/tcp_usrreq.c:1.212 src/sys/netinet/tcp_usrreq.c:1.213
--- src/sys/netinet/tcp_usrreq.c:1.212	Tue Apr 26 08:44:45 2016
+++ src/sys/netinet/tcp_usrreq.c	Fri Nov 18 06:50:04 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: tcp_usrreq.c,v 1.212 2016/04/26 08:44:45 ozaki-r Exp $	*/
+/*	$NetBSD: tcp_usrreq.c,v 1.213 2016/11/18 06:50:04 knakahara Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -99,13 +99,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.212 2016/04/26 08:44:45 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.213 2016/11/18 06:50:04 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
 #include "opt_tcp_debug.h"
 #include "opt_mbuftrace.h"
 #include "opt_tcp_space.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include <sys/param.h>
@@ -1205,9 +1206,13 @@ static int
 tcp_purgeif(struct socket *so, struct ifnet *ifp)
 {
 	int s;
+	int error = 0;
 
 	s = splsoftnet();
+
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
+#endif
 	switch (so->so_proto->pr_domain->dom_family) {
 #ifdef INET
 	case PF_INET:
@@ -1224,14 +1229,15 @@ tcp_purgeif(struct socket *so, struct if
 		break;
 #endif
 	default:
-		mutex_exit(softnet_lock);
-		splx(s);
-		return EAFNOSUPPORT;
+		error = EAFNOSUPPORT;
+		break;
 	}
+#ifndef NET_MPSAFE
 	mutex_exit(softnet_lock);
+#endif
 	splx(s);
 
-	return 0;
+	return error;
 }
 
 /*

Index: src/sys/netinet/udp_usrreq.c
diff -u src/sys/netinet/udp_usrreq.c:1.228 src/sys/netinet/udp_usrreq.c:1.229
--- src/sys/netinet/udp_usrreq.c:1.228	Tue Nov 15 20:50:28 2016
+++ src/sys/netinet/udp_usrreq.c	Fri Nov 18 06:50:04 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp_usrreq.c,v 1.228 2016/11/15 20:50:28 mlelstv Exp $	*/
+/*	$NetBSD: udp_usrreq.c,v 1.229 2016/11/18 06:50:04 knakahara Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.228 2016/11/15 20:50:28 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.229 2016/11/18 06:50:04 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -75,6 +75,7 @@ __KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c
 #include "opt_inet_csum.h"
 #include "opt_ipkdb.h"
 #include "opt_mbuftrace.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 #include <sys/param.h>
@@ -1139,11 +1140,15 @@ udp_purgeif(struct socket *so, struct if
 	int s;
 
 	s = splsoftnet();
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
+#endif
 	in_pcbpurgeif0(&udbtable, ifp);
 	in_purgeif(ifp);
 	in_pcbpurgeif(&udbtable, ifp);
+#ifndef NET_MPSAFE
 	mutex_exit(softnet_lock);
+#endif
 	splx(s);
 
 	return 0;

Index: src/sys/netinet6/dccp6_usrreq.c
diff -u src/sys/netinet6/dccp6_usrreq.c:1.8 src/sys/netinet6/dccp6_usrreq.c:1.9
--- src/sys/netinet6/dccp6_usrreq.c:1.8	Tue Apr 26 08:44:45 2016
+++ src/sys/netinet6/dccp6_usrreq.c	Fri Nov 18 06:50:04 2016
@@ -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 
 	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;
Index: src/sys/netinet6/sctp6_usrreq.c
diff -u src/sys/netinet6/sctp6_usrreq.c:1.8 src/sys/netinet6/sctp6_usrreq.c:1.9
--- src/sys/netinet6/sctp6_usrreq.c:1.8	Mon Aug  1 03:15:31 2016
+++ src/sys/netinet6/sctp6_usrreq.c	Fri Nov 18 06:50:04 2016
@@ -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 
 		}
 	}
 
+#ifndef NET_MPSAFE
 	mutex_enter(softnet_lock);
+#endif
 	in6_purgeif(ifp);
+#ifndef NET_MPSAFE
 	mutex_exit(softnet_lock);
+#endif
 
 	return 0;
 }

Index: src/sys/netinet6/in6.c
diff -u src/sys/netinet6/in6.c:1.221 src/sys/netinet6/in6.c:1.222
--- src/sys/netinet6/in6.c:1.221	Tue Oct 18 07:30:31 2016
+++ src/sys/netinet6/in6.c	Fri Nov 18 06:50:04 2016
@@ -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 *l
 		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);

Index: src/sys/netinet6/mld6.c
diff -u src/sys/netinet6/mld6.c:1.74 src/sys/netinet6/mld6.c:1.75
--- src/sys/netinet6/mld6.c:1.74	Mon Aug  1 03:15:31 2016
+++ src/sys/netinet6/mld6.c	Fri Nov 18 06:50:04 2016
@@ -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);

Index: src/sys/netinet6/raw_ip6.c
diff -u src/sys/netinet6/raw_ip6.c:1.152 src/sys/netinet6/raw_ip6.c:1.153
--- src/sys/netinet6/raw_ip6.c:1.152	Mon Oct 31 04:16:25 2016
+++ src/sys/netinet6/raw_ip6.c	Fri Nov 18 06:50:04 2016
@@ -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;
 }

Index: src/sys/netinet6/udp6_usrreq.c
diff -u src/sys/netinet6/udp6_usrreq.c:1.125 src/sys/netinet6/udp6_usrreq.c:1.126
--- src/sys/netinet6/udp6_usrreq.c:1.125	Tue Nov 15 20:50:28 2016
+++ src/sys/netinet6/udp6_usrreq.c	Fri Nov 18 06:50:04 2016
@@ -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;
 }

Reply via email to