Module Name:    src
Committed By:   knakahara
Date:           Fri Nov 18 10:38:55 UTC 2016

Modified Files:
        src/sys/net: if_spppsubr.c
        src/sys/netinet: in.c in_var.h

Log Message:
We must use PSLIST_ENTRY_DESTROY after PSLIST_WRITER_REMOVE and waiting all 
readers done.

And then, if we want to re-insert the removed pslist element, we need to
call PSLIST_ENTERY_INIT again.

advised by [email protected] and reviewed by [email protected], thanks.


To generate a diff of this commit:
cvs rdiff -u -r1.156 -r1.157 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.187 -r1.188 src/sys/netinet/in.c
cvs rdiff -u -r1.88 -r1.89 src/sys/netinet/in_var.h

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_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.156 src/sys/net/if_spppsubr.c:1.157
--- src/sys/net/if_spppsubr.c:1.156	Sat Oct  8 17:37:32 2016
+++ src/sys/net/if_spppsubr.c	Fri Nov 18 10:38:55 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_spppsubr.c,v 1.156 2016/10/08 17:37:32 joerg Exp $	 */
+/*	$NetBSD: if_spppsubr.c,v 1.157 2016/11/18 10:38:55 knakahara Exp $	 */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,12 +41,13 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.156 2016/10/08 17:37:32 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.157 2016/11/18 10:38:55 knakahara Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
 #include "opt_modular.h"
 #include "opt_compat_netbsd.h"
+#include "opt_net_mpsafe.h"
 #endif
 
 
@@ -4915,9 +4916,14 @@ found:
 
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
+#ifdef NET_MPSAFE
+		pserialize_perform(in_ifaddrhash_psz);
+#endif
+		IN_ADDRHASH_ENTRY_DESTROY(ifatoia(ifa));
 
 		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, &new_dst, 0);
 
+		IN_ADDRHASH_ENTRY_INIT(ifatoia(ifa));
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ifatoia(ifa)->ia_addr.sin_addr.s_addr),
 		    ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_INSERT_HEAD(ifatoia(ifa));
@@ -4977,9 +4983,14 @@ found:
 
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
+#ifdef NET_MPSAFE
+		pserialize_perform(in_ifaddrhash_psz);
+#endif
+		IN_ADDRHASH_ENTRY_DESTROY(ifatoia(ifa));
 
 		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, &new_dst, 0);
 
+		IN_ADDRHASH_ENTRY_INIT(ifatoia(ifa));
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ifatoia(ifa)->ia_addr.sin_addr.s_addr),
 		    ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_INSERT_HEAD(ifatoia(ifa));

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.187 src/sys/netinet/in.c:1.188
--- src/sys/netinet/in.c:1.187	Tue Oct 18 07:30:31 2016
+++ src/sys/netinet/in.c	Fri Nov 18 10:38:55 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.187 2016/10/18 07:30:31 ozaki-r Exp $	*/
+/*	$NetBSD: in.c,v 1.188 2016/11/18 10:38:55 knakahara 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.187 2016/10/18 07:30:31 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.188 2016/11/18 10:38:55 knakahara Exp $");
 
 #include "arp.h"
 
@@ -193,6 +193,7 @@ u_long				in_ifaddrhash;
 struct in_ifaddrhead		in_ifaddrhead;
 static kmutex_t			in_ifaddr_lock;
 
+pserialize_t			in_ifaddrhash_psz;
 struct pslist_head *		in_ifaddrhashtbl_pslist;
 u_long				in_ifaddrhash_pslist;
 struct pslist_head		in_ifaddrhead_pslist;
@@ -208,6 +209,7 @@ in_init(void)
 	in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,
 	    &in_ifaddrhash);
 
+	in_ifaddrhash_psz = pserialize_create();
 	in_ifaddrhashtbl_pslist = hashinit(IN_IFADDR_HASH_SIZE, HASH_PSLIST,
 	    true, &in_ifaddrhash_pslist);
 	mutex_init(&in_ifaddr_lock, MUTEX_DEFAULT, IPL_NONE);
@@ -600,6 +602,10 @@ in_control0(struct socket *so, u_long cm
 			LIST_REMOVE(ia, ia_hash);
 			IN_ADDRHASH_WRITER_REMOVE(ia);
 			mutex_exit(&in_ifaddr_lock);
+#ifdef NET_MPSAFE
+			pserialize_perform(in_ifaddrhash_psz);
+#endif
+			IN_ADDRHASH_ENTRY_DESTROY(ia);
 			need_reinsert = true;
 		}
 		error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)),
@@ -617,6 +623,10 @@ in_control0(struct socket *so, u_long cm
 			LIST_REMOVE(ia, ia_hash);
 			IN_ADDRHASH_WRITER_REMOVE(ia);
 			mutex_exit(&in_ifaddr_lock);
+#ifdef NET_MPSAFE
+			pserialize_perform(in_ifaddrhash_psz);
+#endif
+			IN_ADDRHASH_ENTRY_DESTROY(ia);
 			need_reinsert = true;
 		}
 		error = in_ifinit(ifp, ia, NULL, NULL, 0);
@@ -643,6 +653,10 @@ in_control0(struct socket *so, u_long cm
 				LIST_REMOVE(ia, ia_hash);
 				IN_ADDRHASH_WRITER_REMOVE(ia);
 				mutex_exit(&in_ifaddr_lock);
+#ifdef NET_MPSAFE
+				pserialize_perform(in_ifaddrhash_psz);
+#endif
+				IN_ADDRHASH_ENTRY_DESTROY(ia);
 				need_reinsert = true;
 			}
 			error = in_ifinit(ifp, ia, &ifra->ifra_addr,
@@ -709,6 +723,7 @@ in_control0(struct socket *so, u_long cm
 		mutex_enter(&in_ifaddr_lock);
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
 		    ia, ia_hash);
+		IN_ADDRHASH_ENTRY_INIT(ia);
 		IN_ADDRHASH_WRITER_INSERT_HEAD(ia);
 		mutex_exit(&in_ifaddr_lock);
 	}
@@ -843,6 +858,9 @@ in_purgeaddr(struct ifaddr *ifa)
 	ifa_remove(ifp, &ia->ia_ifa);
 	mutex_exit(&in_ifaddr_lock);
 
+#ifdef NET_MPSAFE
+	pserialize_perform(in_ifaddrhash_psz);
+#endif
 	IN_ADDRHASH_ENTRY_DESTROY(ia);
 	IN_ADDRLIST_ENTRY_DESTROY(ia);
 	ifafree(&ia->ia_ifa);

Index: src/sys/netinet/in_var.h
diff -u src/sys/netinet/in_var.h:1.88 src/sys/netinet/in_var.h:1.89
--- src/sys/netinet/in_var.h:1.88	Tue Oct 11 13:59:30 2016
+++ src/sys/netinet/in_var.h	Fri Nov 18 10:38:55 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_var.h,v 1.88 2016/10/11 13:59:30 roy Exp $	*/
+/*	$NetBSD: in_var.h,v 1.89 2016/11/18 10:38:55 knakahara Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -172,6 +172,7 @@ extern	u_long in_ifaddrhash;			/* size o
 extern  struct in_ifaddrhashhead *in_ifaddrhashtbl;	/* Hash table head */
 extern  struct in_ifaddrhead in_ifaddrhead;		/* List head (in ip_input) */
 
+extern pserialize_t in_ifaddrhash_psz;
 extern struct pslist_head *in_ifaddrhashtbl_pslist;
 extern u_long in_ifaddrhash_pslist;
 extern struct pslist_head in_ifaddrhead_pslist;

Reply via email to