svn commit: r286443 - head/sys/netinet

Julien Charbon jch at FreeBSD.org
Sat Aug 8 08:40:38 UTC 2015


Author: jch
Date: Sat Aug  8 08:40:36 2015
New Revision: 286443
URL: https://svnweb.freebsd.org/changeset/base/286443

Log:
  Fix a kernel assertion issue introduced with r286227:
  Avoid too strict INP_INFO_RLOCK_ASSERT checks due to
  tcp_notify() being called from in6_pcbnotify().
  
  Reported by:	Larry Rosenman <ler at lerctr.org>
  Submitted by:	markj, jch

Modified:
  head/sys/netinet/in_pcb.c
  head/sys/netinet/in_pcb.h
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/tcp_usrreq.c

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Sat Aug  8 06:08:20 2015	(r286442)
+++ head/sys/netinet/in_pcb.c	Sat Aug  8 08:40:36 2015	(r286443)
@@ -1259,7 +1259,7 @@ in_pcbfree(struct inpcb *inp)
 
 #ifdef INVARIANTS
 	if (pcbinfo == &V_tcbinfo) {
-		INP_INFO_RLOCK_ASSERT(pcbinfo);
+		INP_INFO_LOCK_ASSERT(pcbinfo);
 	} else {
 		INP_INFO_WLOCK_ASSERT(pcbinfo);
 	}

Modified: head/sys/netinet/in_pcb.h
==============================================================================
--- head/sys/netinet/in_pcb.h	Sat Aug  8 06:08:20 2015	(r286442)
+++ head/sys/netinet/in_pcb.h	Sat Aug  8 08:40:36 2015	(r286443)
@@ -491,6 +491,7 @@ short	inp_so_options(const struct inpcb 
 #define INP_INFO_TRY_RLOCK(ipi)	rw_try_rlock(&(ipi)->ipi_lock)
 #define INP_INFO_TRY_WLOCK(ipi)	rw_try_wlock(&(ipi)->ipi_lock)
 #define INP_INFO_TRY_UPGRADE(ipi)	rw_try_upgrade(&(ipi)->ipi_lock)
+#define INP_INFO_WLOCKED(ipi)	rw_wowned(&(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)

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c	Sat Aug  8 06:08:20 2015	(r286442)
+++ head/sys/netinet/tcp_subr.c	Sat Aug  8 08:40:36 2015	(r286443)
@@ -906,7 +906,7 @@ tcp_drop(struct tcpcb *tp, int errno)
 {
 	struct socket *so = tp->t_inpcb->inp_socket;
 
-	INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
+	INP_INFO_LOCK_ASSERT(&V_tcbinfo);
 	INP_WLOCK_ASSERT(tp->t_inpcb);
 
 	if (TCPS_HAVERCVDSYN(tp->t_state)) {
@@ -1108,7 +1108,7 @@ tcp_close(struct tcpcb *tp)
 	struct inpcb *inp = tp->t_inpcb;
 	struct socket *so;
 
-	INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
+	INP_INFO_LOCK_ASSERT(&V_tcbinfo);
 	INP_WLOCK_ASSERT(inp);
 
 #ifdef TCP_OFFLOAD
@@ -1186,7 +1186,7 @@ tcp_notify(struct inpcb *inp, int error)
 {
 	struct tcpcb *tp;
 
-	INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
+	INP_INFO_LOCK_ASSERT(&V_tcbinfo);
 	INP_WLOCK_ASSERT(inp);
 
 	if ((inp->inp_flags & INP_TIMEWAIT) ||

Modified: head/sys/netinet/tcp_usrreq.c
==============================================================================
--- head/sys/netinet/tcp_usrreq.c	Sat Aug  8 06:08:20 2015	(r286442)
+++ head/sys/netinet/tcp_usrreq.c	Sat Aug  8 08:40:36 2015	(r286443)
@@ -163,7 +163,7 @@ tcp_detach(struct socket *so, struct inp
 {
 	struct tcpcb *tp;
 
-	INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
+	INP_INFO_LOCK_ASSERT(&V_tcbinfo);
 	INP_WLOCK_ASSERT(inp);
 
 	KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp"));
@@ -241,15 +241,20 @@ static void
 tcp_usr_detach(struct socket *so)
 {
 	struct inpcb *inp;
+	int rlock = 0;
 
 	inp = sotoinpcb(so);
 	KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL"));
-	INP_INFO_RLOCK(&V_tcbinfo);
+	if (!INP_INFO_WLOCKED(&V_tcbinfo)) {
+		INP_INFO_RLOCK(&V_tcbinfo);
+		rlock = 1;
+	}
 	INP_WLOCK(inp);
 	KASSERT(inp->inp_socket != NULL,
 	    ("tcp_usr_detach: inp_socket == NULL"));
 	tcp_detach(so, inp);
-	INP_INFO_RUNLOCK(&V_tcbinfo);
+	if (rlock)
+		INP_INFO_RUNLOCK(&V_tcbinfo);
 }
 
 #ifdef INET


More information about the svn-src-head mailing list