Module Name:    src
Committed By:   ozaki-r
Date:           Wed Jul  6 05:27:52 UTC 2016

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

Log Message:
Add and use pslist(9)-based hashtable for IPv4 addresses

Note that we leave the old hashtable to keep vmstat -H working.


To generate a diff of this commit:
cvs rdiff -u -r1.144 -r1.145 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.169 -r1.170 src/sys/netinet/in.c
cvs rdiff -u -r1.74 -r1.75 src/sys/netinet/in_var.h
cvs rdiff -u -r1.333 -r1.334 src/sys/netinet/ip_input.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_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.144 src/sys/net/if_spppsubr.c:1.145
--- src/sys/net/if_spppsubr.c:1.144	Thu Jun 30 01:34:53 2016
+++ src/sys/net/if_spppsubr.c	Wed Jul  6 05:27:52 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_spppsubr.c,v 1.144 2016/06/30 01:34:53 ozaki-r Exp $	 */
+/*	$NetBSD: if_spppsubr.c,v 1.145 2016/07/06 05:27:52 ozaki-r Exp $	 */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.144 2016/06/30 01:34:53 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.145 2016/07/06 05:27:52 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -4897,10 +4897,16 @@ found:
 				*dest = new_dst; /* fix dstaddr in place */
 			}
 		}
+
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
+		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
+
 		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0, hostIsNew);
+
 		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));
+
 		if (debug && error)
 		{
 			log(LOG_DEBUG, "%s: sppp_set_ip_addrs: in_ifinit "
@@ -4953,10 +4959,16 @@ found:
 		if (sp->ipcp.flags & IPCP_HISADDR_DYN)
 			/* replace peer addr in place */
 			dest->sin_addr.s_addr = sp->ipcp.saved_hisaddr;
+
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
+		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
+
 		in_ifinit(ifp, ifatoia(ifa), &new_sin, 0, 0);
+
 		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));
+
 		(void)pfil_run_hooks(if_pfil,
 		    (struct mbuf **)SIOCDIFADDR, ifp, PFIL_IFADDR);
 	}

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.169 src/sys/netinet/in.c:1.170
--- src/sys/netinet/in.c:1.169	Thu Jun 30 01:34:53 2016
+++ src/sys/netinet/in.c	Wed Jul  6 05:27:52 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.169 2016/06/30 01:34:53 ozaki-r Exp $	*/
+/*	$NetBSD: in.c,v 1.170 2016/07/06 05:27:52 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.169 2016/06/30 01:34:53 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.170 2016/07/06 05:27:52 ozaki-r Exp $");
 
 #include "arp.h"
 
@@ -185,10 +185,14 @@ static krwlock_t		in_multilock;
 #define IN_MULTI_HASH(x, ifp) \
     (in_multihashtbl[(u_long)((x) ^ (ifp->if_index)) % IN_MULTI_HASH_SIZE])
 
+/* XXX DEPRECATED. Keep it to avoid breaking kvm(3) users. */
 struct in_ifaddrhashhead *	in_ifaddrhashtbl;
 u_long				in_ifaddrhash;
 struct in_ifaddrhead		in_ifaddrhead;
 
+struct pslist_head *		in_ifaddrhashtbl_pslist;
+u_long				in_ifaddrhash_pslist;
+
 void
 in_init(void)
 {
@@ -198,6 +202,8 @@ in_init(void)
 
 	in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,
 	    &in_ifaddrhash);
+	in_ifaddrhashtbl_pslist = hashinit(IN_IFADDR_HASH_SIZE, HASH_PSLIST,
+	    true, &in_ifaddrhash_pslist);
 	in_multihashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,
 	    &in_multihash);
 	rw_init(&in_multilock);
@@ -388,15 +394,15 @@ in_control(struct socket *so, u_long cmd
 	case SIOCDIFADDR:
 	case SIOCGIFALIAS:
 	case SIOCGIFAFLAG_IN:
-		if (ifra->ifra_addr.sin_family == AF_INET)
-			LIST_FOREACH(ia,
-			    &IN_IFADDR_HASH(ifra->ifra_addr.sin_addr.s_addr),
-			    ia_hash) {
+		if (ifra->ifra_addr.sin_family == AF_INET) {
+			IN_ADDRHASH_READER_FOREACH(ia,
+			    ifra->ifra_addr.sin_addr.s_addr) {
 				if (ia->ia_ifp == ifp &&
 				    in_hosteq(ia->ia_addr.sin_addr,
 				    ifra->ifra_addr.sin_addr))
 					break;
 			}
+		}
 		if ((cmd == SIOCDIFADDR ||
 		    cmd == SIOCGIFALIAS ||
 		    cmd == SIOCGIFAFLAG_IN) &&
@@ -459,6 +465,7 @@ in_control(struct socket *so, u_long cmd
 			ia->ia_ifp = ifp;
 			ia->ia_idsalt = cprng_fast32() % 65535;
 			LIST_INIT(&ia->ia_multiaddrs);
+			IN_ADDRHASH_ENTRY_INIT(ia);
 
 			newifaddr = 1;
 		}
@@ -535,6 +542,7 @@ in_control(struct socket *so, u_long cmd
 	case SIOCSIFADDR:
 		if (!newifaddr) {
 			LIST_REMOVE(ia, ia_hash);
+			IN_ADDRHASH_WRITER_REMOVE(ia);
 			need_reinsert = true;
 		}
 		error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)),
@@ -549,6 +557,7 @@ in_control(struct socket *so, u_long cmd
 		ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
 		if (!newifaddr) {
 			LIST_REMOVE(ia, ia_hash);
+			IN_ADDRHASH_WRITER_REMOVE(ia);
 			need_reinsert = true;
 		}
 		error = in_ifinit(ifp, ia, NULL, 0, 0);
@@ -578,6 +587,7 @@ in_control(struct socket *so, u_long cmd
 		    (hostIsNew || maskIsNew)) {
 			if (!newifaddr) {
 				LIST_REMOVE(ia, ia_hash);
+				IN_ADDRHASH_WRITER_REMOVE(ia);
 				need_reinsert = true;
 			}
 			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0,
@@ -632,9 +642,11 @@ in_control(struct socket *so, u_long cmd
 		ifa_insert(ifp, &ia->ia_ifa);
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
 		    ia, ia_hash);
+		IN_ADDRHASH_WRITER_INSERT_HEAD(ia);
 	} else if (need_reinsert) {
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
 		    ia, ia_hash);
+		IN_ADDRHASH_WRITER_INSERT_HEAD(ia);
 	}
 
 	if (error == 0) {
@@ -706,6 +718,8 @@ in_purgeaddr(struct ifaddr *ifa)
 	in_ifscrub(ifp, ia);
 	in_ifremlocal(ifa);
 	LIST_REMOVE(ia, ia_hash);
+	IN_ADDRHASH_WRITER_REMOVE(ia);
+	IN_ADDRHASH_ENTRY_DESTROY(ia);
 	ifa_remove(ifp, &ia->ia_ifa);
 	TAILQ_REMOVE(&in_ifaddrhead, ia, ia_list);
 	if (ia->ia_allhosts != NULL)

Index: src/sys/netinet/in_var.h
diff -u src/sys/netinet/in_var.h:1.74 src/sys/netinet/in_var.h:1.75
--- src/sys/netinet/in_var.h:1.74	Mon Aug 31 08:05:20 2015
+++ src/sys/netinet/in_var.h	Wed Jul  6 05:27:52 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_var.h,v 1.74 2015/08/31 08:05:20 ozaki-r Exp $	*/
+/*	$NetBSD: in_var.h,v 1.75 2016/07/06 05:27:52 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -104,6 +104,10 @@ struct in_ifaddr {
 	int	ia4_flags;		/* address flags */
 	void	(*ia_dad_start) (struct ifaddr *);	/* DAD start function */
 	void	(*ia_dad_stop) (struct ifaddr *);	/* DAD stop function */
+
+#ifdef _KERNEL
+	struct pslist_entry	ia_hash_pslist_entry;
+#endif
 };
 
 struct	in_aliasreq {
@@ -142,6 +146,26 @@ 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 struct pslist_head *in_ifaddrhashtbl_pslist;
+extern u_long in_ifaddrhash_pslist;
+
+#define IN_IFADDR_HASH_PSLIST(x)					\
+	in_ifaddrhashtbl_pslist[(u_long)(x) % IN_IFADDR_HASH_SIZE]
+
+#define IN_ADDRHASH_READER_FOREACH(__ia, __addr)			\
+	PSLIST_READER_FOREACH((__ia), &IN_IFADDR_HASH_PSLIST(__addr),	\
+	    struct in_ifaddr, ia_hash_pslist_entry)
+#define IN_ADDRHASH_WRITER_INSERT_HEAD(__ia)				\
+	PSLIST_WRITER_INSERT_HEAD(					\
+	    &IN_IFADDR_HASH_PSLIST((__ia)->ia_addr.sin_addr.s_addr),	\
+	    (__ia), ia_hash_pslist_entry)
+#define IN_ADDRHASH_WRITER_REMOVE(__ia)					\
+	PSLIST_WRITER_REMOVE((__ia), ia_hash_pslist_entry)
+#define IN_ADDRHASH_ENTRY_INIT(__ia)					\
+	PSLIST_ENTRY_INIT((__ia), ia_hash_pslist_entry);
+#define IN_ADDRHASH_ENTRY_DESTROY(__ia)					\
+	PSLIST_ENTRY_DESTROY((__ia), ia_hash_pslist_entry);
+
 extern	const	int	inetctlerrmap[];
 
 /*

Index: src/sys/netinet/ip_input.c
diff -u src/sys/netinet/ip_input.c:1.333 src/sys/netinet/ip_input.c:1.334
--- src/sys/netinet/ip_input.c:1.333	Mon Jul  4 08:10:50 2016
+++ src/sys/netinet/ip_input.c	Wed Jul  6 05:27:52 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.333 2016/07/04 08:10:50 ozaki-r Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.334 2016/07/06 05:27:52 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.333 2016/07/04 08:10:50 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.334 2016/07/06 05:27:52 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -372,7 +372,7 @@ ip_match_our_address(struct ifnet *ifp, 
 	checkif = ip_checkinterface && (ipforwarding == 0) &&
 	    (ifp->if_flags & IFF_LOOPBACK) == 0;
 
-	LIST_FOREACH(ia, &IN_IFADDR_HASH(ip->ip_dst.s_addr), ia_hash) {
+	IN_ADDRHASH_READER_FOREACH(ia, ip->ip_dst.s_addr) {
 		if (in_hosteq(ia->ia_addr.sin_addr, ip->ip_dst)) {
 			if (ia->ia4_flags & IN_IFF_NOTREADY)
 				continue;

Reply via email to