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@lerctr.org> Submitted by: markj, jch
This commit is contained in:
parent
607712fac9
commit
349429fe82
@ -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);
|
||||
}
|
||||
|
@ -491,6 +491,7 @@ short inp_so_options(const struct inpcb *inp);
|
||||
#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)
|
||||
|
@ -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) ||
|
||||
|
@ -163,7 +163,7 @@ tcp_detach(struct socket *so, struct inpcb *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
|
||||
|
Loading…
Reference in New Issue
Block a user