--- sys/contrib/pf/net/pf.c	2007/11/21 10:16:46
+++ sys/contrib/pf/net/pf.c	2008/01/05 21:18:08
@@ -2967,6 +2967,9 @@
 #ifdef INET
 	case AF_INET:
 #ifdef __FreeBSD__
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(pi);	/* XXX LOR */
 		inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
 			dport, 0, NULL);
@@ -2991,6 +2994,9 @@
 #ifdef INET6
 	case AF_INET6:
 #ifdef __FreeBSD__
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(pi);
 		inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
 			&daddr->v6, dport, 0, NULL);
--- sys/dev/cxgb/ulp/tom/cxgb_tom.c	2007/12/17 08:22:48
+++ sys/dev/cxgb/ulp/tom/cxgb_tom.c	2008/01/05 21:18:08
@@ -425,7 +425,11 @@
 {
 	struct inpcb *inp;
 	struct tcpcb *tp;
-	
+
+	/*
+	 * XXXRW: rlock OK.
+	 * XXXRW: shouldn't this lock the inpcb?
+	 */
 	INP_INFO_RLOCK(&tcbinfo);
 	LIST_FOREACH(inp, tcbinfo.ipi_listhead, inp_list) {
 		tp = intotcpcb(inp);
--- sys/kern/subr_witness.c	2007/12/25 17:56:52
+++ sys/kern/subr_witness.c	2008/01/05 23:02:01
@@ -327,14 +327,14 @@
 	/*
 	 * UDP/IP
 	 */
-	{ "udp", &lock_class_mtx_sleep },
+	{ "udp", &lock_class_rw },
 	{ "udpinp", &lock_class_mtx_sleep },
 	{ "so_snd", &lock_class_mtx_sleep },
 	{ NULL, NULL },
 	/*
 	 * TCP/IP
 	 */
-	{ "tcp", &lock_class_mtx_sleep },
+	{ "tcp", &lock_class_rw },
 	{ "tcpinp", &lock_class_mtx_sleep },
 	{ "so_snd", &lock_class_mtx_sleep },
 	{ NULL, NULL },
--- sys/netinet/in_pcb.c	2007/12/22 10:12:29
+++ sys/netinet/in_pcb.c	2008/01/05 21:20:31
@@ -854,6 +854,9 @@
 	struct ip_moptions *imo;
 	int i, gap;
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(pcbinfo);
 	LIST_FOREACH(inp, pcbinfo->ipi_listhead, inp_list) {
 		INP_LOCK(inp);
@@ -1011,7 +1014,10 @@
 	struct inpcb *inp;
 	u_short fport = fport_arg, lport = lport_arg;
 
-	INP_INFO_RLOCK_ASSERT(pcbinfo);
+	/*
+	 * XXXRW: lock OK.
+	 */
+	INP_INFO_LOCK_ASSERT(pcbinfo);
 
 	/*
 	 * First look for an exact match.
--- sys/netinet/in_pcb.h	2007/12/07 01:46:38
+++ sys/netinet/in_pcb.h	2008/01/05 21:16:40
@@ -36,9 +36,14 @@
 #include <sys/queue.h>
 #include <sys/_lock.h>
 #include <sys/_mutex.h>
+#include <sys/_rwlock.h>
 
 #include <net/route.h>
 
+#ifdef _KERNEL
+#include <sys/rwlock.h>		/* XXXRW: Avoid adding rwlock everywhere yet. */
+#endif
+
 #define	in6pcb		inpcb	/* for KAME src sync over BSD*'s */
 #define	in6p_sp		inp_sp	/* for KAME src sync over BSD*'s */
 struct inpcbpolicy;
@@ -264,7 +269,7 @@
 	 * or freed.
 	 */
 	u_quad_t		 ipi_gencnt;
-	struct mtx		 ipi_mtx;
+	struct rwlock		 ipi_lock;
 
 	/*
 	 * vimage 1
@@ -282,15 +287,16 @@
 #define	INP_UNLOCK_ASSERT(inp)	mtx_assert(&(inp)->inp_mtx, MA_NOTOWNED)
 
 #define INP_INFO_LOCK_INIT(ipi, d) \
-	mtx_init(&(ipi)->ipi_mtx, (d), NULL, MTX_DEF | MTX_RECURSE)
-#define INP_INFO_LOCK_DESTROY(ipi)  mtx_destroy(&(ipi)->ipi_mtx)
-#define INP_INFO_RLOCK(ipi)	mtx_lock(&(ipi)->ipi_mtx)
-#define INP_INFO_WLOCK(ipi)	mtx_lock(&(ipi)->ipi_mtx)
-#define INP_INFO_RUNLOCK(ipi)	mtx_unlock(&(ipi)->ipi_mtx)
-#define INP_INFO_WUNLOCK(ipi)	mtx_unlock(&(ipi)->ipi_mtx)
-#define INP_INFO_RLOCK_ASSERT(ipi)	mtx_assert(&(ipi)->ipi_mtx, MA_OWNED)
-#define INP_INFO_WLOCK_ASSERT(ipi)	mtx_assert(&(ipi)->ipi_mtx, MA_OWNED)
-#define INP_INFO_UNLOCK_ASSERT(ipi)	mtx_assert(&(ipi)->ipi_mtx, MA_NOTOWNED)
+	rw_init_flags(&(ipi)->ipi_lock, (d), RW_RECURSE)
+#define INP_INFO_LOCK_DESTROY(ipi)  rw_destroy(&(ipi)->ipi_lock)
+#define INP_INFO_RLOCK(ipi)	rw_rlock(&(ipi)->ipi_lock)
+#define INP_INFO_WLOCK(ipi)	rw_wlock(&(ipi)->ipi_lock)
+#define INP_INFO_RUNLOCK(ipi)	rw_runlock(&(ipi)->ipi_lock)
+#define INP_INFO_WUNLOCK(ipi)	rw_wunlock(&(ipi)->ipi_lock)
+#define	INP_INFO_LOCK_ASSERT(ipi)	rw_assert(&(ipi)->ipi_lock, RA_LOCKED)
+#define INP_INFO_RLOCK_ASSERT(ipi)	rw_assert(&(ipi)->ipi_lock, RA_RLOCKED)
+#define INP_INFO_WLOCK_ASSERT(ipi)	rw_assert(&(ipi)->ipi_lock, RA_WLOCKED)
+#define INP_INFO_UNLOCK_ASSERT(ipi)	rw_assert(&(ipi)->ipi_lock, RA_UNLOCKED)
 
 #define INP_PCBHASH(faddr, lport, fport, mask) \
 	(((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask))
--- sys/netinet/ip_divert.c	2007/10/24 19:06:35
+++ sys/netinet/ip_divert.c	2008/01/05 21:18:08
@@ -266,6 +266,9 @@
 	/* Put packet on socket queue, if any */
 	sa = NULL;
 	nport = htons((u_int16_t)divert_info(mtag));
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&divcbinfo);
 	LIST_FOREACH(inp, &divcb, inp_list) {
 		INP_LOCK(inp);
@@ -590,6 +593,9 @@
 	/*
 	 * OK, now we're committed to doing something.
 	 */
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&divcbinfo);
 	gencnt = divcbinfo.ipi_gencnt;
 	n = divcbinfo.ipi_count;
--- sys/netinet/ip_fw2.c	2007/12/09 15:35:46
+++ sys/netinet/ip_fw2.c	2008/01/05 21:18:08
@@ -2013,6 +2013,9 @@
 		return 0;
 	match = 0;
 	if (*lookup == 0) {
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(pi);
 		pcb =  (oif) ?
 			in_pcblookup_hash(pi,
--- sys/netinet/raw_ip.c	2007/10/24 19:06:35
+++ sys/netinet/raw_ip.c	2008/01/05 21:18:08
@@ -205,6 +205,9 @@
 	int proto = ip->ip_p;
 	struct inpcb *inp, *last;
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&ripcbinfo);
 	ripsrc.sin_addr = ip->ip_src;
 	last = NULL;
@@ -831,6 +834,9 @@
 	/*
 	 * OK, now we're committed to doing something.
 	 */
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&ripcbinfo);
 	gencnt = ripcbinfo.ipi_gencnt;
 	n = ripcbinfo.ipi_count;
@@ -847,7 +853,10 @@
 	inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
 	if (inp_list == 0)
 		return ENOMEM;
-	
+
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&ripcbinfo);
 	for (inp = LIST_FIRST(ripcbinfo.ipi_listhead), i = 0; inp && i < n;
 	     inp = LIST_NEXT(inp, inp_list)) {
@@ -887,6 +896,9 @@
 		 * while we were processing this request, and it
 		 * might be necessary to retry.
 		 */
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(&ripcbinfo);
 		xig.xig_gen = ripcbinfo.ipi_gencnt;
 		xig.xig_sogen = so_gencnt;
--- sys/netinet/tcp_subr.c	2007/12/18 23:02:41
+++ sys/netinet/tcp_subr.c	2008/01/05 21:18:08
@@ -811,6 +811,9 @@
 	 *	where we're really low on mbufs, this is potentially
 	 *	usefull.
 	 */
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(&tcbinfo);
 		LIST_FOREACH(inpb, tcbinfo.ipi_listhead, inp_list) {
 			if (inpb->inp_vflag & INP_TIMEWAIT)
@@ -911,6 +914,9 @@
 	/*
 	 * OK, now we're committed to doing something.
 	 */
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&tcbinfo);
 	gencnt = tcbinfo.ipi_gencnt;
 	n = tcbinfo.ipi_count;
@@ -939,6 +945,9 @@
 	if (inp_list == NULL)
 		return (ENOMEM);
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&tcbinfo);
 	for (inp = LIST_FIRST(tcbinfo.ipi_listhead), i = 0; inp != NULL && i
 	    < n; inp = LIST_NEXT(inp, inp_list)) {
@@ -1007,6 +1016,9 @@
 		 * while we were processing this request, and it
 		 * might be necessary to retry.
 		 */
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(&tcbinfo);
 		xig.xig_gen = tcbinfo.ipi_gencnt;
 		xig.xig_sogen = so_gencnt;
@@ -1035,6 +1047,9 @@
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
 		return (error);
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&tcbinfo);
 	inp = in_pcblookup_hash(&tcbinfo, addrs[1].sin_addr, addrs[1].sin_port,
 	    addrs[0].sin_addr, addrs[0].sin_port, 0, NULL);
@@ -1090,6 +1105,9 @@
 			return (EINVAL);
 	}
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&tcbinfo);
 	if (mapped == 1)
 		inp = in_pcblookup_hash(&tcbinfo,
--- sys/netinet/tcp_timer.c	2007/10/07 20:49:19
+++ sys/netinet/tcp_timer.c	2008/01/05 21:18:08
@@ -152,6 +152,9 @@
 	struct tcpcb *tp = xtp;
 	struct inpcb *inp;
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&tcbinfo);
 	inp = tp->t_inpcb;
 	/*
--- sys/netinet/udp_usrreq.c	2007/10/24 19:06:35
+++ sys/netinet/udp_usrreq.c	2008/01/05 21:18:08
@@ -382,6 +382,9 @@
 	}
 #endif
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&udbinfo);
 	if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
 	    in_broadcast(ip->ip_dst, ifp)) {
@@ -606,6 +609,9 @@
 		return;
 	if (ip != NULL) {
 		uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(&udbinfo);
 		inp = in_pcblookup_hash(&udbinfo, faddr, uh->uh_dport,
 		    ip->ip_src, uh->uh_sport, 0, NULL);
@@ -647,6 +653,9 @@
 	/*
 	 * OK, now we're committed to doing something.
 	 */
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&udbinfo);
 	gencnt = udbinfo.ipi_gencnt;
 	n = udbinfo.ipi_count;
@@ -669,6 +678,9 @@
 	if (inp_list == 0)
 		return (ENOMEM);
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&udbinfo);
 	for (inp = LIST_FIRST(udbinfo.ipi_listhead), i = 0; inp && i < n;
 	     inp = LIST_NEXT(inp, inp_list)) {
@@ -706,6 +718,9 @@
 		 * that something happened while we were processing this
 		 * request, and it might be necessary to retry.
 		 */
+		/*
+		 * XXXRW: rlock OK.
+		 */
 		INP_INFO_RLOCK(&udbinfo);
 		xig.xig_gen = udbinfo.ipi_gencnt;
 		xig.xig_sogen = so_gencnt;
@@ -734,6 +749,9 @@
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
 		return (error);
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&udbinfo);
 	inp = in_pcblookup_hash(&udbinfo, addrs[1].sin_addr, addrs[1].sin_port,
 				addrs[0].sin_addr, addrs[0].sin_port, 1, NULL);
--- sys/netinet6/icmp6.c	2007/12/10 16:07:50
+++ sys/netinet6/icmp6.c	2008/01/05 21:18:08
@@ -1889,6 +1889,9 @@
 		return (IPPROTO_DONE);
 	}
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&ripcbinfo);
 	LIST_FOREACH(in6p, &ripcb, inp_list) {
 		INP_LOCK(in6p);
--- sys/netinet6/in6_pcb.c	2007/12/17 17:22:20
+++ sys/netinet6/in6_pcb.c	2008/01/05 21:20:31
@@ -767,6 +767,9 @@
 	struct ip6_moptions *im6o;
 	struct in6_multi_mship *imm, *nimm;
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(pcbinfo);
 	LIST_FOREACH(in6p, pcbinfo->ipi_listhead, inp_list) {
 		INP_LOCK(in6p);
@@ -843,7 +846,10 @@
 	u_short fport = fport_arg, lport = lport_arg;
 	int faith;
 
-	INP_INFO_RLOCK_ASSERT(pcbinfo);
+	/*
+	 * XXXRW: lock OK.
+	 */
+	INP_INFO_LOCK_ASSERT(pcbinfo);
 
 	if (faithprefix_p != NULL)
 		faith = (*faithprefix_p)(laddr);
--- sys/netinet6/raw_ip6.c	2007/12/10 16:07:50
+++ sys/netinet6/raw_ip6.c	2008/01/05 21:18:08
@@ -152,6 +152,9 @@
 
 	init_sin6(&fromsa, m); /* general init */
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&ripcbinfo);
 	LIST_FOREACH(in6p, &ripcb, inp_list) {
 		INP_LOCK(in6p);
--- sys/netinet6/udp6_usrreq.c	2007/12/10 16:07:50
+++ sys/netinet6/udp6_usrreq.c	2008/01/05 21:18:08
@@ -227,6 +227,9 @@
 	init_sin6(&fromsa, m);
 	fromsa.sin6_port = uh->uh_sport;
 
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&udbinfo);
 	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
 		struct inpcb *last;
@@ -445,6 +448,9 @@
 	    (error = sa6_embedscope(&addrs[1], ip6_use_defzone)) != 0) {
 		return (error);
 	}
+	/*
+	 * XXXRW: rlock OK.
+	 */
 	INP_INFO_RLOCK(&udbinfo);
 	inp = in6_pcblookup_hash(&udbinfo, &addrs[1].sin6_addr,
 	    addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port, 1,
