From owner-svn-src-head@freebsd.org Sat Aug 8 08:40:38 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6A6A49B325F; Sat, 8 Aug 2015 08:40:38 +0000 (UTC) (envelope-from jch@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 58C6215CA; Sat, 8 Aug 2015 08:40:38 +0000 (UTC) (envelope-from jch@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t788ecIo036291; Sat, 8 Aug 2015 08:40:38 GMT (envelope-from jch@FreeBSD.org) Received: (from jch@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t788ebXb036287; Sat, 8 Aug 2015 08:40:37 GMT (envelope-from jch@FreeBSD.org) Message-Id: <201508080840.t788ebXb036287@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jch set sender to jch@FreeBSD.org using -f From: Julien Charbon Date: Sat, 8 Aug 2015 08:40:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r286443 - head/sys/netinet X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 Aug 2015 08:40:38 -0000 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 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