--- contrib/pf/net/pf.c 2007/11/21 10:16:46 +++ contrib/pf/net/pf.c 2008/01/06 23:09:29 @@ -2915,7 +2915,7 @@ pd->lookup.pid = NO_PID; /* XXX: revisit */ #ifdef __FreeBSD__ if (inp_arg != NULL) { - INP_LOCK_ASSERT(inp_arg); + INP_RLOCK_ASSERT(inp_arg); if (inp_arg->inp_socket) { pd->lookup.uid = inp_arg->inp_socket->so_cred->cr_uid; pd->lookup.gid = @@ -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); @@ -3018,15 +3024,15 @@ return (-1); } #ifdef __FreeBSD__ - INP_LOCK(inp); + INP_RLOCK(inp); if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) { - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_RUNLOCK(pi); return (-1); } pd->lookup.uid = inp->inp_socket->so_cred->cr_uid; pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0]; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_RUNLOCK(pi); #else pd->lookup.uid = inp->inp_socket->so_euid; --- dev/cxgb/ulp/tom/cxgb_cpl_io.c 2007/12/17 10:06:58 +++ dev/cxgb/ulp/tom/cxgb_cpl_io.c 2008/01/06 23:09:29 @@ -191,9 +191,9 @@ if (__predict_false(tp->t_state == TCPS_SYN_SENT)) { - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); mbufq_tail(&toep->out_of_order_queue, m); // defer - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); } else if (through_l2t) l2t_send(T3C_DEV(so), m, toep->tp_l2t); // send through L2T else @@ -228,7 +228,7 @@ struct toepcb *toep = tp->t_toe; struct tx_data_wr *req; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); req = mtod(m, struct tx_data_wr *); m->m_len = sizeof(*req); @@ -281,7 +281,7 @@ return (0); } - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); SOCKBUF_LOCK(&so->so_snd); @@ -401,7 +401,7 @@ unsigned int tid; - INP_LOCK(inp); + INP_WLOCK(inp); tp = sototcpcb(so); toep = tp->t_toe; @@ -409,7 +409,7 @@ t3_push_frames(so, 1); if (toep->tp_flags & TP_FIN_SENT) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return; } @@ -426,7 +426,7 @@ req->wr.wr_lo = htonl(V_WR_TID(tid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, tid)); req->rsvd = htonl(toep->tp_write_seq); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); /* * XXX - need to defer shutdown while there is still data in the queue * @@ -496,7 +496,7 @@ if (!((tp->t_state == TCPS_ESTABLISHED) || (tp->t_state == TCPS_FIN_WAIT_1) || (tp->t_state == TCPS_FIN_WAIT_2))) return; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); so = tp->t_inpcb->inp_socket; SOCKBUF_LOCK(&so->so_rcv); @@ -592,7 +592,7 @@ static int cxgb_toe_rcvd(struct tcpcb *tp) { - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); t3_cleanup_rbuf(tp); return (0); @@ -801,7 +801,7 @@ if (!m) return (ENOMEM); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); m_set_priority(m, mkprio(CPL_PRIORITY_CONTROL, so)); req = mtod(m, struct cpl_get_tcb *); m->m_pkthdr.len = m->m_len = sizeof(*req); @@ -919,7 +919,7 @@ toep->tp_tp = NULL; if (tp) { - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); tp->t_toe = NULL; tp->t_flags &= ~TF_TOE; } @@ -1143,7 +1143,7 @@ t3_release_offload_resources(toep); if (tp) { - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); cxgb_tcp_drop(tp, errno); } @@ -1166,7 +1166,7 @@ goto done; inp = toep->tp_tp->t_inpcb; - INP_LOCK(inp); + INP_WLOCK(inp); /* * Don't handle connection retry for now @@ -1182,7 +1182,7 @@ } else #endif fail_act_open(toep, act_open_rpl_status_to_errno(rpl->status)); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); done: INP_INFO_WUNLOCK(&tcbinfo); @@ -1232,14 +1232,14 @@ struct inpcb *inp = tp->t_inpcb; struct socket *so = toeptoso(toep); - INP_LOCK(inp); + INP_WLOCK(inp); if (tp->t_state == TCPS_SYN_SENT || tp->t_state == TCPS_SYN_RECEIVED) { fail_act_open(so, EHOSTUNREACH); printf("freeing %p\n", m); m_free(m); } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } #endif /* @@ -1269,7 +1269,7 @@ if (!e) goto free_tid; - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); m = m_gethdr(MT_DATA, M_WAITOK); #if 0 @@ -1326,7 +1326,7 @@ struct mbuf *m; if (tp) { - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); so = toeptoso(toep); } @@ -1435,14 +1435,14 @@ inp = sotoinpcb(so); tp = intotcpcb(inp); - INP_LOCK(inp); + INP_WLOCK(inp); oldval = tp->t_flags; if (optval) tp->t_flags |= TF_NODELAY; else tp->t_flags &= ~TF_NODELAY; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (oldval != tp->t_flags) t3_set_nagle(so); @@ -1479,7 +1479,7 @@ struct socket *so = toeptoso(toep); int len = be16toh(hdr->len); - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); #ifdef notyet if (__predict_false(sk_no_receive(sk))) { @@ -1545,7 +1545,7 @@ ("so=%p, data contents exceed mbmax, sb_cc=%d sb_mbmax=%d", so, so->so_rcv.sb_cc, so->so_rcv.sb_mbmax)); - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); DPRINTF("sb_cc=%d sb_mbcnt=%d\n", so->so_rcv.sb_cc, so->so_rcv.sb_mbcnt); @@ -1785,7 +1785,7 @@ { struct tcpcb *tp = sototcpcb(so); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* * Bump rcv_nxt for the peer FIN. We don't do this at the time we * process peer_close because we don't want to carry the peer FIN in @@ -1832,7 +1832,7 @@ sock_set_flag(so, SOCK_DONE); #endif INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); if (TCPS_HAVERCVDFIN(tp->t_state) == 0) socantrcvmore(so); switch (tp->t_state) { @@ -1868,7 +1868,7 @@ } INP_INFO_WUNLOCK(&tcbinfo); if (tp) - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); if (!dead) { DPRINTF("waking up waiters on %p rcv_notify=%d flags=0x%x\n", so, sb_notify(&so->so_rcv), so->so_rcv.sb_flags); @@ -1922,7 +1922,7 @@ goto out; INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); switch (tp->t_state) { case TCPS_CLOSING: /* see FIN_WAIT2 case in do_peer_fin */ t3_release_offload_resources(toep); @@ -1968,7 +1968,7 @@ } INP_INFO_WUNLOCK(&tcbinfo); if (tp) - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); out: m_free(m); } @@ -2006,7 +2006,7 @@ "process_abort_rpl: GTS rpl pending %d", sock_flag(sk, ABORT_RPL_PENDING)); #endif - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); if (toep->tp_flags & TP_ABORT_RPL_PENDING) { /* @@ -2021,7 +2021,7 @@ if (toep->tp_flags & TP_ABORT_REQ_RCVD) panic("TP_ABORT_REQ_RCVD set"); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); t3_release_offload_resources(toep); tp = tcp_close(tp); INP_INFO_WUNLOCK(&tcbinfo); @@ -2029,7 +2029,7 @@ } } if (tp) - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); m_free(m); } @@ -2215,12 +2215,12 @@ if (__predict_false(parenttp->t_state == TCPS_LISTEN)) { cleanup_syn_rcv_conn(child, parent); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(childtp->t_inpcb); + INP_WLOCK(childtp->t_inpcb); t3_release_offload_resources(childtp->t_toe); childtp = tcp_close(childtp); INP_INFO_WUNLOCK(&tcbinfo); if (childtp) - INP_UNLOCK(childtp->t_inpcb); + INP_WUNLOCK(childtp->t_inpcb); } } #endif @@ -2268,7 +2268,7 @@ struct tcpcb *tp = sototcpcb(so); struct toepcb *toep = tp->t_toe; - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); if ((toep->tp_flags & TP_ABORT_REQ_RCVD) == 0) { toep->tp_flags |= (TP_ABORT_REQ_RCVD|TP_ABORT_SHUTDOWN); m_free(m); @@ -2304,12 +2304,12 @@ tp = tcp_close(tp); } if (tp) - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); send_abort_rpl(m, tdev, rst_status); return; skip: - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); } /* @@ -2545,7 +2545,7 @@ to.to_flags = (mss ? TOF_MSS : 0) | (wsf ? TOF_SCALE : 0) | (ts ? TOF_TS : 0) | (sack ? TOF_SACKPERM : 0); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); syncache_offload_add(&inc, &to, &th, inp, &lso, &cxgb_toe_usrreqs, toep); } @@ -2802,7 +2802,7 @@ struct tcpcb *tp = sototcpcb(so); struct toepcb *toep = tp->t_toe; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); toep->tp_mss_clamp = td->mtus[G_TCPOPT_MSS(opt)] - 40; tp->t_flags |= G_TCPOPT_TSTAMP(opt) ? TF_RCVD_TSTMP : 0; @@ -2947,7 +2947,7 @@ toepcb_release(toep); tp = sototcpcb(so); - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); #ifdef notyet so->so_snd.sb_flags |= SB_TOE; so->so_rcv.sb_flags |= SB_TOE; @@ -2974,7 +2974,7 @@ make_established(so, ntohl(req->snd_isn), ntohs(req->tcp_opt)); INP_INFO_WUNLOCK(&tcbinfo); - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); soisconnected(so); #ifdef notyet @@ -3022,7 +3022,7 @@ printf("fixup_and_send_ofo\n"); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); while ((m = mbufq_dequeue(&toep->out_of_order_queue)) != NULL) { /* * A variety of messages can be waiting but the fields we'll @@ -3125,7 +3125,7 @@ tdev = TOE_DEV(so); /* blow up here if link was down */ d = TOM_DATA(tdev); - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); /* * It's OK if the TID is currently in use, the owning socket may have @@ -3138,7 +3138,7 @@ toep->tp_qset = G_QNUM(ntohl(m->m_pkthdr.csum_data)); socket_act_establish(so, m); - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); return (0); } @@ -3158,7 +3158,7 @@ DPRINTF("wr_ack: snd_una=%u credits=%d\n", snd_una, credits); - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); toep->tp_wr_avail += credits; if (toep->tp_wr_unacked > toep->tp_wr_max - toep->tp_wr_avail) @@ -3238,7 +3238,7 @@ t3_push_frames(so, 0); out_free: - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); m_free(m); } @@ -3290,9 +3290,9 @@ tp = sototcpcb(so); if (tp->t_flags & TF_TOE) { - INP_LOCK(tp->t_inpcb); + INP_WLOCK(tp->t_inpcb); t3_reset_listen_child(so); - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); } } --- dev/cxgb/ulp/tom/cxgb_tcp_subr.c 2007/12/17 08:22:48 +++ dev/cxgb/ulp/tom/cxgb_tcp_subr.c 2008/01/06 23:09:29 @@ -211,7 +211,7 @@ struct socket *so = tp->t_inpcb->inp_socket; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); if (TCPS_HAVERCVDSYN(tp->t_state)) { tp->t_state = TCPS_CLOSED; @@ -236,7 +236,7 @@ struct socket *so; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (tp->t_state == TCPS_LISTEN) tcp_gen_listen_close(tp); @@ -249,7 +249,7 @@ KASSERT(so->so_state & SS_PROTOREF, ("tcp_close: !SS_PROTOREF")); inp->inp_vflag &= ~INP_SOCKREF; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); ACCEPT_LOCK(); SOCK_LOCK(so); so->so_state &= ~SS_PROTOREF; @@ -273,7 +273,7 @@ struct tcpcb *tp; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if ((inp->inp_vflag & INP_TIMEWAIT) || (inp->inp_vflag & INP_DROPPED)) @@ -362,7 +362,7 @@ inp = in_pcblookup_hash(&tcbinfo, faddr, th->th_dport, ip->ip_src, th->th_sport, 0, NULL); if (inp != NULL) { - INP_LOCK(inp); + INP_WLOCK(inp); if (!(inp->inp_vflag & INP_TIMEWAIT) && !(inp->inp_vflag & INP_DROPPED) && !(inp->inp_socket == NULL)) { @@ -411,7 +411,7 @@ } } if (inp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else { inc.inc_fport = th->th_dport; inc.inc_lport = th->th_sport; @@ -563,7 +563,7 @@ struct tcpcb *tp; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if ((inp->inp_vflag & INP_TIMEWAIT) || (inp->inp_vflag & INP_DROPPED)) @@ -661,7 +661,7 @@ break; } if (inp != NULL) { - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & INP_TIMEWAIT) { /* * XXXRW: There currently exists a state where an @@ -673,15 +673,15 @@ if (tw != NULL) tcp_twclose(tw, 0); else - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else if (!(inp->inp_vflag & INP_DROPPED) && !(inp->inp_socket->so_options & SO_ACCEPTCONN)) { tp = intotcpcb(inp); tp = cxgb_tcp_drop(tp, ECONNABORTED); if (tp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else error = ESRCH; INP_INFO_WUNLOCK(&tcbinfo); --- dev/cxgb/ulp/tom/cxgb_tcp_usrreq.c 2007/12/17 08:22:48 +++ dev/cxgb/ulp/tom/cxgb_tcp_usrreq.c 2008/01/06 23:09:29 @@ -161,7 +161,7 @@ #endif INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp")); KASSERT(inp->inp_socket == so, ("tcp_detach: inp_socket != so")); @@ -254,7 +254,7 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL")); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_detach: inp_socket == NULL")); tcp_detach(so, inp); @@ -287,7 +287,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -327,7 +327,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -373,7 +373,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -410,7 +410,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -470,7 +470,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -513,7 +513,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -573,7 +573,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -608,7 +608,7 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNABORTED; goto out; @@ -650,7 +650,7 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNABORTED; goto out; @@ -699,7 +699,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -731,7 +731,7 @@ TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_rcvd: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -781,7 +781,7 @@ } inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { if (control) m_freem(control); @@ -920,7 +920,7 @@ KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL")); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_abort: inp_socket == NULL")); @@ -958,7 +958,7 @@ KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL")); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_close: inp_socket == NULL")); @@ -996,7 +996,7 @@ TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -1087,7 +1087,7 @@ int error; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (inp->inp_lport == 0) { error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); @@ -1142,7 +1142,7 @@ int error; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (inp->inp_lport == 0) { error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); @@ -1281,7 +1281,7 @@ struct socket *so = inp->inp_socket; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); /* * Neither tcp_close() nor tcp_drop() should return NULL, as the @@ -1319,7 +1319,7 @@ { INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); switch (tp->t_state) { case TCPS_LISTEN: --- dev/cxgb/ulp/tom/cxgb_tom.c 2007/12/17 08:22:48 +++ 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); --- kern/subr_witness.c 2007/12/25 17:56:52 +++ kern/subr_witness.c 2008/01/06 23:42:45 @@ -313,7 +313,7 @@ /* * Multicast - protocol locks before interface locks, after UDP locks. */ - { "udpinp", &lock_class_mtx_sleep }, + { "udpinp", &lock_class_rw }, { "in_multi_mtx", &lock_class_mtx_sleep }, { "igmp_mtx", &lock_class_mtx_sleep }, { "if_addr_mtx", &lock_class_mtx_sleep }, @@ -327,15 +327,15 @@ /* * UDP/IP */ - { "udp", &lock_class_mtx_sleep }, - { "udpinp", &lock_class_mtx_sleep }, + { "udp", &lock_class_rw }, + { "udpinp", &lock_class_rw }, { "so_snd", &lock_class_mtx_sleep }, { NULL, NULL }, /* * TCP/IP */ - { "tcp", &lock_class_mtx_sleep }, - { "tcpinp", &lock_class_mtx_sleep }, + { "tcp", &lock_class_rw }, + { "tcpinp", &lock_class_rw }, { "so_snd", &lock_class_mtx_sleep }, { NULL, NULL }, /* --- netinet/in_mcast.c 2007/08/06 22:20:57 +++ netinet/in_mcast.c 2008/01/06 23:09:29 @@ -651,7 +651,7 @@ } out_locked: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -667,11 +667,11 @@ struct in_mfilter *imfp; size_t idx; - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_moptions != NULL) return (inp->inp_moptions); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); imo = (struct ip_moptions *)malloc(sizeof(*imo), M_IPMOPTS, M_WAITOK); @@ -698,7 +698,7 @@ } imo->imo_mfilters = imfp; - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_moptions != NULL) { free(imfp, M_IPMSOURCE); free(immp, M_IPMOPTS); @@ -762,12 +762,12 @@ int error; size_t idx; - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); imo = inp->inp_moptions; KASSERT(imo != NULL, ("%s: null ip_moptions", __func__)); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); error = sooptcopyin(sopt, &msfr, sizeof(struct __msfilterreq), sizeof(struct __msfilterreq)); @@ -781,7 +781,7 @@ if (ifp == NULL) return (EINVAL); - INP_LOCK(inp); + INP_WLOCK(inp); /* * Lookup group on the socket. @@ -789,7 +789,7 @@ gsa = (sockunion_t *)&msfr.msfr_group; idx = imo_match_group(imo, ifp, &gsa->sa); if (idx == -1 || imo->imo_mfilters == NULL) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (EADDRNOTAVAIL); } @@ -826,7 +826,7 @@ } } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (tss != NULL) { error = copyout(tss, msfr.msfr_srcs, @@ -855,7 +855,7 @@ int error, optval; u_char coptval; - INP_LOCK(inp); + INP_WLOCK(inp); imo = inp->inp_moptions; /* * If socket is neither of type SOCK_RAW or SOCK_DGRAM, @@ -864,7 +864,7 @@ if (inp->inp_socket->so_proto->pr_protocol == IPPROTO_DIVERT || (inp->inp_socket->so_proto->pr_type != SOCK_RAW && inp->inp_socket->so_proto->pr_type != SOCK_DGRAM)) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (EOPNOTSUPP); } @@ -875,7 +875,7 @@ optval = imo->imo_multicast_vif; else optval = -1; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof(int)); break; @@ -894,7 +894,7 @@ } } } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) { error = sooptcopyout(sopt, &mreqn, sizeof(struct ip_mreqn)); @@ -909,7 +909,7 @@ optval = coptval = IP_DEFAULT_MULTICAST_TTL; else optval = coptval = imo->imo_multicast_ttl; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (sopt->sopt_valsize == sizeof(u_char)) error = sooptcopyout(sopt, &coptval, sizeof(u_char)); else @@ -921,7 +921,7 @@ optval = coptval = IP_DEFAULT_MULTICAST_LOOP; else optval = coptval = imo->imo_multicast_loop; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (sopt->sopt_valsize == sizeof(u_char)) error = sooptcopyout(sopt, &coptval, sizeof(u_char)); else @@ -931,14 +931,14 @@ case IP_MSFILTER: if (imo == NULL) { error = EADDRNOTAVAIL; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else { error = inp_get_source_filters(inp, sopt); } break; default: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); error = ENOPROTOOPT; break; } @@ -1192,14 +1192,14 @@ * to prevent a lock order reversal. */ --imo->imo_num_memberships; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); in_delmulti(inm); return (error); } } out_locked: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -1382,7 +1382,7 @@ imo->imo_num_memberships--; out_locked: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -1454,7 +1454,7 @@ imo = inp_findmoptions(inp); imo->imo_multicast_ifp = ifp; imo->imo_multicast_addr.s_addr = INADDR_ANY; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (0); } @@ -1545,7 +1545,7 @@ * in order to satisfy a malloc request. * We will re-take it before changing socket state. */ - INP_UNLOCK(inp); + INP_WUNLOCK(inp); #ifdef DIAGNOSTIC if (bootverbose) { printf("%s: loading %lu source list entries\n", @@ -1646,7 +1646,7 @@ * Re-take the inp lock; we are changing socket state. */ pkss = kss; - INP_LOCK(inp); + INP_WLOCK(inp); for (i = 0; i < msfr.msfr_nsrcs; i++, pkss++) { memcpy(&(pnims[i]->ims_addr), pkss, sizeof(struct sockaddr_storage)); @@ -1661,11 +1661,11 @@ /* * Update the filter mode on the socket before releasing the inpcb. */ - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); imf->imf_fmode = msfr.msfr_fmode; out_locked: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -1716,7 +1716,7 @@ } imo = inp_findmoptions(inp); imo->imo_multicast_vif = vifi; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); break; } @@ -1753,7 +1753,7 @@ } imo = inp_findmoptions(inp); imo->imo_multicast_ttl = ttl; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); break; } @@ -1782,7 +1782,7 @@ } imo = inp_findmoptions(inp); imo->imo_multicast_loop = !!loop; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); break; } --- netinet/in_pcb.c 2007/12/22 10:12:29 +++ netinet/in_pcb.c 2008/01/06 23:09:29 @@ -178,6 +178,9 @@ struct inpcb *inp; int error; + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(pcbinfo); error = 0; inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT); @@ -218,7 +221,7 @@ if (ip6_auto_flowlabel) inp->inp_flags |= IN6P_AUTOFLOWLABEL; #endif - INP_LOCK(inp); + INP_WLOCK(inp); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; #if defined(IPSEC) || defined(MAC) @@ -234,8 +237,11 @@ { int anonport, error; + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY) return (EINVAL); @@ -278,7 +284,10 @@ int error, prison = 0; int dorandom; - INP_INFO_WLOCK_ASSERT(pcbinfo); + /* + * XXXRW: lock assert OK. + */ + INP_INFO_LOCK_ASSERT(pcbinfo); INP_LOCK_ASSERT(inp); if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */ @@ -502,8 +511,11 @@ in_addr_t laddr, faddr; int anonport, error; + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); lport = inp->inp_lport; laddr = inp->inp_laddr.s_addr; @@ -565,7 +577,10 @@ u_short lport, fport; int error; - INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); + /* + * XXXRW: lock assert OK. + */ + INP_INFO_LOCK_ASSERT(inp->inp_pcbinfo); INP_LOCK_ASSERT(inp); if (oinpp != NULL) @@ -684,8 +699,11 @@ in_pcbdisconnect(struct inpcb *inp) { + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); inp->inp_faddr.s_addr = INADDR_ANY; inp->inp_fport = 0; @@ -714,8 +732,12 @@ struct inpcbinfo *ipi = inp->inp_pcbinfo; KASSERT(inp->inp_socket == NULL, ("in_pcbfree: inp_socket != NULL")); + + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(ipi); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); #ifdef IPSEC ipsec4_delete_pcbpolicy(inp); @@ -731,7 +753,7 @@ #ifdef MAC mac_inpcb_destroy(inp); #endif - INP_UNLOCK(inp); + INP_WUNLOCK(inp); uma_zfree(ipi->ipi_zone, inp); } @@ -745,8 +767,11 @@ in_pcbdrop(struct inpcb *inp) { + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); inp->inp_vflag |= INP_DROPPED; if (inp->inp_lport) { @@ -790,10 +815,10 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("in_getsockaddr: inp == NULL")); - INP_LOCK(inp); + INP_RLOCK(inp); port = inp->inp_lport; addr = inp->inp_laddr; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); *nam = in_sockaddr(port, &addr); return 0; @@ -809,10 +834,10 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("in_getpeeraddr: inp == NULL")); - INP_LOCK(inp); + INP_RLOCK(inp); port = inp->inp_fport; addr = inp->inp_faddr; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); *nam = in_sockaddr(port, &addr); return 0; @@ -825,24 +850,28 @@ struct inpcb *inp, *ninp; struct inpcbhead *head; + /* + * XXXRW: wlock assert OK, although could be an rlock for non-TCP + * cases. + */ INP_INFO_WLOCK(pcbinfo); head = pcbinfo->ipi_listhead; for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { - INP_LOCK(inp); + INP_WLOCK(inp); ninp = LIST_NEXT(inp, inp_list); #ifdef INET6 if ((inp->inp_vflag & INP_IPV4) == 0) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); continue; } #endif if (inp->inp_faddr.s_addr != faddr.s_addr || inp->inp_socket == NULL) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); continue; } if ((*notify)(inp, errno)) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } INP_INFO_WUNLOCK(pcbinfo); } @@ -854,9 +883,12 @@ 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); + INP_WLOCK(inp); imo = inp->inp_moptions; if ((inp->inp_vflag & INP_IPV4) && imo != NULL) { @@ -882,7 +914,7 @@ } imo->imo_num_memberships -= gap; } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } INP_INFO_RUNLOCK(pcbinfo); } @@ -904,7 +936,10 @@ int wildcard; u_short lport = lport_arg; - INP_INFO_WLOCK_ASSERT(pcbinfo); + /* + * XXXRW: lock assert OK. + */ + INP_INFO_LOCK_ASSERT(pcbinfo); if (!wild_okay) { struct inpcbhead *head; @@ -1011,7 +1046,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. @@ -1085,8 +1123,11 @@ struct inpcbport *phd; u_int32_t hashkey_faddr; + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); #ifdef INET6 if (inp->inp_vflag & INP_IPV6) @@ -1139,8 +1180,11 @@ struct inpcbhead *head; u_int32_t hashkey_faddr; + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); #ifdef INET6 if (inp->inp_vflag & INP_IPV6) @@ -1164,8 +1208,11 @@ { struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; + /* + * XXXRW: wlock assert OK. + */ INP_INFO_WLOCK_ASSERT(pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; if (inp->inp_lport) { @@ -1195,11 +1242,11 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("in_pcbsosetlabel: so->so_pcb == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); SOCK_LOCK(so); mac_inpcb_sosetlabel(so, inp); SOCK_UNLOCK(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); #endif } --- netinet/in_pcb.h 2007/12/07 01:46:38 +++ netinet/in_pcb.h 2008/01/06 23:09:29 @@ -36,9 +36,14 @@ #include #include #include +#include #include +#ifdef _KERNEL +#include /* 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; @@ -171,7 +176,7 @@ struct inpcbport *inp_phd; /* head of this list */ #define inp_zero_size offsetof(struct inpcb, inp_gencnt) inp_gen_t inp_gencnt; /* generation count of this instance */ - struct mtx inp_mtx; + struct rwlock inp_lock; #define in6p_faddr inp_inc.inc6_faddr #define in6p_laddr inp_inc.inc6_laddr @@ -264,7 +269,7 @@ * or freed. */ u_quad_t ipi_gencnt; - struct mtx ipi_mtx; + struct rwlock ipi_lock; /* * vimage 1 @@ -273,24 +278,33 @@ void *ipi_pspare[2]; }; +/* + * XXXRW: rwlock(9) doesn't support classes, only names, unlike mutexes, so + * we use the class as the name. What should we be doing? + */ #define INP_LOCK_INIT(inp, d, t) \ - mtx_init(&(inp)->inp_mtx, (d), (t), MTX_DEF | MTX_RECURSE | MTX_DUPOK) -#define INP_LOCK_DESTROY(inp) mtx_destroy(&(inp)->inp_mtx) -#define INP_LOCK(inp) mtx_lock(&(inp)->inp_mtx) -#define INP_UNLOCK(inp) mtx_unlock(&(inp)->inp_mtx) -#define INP_LOCK_ASSERT(inp) mtx_assert(&(inp)->inp_mtx, MA_OWNED) -#define INP_UNLOCK_ASSERT(inp) mtx_assert(&(inp)->inp_mtx, MA_NOTOWNED) + rw_init_flags(&(inp)->inp_lock, (t), RW_RECURSE | RW_DUPOK) +#define INP_LOCK_DESTROY(inp) rw_destroy(&(inp)->inp_lock) +#define INP_RLOCK(inp) rw_rlock(&(inp)->inp_lock) +#define INP_WLOCK(inp) rw_wlock(&(inp)->inp_lock) +#define INP_RUNLOCK(inp) rw_runlock(&(inp)->inp_lock) +#define INP_WUNLOCK(inp) rw_wunlock(&(inp)->inp_lock) +#define INP_LOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_LOCKED) +#define INP_RLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_RLOCKED) +#define INP_WLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_WLOCKED) +#define INP_UNLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_UNLOCKED) #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)) --- netinet/ip_divert.c 2007/10/24 19:06:35 +++ netinet/ip_divert.c 2008/01/06 23:09:29 @@ -266,9 +266,12 @@ /* 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); + INP_RLOCK(inp); /* XXX why does only one socket match? */ if (inp->inp_lport == nport) { sa = inp->inp_socket; @@ -280,10 +283,10 @@ sa = NULL; /* force mbuf reclaim below */ } else sorwakeup_locked(sa); - INP_UNLOCK(inp); + INP_RUNLOCK(inp); break; } - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } INP_INFO_RUNLOCK(&divcbinfo); if (sa == NULL) { @@ -356,7 +359,7 @@ dt->info |= IP_FW_DIVERT_OUTPUT_FLAG; INP_INFO_WLOCK(&divcbinfo); inp = sotoinpcb(so); - INP_LOCK(inp); + INP_RLOCK(inp); /* * Don't allow both user specified and setsockopt options, * and don't allow packet length sizes that will crash @@ -364,7 +367,7 @@ if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) || ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { error = EINVAL; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_WUNLOCK(&divcbinfo); m_freem(m); } else { @@ -405,7 +408,7 @@ if (options == NULL) error = ENOBUFS; } - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_WUNLOCK(&divcbinfo); if (error == ENOBUFS) { m_freem(m); @@ -480,7 +483,7 @@ inp->inp_ip_p = proto; inp->inp_vflag |= INP_IPV4; inp->inp_flags |= INP_HDRINCL; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return 0; } @@ -492,7 +495,7 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("div_detach: inp == NULL")); INP_INFO_WLOCK(&divcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); in_pcbdetach(inp); in_pcbfree(inp); INP_INFO_WUNLOCK(&divcbinfo); @@ -517,9 +520,9 @@ return EAFNOSUPPORT; ((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY; INP_INFO_WLOCK(&divcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); error = in_pcbbind(inp, nam, td->td_ucred); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&divcbinfo); return error; } @@ -531,9 +534,10 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("div_shutdown: inp == NULL")); - INP_LOCK(inp); + /* XXXRW: Perhaps INP_RLOCK? */ + INP_WLOCK(inp); socantsendmore(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return 0; } @@ -590,6 +594,9 @@ /* * OK, now we're committed to doing something. */ + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(&divcbinfo); gencnt = divcbinfo.ipi_gencnt; n = divcbinfo.ipi_count; @@ -615,11 +622,11 @@ INP_INFO_RLOCK(&divcbinfo); for (inp = LIST_FIRST(divcbinfo.ipi_listhead), i = 0; inp && i < n; inp = LIST_NEXT(inp, inp_list)) { - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt && cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) inp_list[i++] = inp; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } INP_INFO_RUNLOCK(&divcbinfo); n = i; @@ -627,7 +634,7 @@ error = 0; for (i = 0; i < n; i++) { inp = inp_list[i]; - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt) { struct xinpcb xi; bzero(&xi, sizeof(xi)); @@ -636,10 +643,10 @@ bcopy(inp, &xi.xi_inp, sizeof *inp); if (inp->inp_socket) sotoxsocket(inp->inp_socket, &xi.xi_socket); - INP_UNLOCK(inp); + INP_RUNLOCK(inp); error = SYSCTL_OUT(req, &xi, sizeof xi); } else - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } if (!error) { /* --- netinet/ip_fw2.c 2007/12/09 15:35:46 +++ netinet/ip_fw2.c 2008/01/06 23:09:29 @@ -2013,6 +2013,9 @@ return 0; match = 0; if (*lookup == 0) { + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(pi); pcb = (oif) ? in_pcblookup_hash(pi, @@ -2024,12 +2027,12 @@ dst_ip, htons(dst_port), wildcard, NULL); if (pcb != NULL) { - INP_LOCK(pcb); + INP_RLOCK(pcb); if (pcb->inp_socket != NULL) { fill_ugid_cache(pcb, ugp); *lookup = 1; } - INP_UNLOCK(pcb); + INP_RUNLOCK(pcb); } INP_INFO_RUNLOCK(pi); if (*lookup == 0) { --- netinet/ip_options.c 2007/10/24 19:06:35 +++ netinet/ip_options.c 2008/01/06 23:09:29 @@ -589,7 +589,7 @@ struct mbuf **pcbopt; u_char opt; - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); pcbopt = &inp->inp_options; --- netinet/ip_output.c 2007/10/24 19:06:35 +++ netinet/ip_output.c 2008/01/06 23:09:29 @@ -415,6 +415,11 @@ sendit: #ifdef IPSEC + /* + * XXXRW: Check that it's OK with IPSEC that we may be passing down + * a read lock on inpcb. Is IPSEC using the inp lock to protect its + * own data? + */ switch(ip_ipsec_output(&m, inp, &flags, &error, &ro, &iproute, &dst, &ia, &ifp)) { case 1: goto bad; @@ -433,6 +438,10 @@ if (!PFIL_HOOKED(&inet_pfil_hook)) goto passout; + /* + * XXXRW: Confirm that pfil users aren't piggy-backing on the inpcb + * lock to protect data. + */ /* Run through list of hooks for output packets. */ odst.s_addr = ip->ip_dst.s_addr; error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, inp); @@ -833,9 +842,9 @@ m_free(m); break; } - INP_LOCK(inp); + INP_WLOCK(inp); error = ip_pcbopts(inp, sopt->sopt_name, m); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -872,12 +881,12 @@ break; #define OPTSET(bit) do { \ - INP_LOCK(inp); \ + INP_WLOCK(inp); \ if (optval) \ inp->inp_flags |= bit; \ else \ inp->inp_flags &= ~bit; \ - INP_UNLOCK(inp); \ + INP_WUNLOCK(inp); \ } while (0) case IP_RECVOPTS: @@ -944,7 +953,7 @@ if (error) break; - INP_LOCK(inp); + INP_WLOCK(inp); switch (optval) { case IP_PORTRANGE_DEFAULT: inp->inp_flags &= ~(INP_LOWPORT); @@ -965,7 +974,7 @@ error = EINVAL; break; } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); break; #ifdef IPSEC --- netinet/raw_ip.c 2007/10/24 19:06:35 +++ netinet/raw_ip.c 2008/01/06 23:09:29 @@ -157,6 +157,9 @@ INP_LOCK_ASSERT(last); + /* + * XXXRW: Check that IPSEC doesn't mind a read-locked inpcb. + */ #ifdef IPSEC /* check AH/ESP integrity. */ if (ipsec4_in_reject(n, last)) { @@ -205,14 +208,17 @@ int proto = ip->ip_p; struct inpcb *inp, *last; + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(&ripcbinfo); ripsrc.sin_addr = ip->ip_src; last = NULL; LIST_FOREACH(inp, &ripcb, inp_list) { - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_ip_p && inp->inp_ip_p != proto) { docontinue: - INP_UNLOCK(inp); + INP_RUNLOCK(inp); continue; } #ifdef INET6 @@ -236,14 +242,14 @@ if (n != NULL) (void) raw_append(last, ip, n); /* XXX count dropped packet */ - INP_UNLOCK(last); + INP_RUNLOCK(last); } last = inp; } if (last != NULL) { if (raw_append(last, ip, m) != 0) ipstat.ips_delivered--; - INP_UNLOCK(last); + INP_RUNLOCK(last); } else { m_freem(m); ipstat.ips_noproto++; @@ -278,7 +284,7 @@ if (m == NULL) return(ENOBUFS); - INP_LOCK(inp); + INP_RLOCK(inp); ip = mtod(m, struct ip *); ip->ip_tos = inp->inp_ip_tos; if (inp->inp_flags & INP_DONTFRAG) @@ -299,12 +305,12 @@ m_freem(m); return(EMSGSIZE); } - INP_LOCK(inp); + INP_RLOCK(inp); ip = mtod(m, struct ip *); if (jailed(inp->inp_socket->so_cred)) { if (ip->ip_src.s_addr != htonl(prison_getip(inp->inp_socket->so_cred))) { - INP_UNLOCK(inp); + INP_RUNLOCK(inp); m_freem(m); return (EPERM); } @@ -315,7 +321,7 @@ && inp->inp_options) || (ip->ip_len > m->m_pkthdr.len) || (ip->ip_len < (ip->ip_hl << 2))) { - INP_UNLOCK(inp); + INP_RUNLOCK(inp); m_freem(m); return EINVAL; } @@ -335,7 +341,7 @@ error = ip_output(m, inp->inp_options, NULL, flags, inp->inp_moptions, inp); - INP_UNLOCK(inp); + INP_RUNLOCK(inp); return error; } @@ -621,7 +627,7 @@ inp->inp_vflag |= INP_IPV4; inp->inp_ip_p = proto; inp->inp_ip_ttl = ip_defttl; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return 0; } @@ -636,7 +642,7 @@ ("rip_detach: not closed")); INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (so == ip_mrouter && ip_mrouter_done) ip_mrouter_done(); if (ip_rsvp_force_done) @@ -652,7 +658,7 @@ rip_dodisconnect(struct socket *so, struct inpcb *inp) { - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); inp->inp_faddr.s_addr = INADDR_ANY; SOCK_LOCK(so); @@ -669,9 +675,9 @@ KASSERT(inp != NULL, ("rip_abort: inp == NULL")); INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); rip_dodisconnect(so, inp); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); } @@ -684,9 +690,9 @@ KASSERT(inp != NULL, ("rip_close: inp == NULL")); INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); rip_dodisconnect(so, inp); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); } @@ -701,9 +707,9 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("rip_disconnect: inp == NULL")); INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); rip_dodisconnect(so, inp); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); return (0); } @@ -734,9 +740,9 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("rip_bind: inp == NULL")); INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); inp->inp_laddr = addr->sin_addr; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); return 0; } @@ -757,10 +763,10 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("rip_connect: inp == NULL")); INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); inp->inp_faddr = addr->sin_addr; soisconnected(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); return 0; } @@ -770,11 +776,14 @@ { struct inpcb *inp; + /* + * XXXRW: Actually, this could probably be a read lock... + */ inp = sotoinpcb(so); KASSERT(inp != NULL, ("rip_shutdown: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); socantsendmore(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return 0; } @@ -831,6 +840,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,17 +859,20 @@ 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)) { - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt && cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) { /* XXX held references? */ inp_list[i++] = inp; } - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } INP_INFO_RUNLOCK(&ripcbinfo); n = i; @@ -865,7 +880,7 @@ error = 0; for (i = 0; i < n; i++) { inp = inp_list[i]; - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt) { struct xinpcb xi; bzero(&xi, sizeof(xi)); @@ -874,10 +889,10 @@ bcopy(inp, &xi.xi_inp, sizeof *inp); if (inp->inp_socket) sotoxsocket(inp->inp_socket, &xi.xi_socket); - INP_UNLOCK(inp); + INP_RUNLOCK(inp); error = SYSCTL_OUT(req, &xi, sizeof xi); } else - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } if (!error) { /* @@ -887,6 +902,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; --- netinet/tcp_input.c 2007/10/24 19:06:35 +++ netinet/tcp_input.c 2008/01/06 23:09:29 @@ -476,7 +476,7 @@ rstreason = BANDLIM_RST_CLOSEDPORT; goto dropwithreset; } - INP_LOCK(inp); + INP_WLOCK(inp); #ifdef IPSEC #ifdef INET6 @@ -533,7 +533,7 @@ } #ifdef MAC - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (mac_inpcb_check_deliver(inp, m)) goto dropunlock; #endif @@ -631,9 +631,9 @@ * Unlock the listen socket, lock the newly * created socket and update the tp variable. */ - INP_UNLOCK(inp); /* listen socket */ + INP_WUNLOCK(inp); /* listen socket */ inp = sotoinpcb(so); - INP_LOCK(inp); /* new connection */ + INP_WLOCK(inp); /* new connection */ tp = intotcpcb(inp); KASSERT(tp->t_state == TCPS_SYN_RECEIVED, ("%s: ", __func__)); @@ -853,7 +853,7 @@ dropunlock: INP_INFO_WLOCK_ASSERT(&tcbinfo); if (inp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); drop: INP_INFO_UNLOCK_ASSERT(&tcbinfo); @@ -886,7 +886,7 @@ thflags = th->th_flags; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", __func__)); KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", @@ -1330,7 +1330,7 @@ KASSERT(headlocked, ("%s: trimthenstep6: head not locked", __func__)); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* * Advance th->th_seq to correspond to first data byte. @@ -1938,7 +1938,7 @@ process_ACK: KASSERT(headlocked, ("%s: process_ACK: head not locked", __func__)); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); acked = th->th_ack - tp->snd_una; tcpstat.tcps_rcvackpack++; @@ -2121,7 +2121,7 @@ step6: KASSERT(headlocked, ("%s: step6: head not locked", __func__)); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* * Update window information. @@ -2207,7 +2207,7 @@ } dodata: /* XXX */ KASSERT(headlocked, ("%s: dodata: head not locked", __func__)); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* * Process the segment text, merging it into the TCP sequencing queue, @@ -2350,12 +2350,12 @@ KASSERT(headlocked == 0, ("%s: check_delack: head locked", __func__)); INP_INFO_UNLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); if (tp->t_flags & TF_DELACK) { tp->t_flags &= ~TF_DELACK; tcp_timer_activate(tp, TT_DELACK, tcp_delacktime); } - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); return; dropafterack: @@ -2390,7 +2390,7 @@ INP_INFO_WUNLOCK(&tcbinfo); tp->t_flags |= TF_ACKNOW; (void) tcp_output(tp); - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); m_freem(m); return; @@ -2400,7 +2400,7 @@ tcp_dropwithreset(m, th, tp, tlen, rstreason); if (tp != NULL) - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); if (headlocked) INP_INFO_WUNLOCK(&tcbinfo); return; @@ -2415,7 +2415,7 @@ &tcp_savetcp, 0); #endif if (tp != NULL) - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); if (headlocked) INP_INFO_WUNLOCK(&tcbinfo); m_freem(m); @@ -2609,7 +2609,7 @@ { int delta; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); tcpstat.tcps_rttupdated++; tp->t_rttupdated++; --- netinet/tcp_output.c 2007/11/30 23:51:38 +++ netinet/tcp_output.c 2008/01/06 23:09:29 @@ -152,7 +152,7 @@ isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0; #endif - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* * Determine length of data that should be transmitted, --- netinet/tcp_reass.c 2007/10/07 20:49:19 +++ netinet/tcp_reass.c 2008/01/06 23:09:29 @@ -131,7 +131,7 @@ struct socket *so = tp->t_inpcb->inp_socket; int flags; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* * XXX: tcp_reass() is rather inefficient with its data structures --- netinet/tcp_sack.c 2007/05/11 11:26:58 +++ netinet/tcp_sack.c 2008/01/06 23:09:29 @@ -160,7 +160,7 @@ struct sackblk head_blk, saved_blks[MAX_SACK_BLKS]; int num_head, num_saved, i; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* Check arguments. */ KASSERT(SEQ_LT(rcv_start, rcv_end), ("rcv_start < rcv_end")); @@ -240,7 +240,7 @@ { int i; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); tp->rcv_numsacks = 0; for (i = 0; i < MAX_SACK_BLKS; i++) tp->sackblks[i].start = tp->sackblks[i].end=0; @@ -347,7 +347,7 @@ struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1], *sblkp; int i, j, num_sack_blks; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); num_sack_blks = 0; /* @@ -544,7 +544,7 @@ { struct sackhole *q; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); while ((q = TAILQ_FIRST(&tp->snd_holes)) != NULL) tcp_sackhole_remove(tp, q); tp->sackhint.sack_bytes_rexmit = 0; @@ -567,7 +567,7 @@ { int num_segs = 1; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; /* Send one or 2 segments based on how much new data was acked. */ @@ -591,7 +591,7 @@ { struct sackhole *p; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); *sack_bytes_rexmt = 0; TAILQ_FOREACH(p, &tp->snd_holes, scblink) { if (SEQ_LT(p->rxmit, p->end)) { @@ -629,7 +629,7 @@ { struct sackhole *hole = NULL; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); *sack_bytes_rexmt = tp->sackhint.sack_bytes_rexmit; hole = tp->sackhint.nexthole; if (hole == NULL || SEQ_LT(hole->rxmit, hole->end)) @@ -654,7 +654,7 @@ { struct sackhole *p, *cur = TAILQ_FIRST(&tp->snd_holes); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); if (cur == NULL) return; /* No holes */ if (SEQ_GEQ(tp->snd_nxt, tp->snd_fack)) --- netinet/tcp_subr.c 2007/12/18 23:02:41 +++ netinet/tcp_subr.c 2008/01/06 23:09:29 @@ -332,6 +332,9 @@ { struct tcphdr *th = (struct tcphdr *)tcp_ptr; + /* + * XXXRW: A read lock here is fine, but that won't ever happen. + */ INP_LOCK_ASSERT(inp); #ifdef INET6 @@ -438,7 +441,7 @@ if (tp != NULL) { inp = tp->t_inpcb; KASSERT(inp != NULL, ("tcp control block w/o inpcb")); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); } else inp = NULL; @@ -648,7 +651,7 @@ struct socket *so = tp->t_inpcb->inp_socket; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); if (TCPS_HAVERCVDSYN(tp->t_state)) { tp->t_state = TCPS_CLOSED; @@ -672,7 +675,7 @@ int isipv6 = (inp->inp_vflag & INP_IPV6) != 0; #endif /* INET6 */ - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); /* * Make sure that all of our timers are stopped before we @@ -770,7 +773,7 @@ struct socket *so; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); /* Notify any offload devices of listener close */ if (tp->t_state == TCPS_LISTEN) @@ -784,7 +787,7 @@ KASSERT(so->so_state & SS_PROTOREF, ("tcp_close: !SS_PROTOREF")); inp->inp_vflag &= ~INP_SOCKREF; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); ACCEPT_LOCK(); SOCK_LOCK(so); so->so_state &= ~SS_PROTOREF; @@ -811,11 +814,14 @@ * 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) continue; - INP_LOCK(inpb); + INP_WLOCK(inpb); if ((tcpb = intotcpcb(inpb)) != NULL) { while ((te = LIST_FIRST(&tcpb->t_segq)) != NULL) { @@ -827,7 +833,7 @@ } tcp_clean_sackreport(tcpb); } - INP_UNLOCK(inpb); + INP_WUNLOCK(inpb); } INP_INFO_RUNLOCK(&tcbinfo); } @@ -847,7 +853,7 @@ struct tcpcb *tp; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if ((inp->inp_vflag & INP_TIMEWAIT) || (inp->inp_vflag & INP_DROPPED)) @@ -911,6 +917,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,10 +948,13 @@ 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)) { - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt) { /* * XXX: This use of cr_cansee(), introduced with @@ -961,7 +973,7 @@ if (error == 0) inp_list[i++] = inp; } - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } INP_INFO_RUNLOCK(&tcbinfo); n = i; @@ -969,7 +981,7 @@ error = 0; for (i = 0; i < n; i++) { inp = inp_list[i]; - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt) { struct xtcpcb xt; void *inp_ppcb; @@ -993,10 +1005,10 @@ xt.xt_socket.xso_protocol = IPPROTO_TCP; } xt.xt_inp.inp_gencnt = inp->inp_gencnt; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); error = SYSCTL_OUT(req, &xt, sizeof xt); } else - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } if (!error) { @@ -1007,6 +1019,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 +1050,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); @@ -1042,7 +1060,7 @@ error = ENOENT; goto outunlocked; } - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_socket == NULL) { error = ENOENT; goto out; @@ -1052,7 +1070,7 @@ goto out; cru2x(inp->inp_socket->so_cred, &xuc); out: - INP_UNLOCK(inp); + INP_RUNLOCK(inp); outunlocked: INP_INFO_RUNLOCK(&tcbinfo); if (error == 0) @@ -1090,6 +1108,9 @@ return (EINVAL); } + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(&tcbinfo); if (mapped == 1) inp = in_pcblookup_hash(&tcbinfo, @@ -1106,7 +1127,7 @@ error = ENOENT; goto outunlocked; } - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_socket == NULL) { error = ENOENT; goto out; @@ -1116,7 +1137,7 @@ goto out; cru2x(inp->inp_socket->so_cred, &xuc); out: - INP_UNLOCK(inp); + INP_RUNLOCK(inp); outunlocked: INP_INFO_RUNLOCK(&tcbinfo); if (error == 0) @@ -1181,7 +1202,7 @@ inp = in_pcblookup_hash(&tcbinfo, faddr, th->th_dport, ip->ip_src, th->th_sport, 0, NULL); if (inp != NULL) { - INP_LOCK(inp); + INP_WLOCK(inp); if (!(inp->inp_vflag & INP_TIMEWAIT) && !(inp->inp_vflag & INP_DROPPED) && !(inp->inp_socket == NULL)) { @@ -1230,7 +1251,7 @@ } } if (inp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else { inc.inc_fport = th->th_dport; inc.inc_lport = th->th_sport; @@ -1381,7 +1402,7 @@ u_int32_t md5_buffer[4]; tcp_seq new_isn; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); ISN_LOCK(); /* Seed if this is the first use, reseed if requested. */ @@ -1452,7 +1473,7 @@ struct tcpcb *tp; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if ((inp->inp_vflag & INP_TIMEWAIT) || (inp->inp_vflag & INP_DROPPED)) @@ -1487,7 +1508,7 @@ int isipv6; #endif /* INET6 */ - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if ((inp->inp_vflag & INP_TIMEWAIT) || (inp->inp_vflag & INP_DROPPED)) return (inp); @@ -1752,7 +1773,7 @@ u_long bwnd; int save_ticks; - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); /* * If inflight_enable is disabled in the middle of a tcp connection, @@ -2045,7 +2066,7 @@ break; } if (inp != NULL) { - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & INP_TIMEWAIT) { /* * XXXRW: There currently exists a state where an @@ -2057,15 +2078,15 @@ if (tw != NULL) tcp_twclose(tw, 0); else - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else if (!(inp->inp_vflag & INP_DROPPED) && !(inp->inp_socket->so_options & SO_ACCEPTCONN)) { tp = intotcpcb(inp); tp = tcp_drop(tp, ECONNABORTED); if (tp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else error = ESRCH; INP_INFO_WUNLOCK(&tcbinfo); --- netinet/tcp_syncache.c 2007/12/19 17:01:59 +++ netinet/tcp_syncache.c 2008/01/06 23:09:29 @@ -670,7 +670,7 @@ #endif inp = sotoinpcb(so); - INP_LOCK(inp); + INP_WLOCK(inp); /* Insert new socket into PCB hash list. */ inp->inp_inc.inc_isipv6 = sc->sc_inc.inc_isipv6; @@ -817,13 +817,13 @@ tp->snd_cwnd = tp->t_maxseg; tcp_timer_activate(tp, TT_KEEP, tcp_keepinit); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); tcpstat.tcps_accepts++; return (so); abort: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); abort2: if (so != NULL) soabort(so); @@ -987,7 +987,7 @@ struct syncache scs; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); /* listen socket */ + INP_WLOCK_ASSERT(inp); /* listen socket */ KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN, ("%s: unexpected tcp flags", __func__)); @@ -1014,13 +1014,13 @@ #ifdef MAC if (mac_syncache_init(&maclabel) != 0) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); goto done; } else mac_syncache_create(maclabel, inp); #endif - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); /* --- netinet/tcp_timer.c 2007/10/07 20:49:19 +++ netinet/tcp_timer.c 2008/01/06 23:09:29 @@ -152,6 +152,9 @@ struct tcpcb *tp = xtp; struct inpcb *inp; + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(&tcbinfo); inp = tp->t_inpcb; /* @@ -166,11 +169,11 @@ INP_INFO_RUNLOCK(&tcbinfo); return; } - INP_LOCK(inp); + INP_WLOCK(inp); INP_INFO_RUNLOCK(&tcbinfo); if ((inp->inp_vflag & INP_DROPPED) || callout_pending(&tp->t_timers->tt_delack) || !callout_active(&tp->t_timers->tt_delack)) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return; } callout_deactivate(&tp->t_timers->tt_delack); @@ -178,7 +181,7 @@ tp->t_flags |= TF_ACKNOW; tcpstat.tcps_delack++; (void) tcp_output(tp); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } void @@ -208,11 +211,11 @@ INP_INFO_WUNLOCK(&tcbinfo); return; } - INP_LOCK(inp); + INP_WLOCK(inp); tcp_free_sackholes(tp); if ((inp->inp_vflag & INP_DROPPED) || callout_pending(&tp->t_timers->tt_2msl) || !callout_active(&tp->t_timers->tt_2msl)) { - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); INP_INFO_WUNLOCK(&tcbinfo); return; } @@ -247,7 +250,7 @@ PRU_SLOWTIMO); #endif if (tp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); } @@ -276,10 +279,10 @@ INP_INFO_WUNLOCK(&tcbinfo); return; } - INP_LOCK(inp); + INP_WLOCK(inp); if ((inp->inp_vflag & INP_DROPPED) || callout_pending(&tp->t_timers->tt_keep) || !callout_active(&tp->t_timers->tt_keep)) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return; } @@ -324,7 +327,7 @@ tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0, PRU_SLOWTIMO); #endif - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return; @@ -338,7 +341,7 @@ PRU_SLOWTIMO); #endif if (tp != NULL) - INP_UNLOCK(tp->t_inpcb); + INP_WUNLOCK(tp->t_inpcb); INP_INFO_WUNLOCK(&tcbinfo); } @@ -366,10 +369,10 @@ INP_INFO_WUNLOCK(&tcbinfo); return; } - INP_LOCK(inp); + INP_WLOCK(inp); if ((inp->inp_vflag & INP_DROPPED) || callout_pending(&tp->t_timers->tt_persist) || !callout_active(&tp->t_timers->tt_persist)) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return; } @@ -404,7 +407,7 @@ tcp_trace(TA_USER, ostate, tp, NULL, NULL, PRU_SLOWTIMO); #endif if (tp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); } @@ -435,10 +438,10 @@ INP_INFO_WUNLOCK(&tcbinfo); return; } - INP_LOCK(inp); + INP_WLOCK(inp); if ((inp->inp_vflag & INP_DROPPED) || callout_pending(&tp->t_timers->tt_rexmt) || !callout_active(&tp->t_timers->tt_rexmt)) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return; } @@ -560,7 +563,7 @@ PRU_SLOWTIMO); #endif if (tp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (headlocked) INP_INFO_WUNLOCK(&tcbinfo); } --- netinet/tcp_timewait.c 2007/10/24 19:06:35 +++ netinet/tcp_timewait.c 2008/01/06 23:09:29 @@ -186,12 +186,12 @@ struct socket *so; INP_INFO_WLOCK_ASSERT(&tcbinfo); /* tcp_tw_2msl_reset(). */ - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (nolocaltimewait && in_localip(inp->inp_faddr)) { tp = tcp_close(tp); if (tp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return; } @@ -201,7 +201,7 @@ if (tw == NULL) { tp = tcp_close(tp); if (tp != NULL) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return; } } @@ -267,13 +267,13 @@ KASSERT(so->so_state & SS_PROTOREF, ("tcp_twstart: !SS_PROTOREF")); inp->inp_vflag &= ~INP_SOCKREF; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); ACCEPT_LOCK(); SOCK_LOCK(so); so->so_state &= ~SS_PROTOREF; sofree(so); } else - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } #if 0 @@ -328,7 +328,7 @@ /* tcbinfo lock required for tcp_twclose(), tcp_tw_2msl_reset(). */ INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); /* * XXXRW: Time wait state for inpcb has been recycled, but inpcb is @@ -441,11 +441,11 @@ tcp_respond(NULL, mtod(m, void *), th, m, seq, 0, TH_RST|TH_ACK); } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (0); drop: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); m_freem(m); return (0); } @@ -469,7 +469,7 @@ KASSERT((inp->inp_vflag & INP_TIMEWAIT), ("tcp_twclose: !timewait")); KASSERT(intotw(inp) == tw, ("tcp_twclose: inp_ppcb != tw")); INP_INFO_WLOCK_ASSERT(&tcbinfo); /* tcp_tw_2msl_stop(). */ - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); tw->tw_inpcb = NULL; tcp_tw_2msl_stop(tw); @@ -486,7 +486,7 @@ */ if (inp->inp_vflag & INP_SOCKREF) { inp->inp_vflag &= ~INP_SOCKREF; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); ACCEPT_LOCK(); SOCK_LOCK(so); KASSERT(so->so_state & SS_PROTOREF, @@ -499,7 +499,7 @@ * inpcb need to be left around to be handled by * tcp_usr_detach() later. */ - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } } else { #ifdef INET6 @@ -532,7 +532,7 @@ int isipv6 = inp->inp_inc.inc_isipv6; #endif - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); m = m_gethdr(M_DONTWAIT, MT_DATA); if (m == NULL) @@ -615,7 +615,7 @@ { INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(tw->tw_inpcb); + INP_WLOCK_ASSERT(tw->tw_inpcb); if (rearm) TAILQ_REMOVE(&twq_2msl, tw, tw_2msl); tw->tw_time = ticks + 2 * tcp_msl; @@ -640,7 +640,7 @@ tw = TAILQ_FIRST(&twq_2msl); if (tw == NULL || (!reuse && tw->tw_time > ticks)) break; - INP_LOCK(tw->tw_inpcb); + INP_WLOCK(tw->tw_inpcb); tcp_twclose(tw, reuse); if (reuse) return (tw); --- netinet/tcp_usrreq.c 2007/12/18 23:02:41 +++ netinet/tcp_usrreq.c 2008/01/06 23:09:29 @@ -160,7 +160,7 @@ #endif INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp")); KASSERT(inp->inp_socket == so, ("tcp_detach: inp_socket != so")); @@ -201,7 +201,7 @@ else #endif in_pcbdetach(inp); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } } else { /* @@ -253,7 +253,7 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL")); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_detach: inp_socket == NULL")); tcp_detach(so, inp); @@ -286,7 +286,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -296,7 +296,7 @@ error = in_pcbbind(inp, nam, td->td_ucred); out: TCPDEBUG2(PRU_BIND); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); @@ -326,7 +326,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -352,7 +352,7 @@ error = in6_pcbbind(inp, nam, td->td_ucred); out: TCPDEBUG2(PRU_BIND); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); } @@ -372,7 +372,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -392,7 +392,7 @@ out: TCPDEBUG2(PRU_LISTEN); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); } @@ -409,7 +409,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -432,7 +432,7 @@ out: TCPDEBUG2(PRU_LISTEN); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); } @@ -469,7 +469,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -481,7 +481,7 @@ error = tcp_output_connect(so, nam); out: TCPDEBUG2(PRU_CONNECT); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); } @@ -510,7 +510,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = EINVAL; goto out; @@ -542,7 +542,7 @@ out: TCPDEBUG2(PRU_CONNECT); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); } @@ -570,7 +570,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -580,7 +580,7 @@ tcp_disconnect(tp); out: TCPDEBUG2(PRU_DISCONNECT); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); } @@ -605,7 +605,7 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNABORTED; goto out; @@ -623,7 +623,7 @@ out: TCPDEBUG2(PRU_ACCEPT); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (error == 0) *nam = in_sockaddr(port, &addr); return error; @@ -647,7 +647,7 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNABORTED; goto out; @@ -671,7 +671,7 @@ out: TCPDEBUG2(PRU_ACCEPT); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (error == 0) { if (v4) *nam = in6_v4mapsin6_sockaddr(port, &addr); @@ -696,7 +696,7 @@ INP_INFO_WLOCK(&tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -709,7 +709,7 @@ out: TCPDEBUG2(PRU_SHUTDOWN); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (error); @@ -728,7 +728,7 @@ TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_rcvd: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -739,7 +739,7 @@ out: TCPDEBUG2(PRU_RCVD); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -778,7 +778,7 @@ } inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { if (control) m_freem(control); @@ -897,7 +897,7 @@ out: TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); if (headlocked) INP_INFO_WUNLOCK(&tcbinfo); return (error); @@ -917,7 +917,7 @@ KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL")); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_abort: inp_socket == NULL")); @@ -937,7 +937,7 @@ SOCK_UNLOCK(so); inp->inp_vflag |= INP_SOCKREF; } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); } @@ -955,7 +955,7 @@ KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL")); INP_INFO_WLOCK(&tcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_close: inp_socket == NULL")); @@ -976,7 +976,7 @@ SOCK_UNLOCK(so); inp->inp_vflag |= INP_SOCKREF; } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); } @@ -993,7 +993,7 @@ TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { error = ECONNRESET; goto out; @@ -1018,7 +1018,7 @@ out: TCPDEBUG2(PRU_RCVOOB); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -1084,7 +1084,7 @@ int error; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (inp->inp_lport == 0) { error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); @@ -1139,7 +1139,7 @@ int error; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (inp->inp_lport == 0) { error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); @@ -1203,6 +1203,9 @@ tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti) { + /* + * XXXRW: lock assert OK. + */ INP_LOCK_ASSERT(tp->t_inpcb); bzero(ti, sizeof(*ti)); @@ -1252,9 +1255,9 @@ error = 0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); if (sopt->sopt_level != IPPROTO_TCP) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); #ifdef INET6 if (INP_CHECK_SOCKAF(so, AF_INET6)) error = ip6_ctloutput(so, sopt); @@ -1382,7 +1385,7 @@ break; } out: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (error); } @@ -1452,7 +1455,7 @@ return (ENOBUFS); } tp->t_state = TCPS_CLOSED; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); return (0); } @@ -1472,7 +1475,7 @@ struct socket *so = inp->inp_socket; INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); /* * Neither tcp_close() nor tcp_drop() should return NULL, as the @@ -1510,7 +1513,7 @@ { INP_INFO_WLOCK_ASSERT(&tcbinfo); - INP_LOCK_ASSERT(tp->t_inpcb); + INP_WLOCK_ASSERT(tp->t_inpcb); switch (tp->t_state) { case TCPS_LISTEN: --- netinet/udp_usrreq.c 2007/10/24 19:06:35 +++ netinet/udp_usrreq.c 2008/01/06 23:09:29 @@ -195,7 +195,7 @@ struct sockaddr_in6 udp_in6; #endif - INP_LOCK_ASSERT(inp); + INP_RLOCK_ASSERT(inp); #ifdef IPSEC /* Check AH/ESP integrity. */ @@ -217,6 +217,11 @@ if (inp->inp_vflag & INP_IPV6) { int savedflags; + /* + * XXXRW: we have an rlock so this is bad. Should + * be passing a flag to ip6_savecontrol rather than + * changing the inpcb flag. + */ savedflags = inp->inp_flags; inp->inp_flags &= ~INP_UNMAPPABLEOPTS; ip6_savecontrol(inp, n, &opts); @@ -382,6 +387,9 @@ } #endif + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(&udbinfo); if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in_broadcast(ip->ip_dst, ifp)) { @@ -412,7 +420,7 @@ inp->inp_fport != uh->uh_sport) continue; - INP_LOCK(inp); + INP_RLOCK(inp); /* * Handle socket delivery policy for any-source @@ -469,7 +477,7 @@ } } if (blocked != 0) { - INP_UNLOCK(inp); + INP_RUNLOCK(inp); continue; } } @@ -480,7 +488,7 @@ if (n != NULL) udp_append(last, ip, n, iphlen + sizeof(struct udphdr), &udp_in); - INP_UNLOCK(last); + INP_RUNLOCK(last); } last = inp; /* @@ -507,7 +515,7 @@ } udp_append(last, ip, m, iphlen + sizeof(struct udphdr), &udp_in); - INP_UNLOCK(last); + INP_RUNLOCK(last); INP_INFO_RUNLOCK(&udbinfo); return; } @@ -546,17 +554,17 @@ /* * Check the minimum TTL for socket. */ - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl) goto badheadlocked; udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in); - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_RUNLOCK(&udbinfo); return; badheadlocked: if (inp) - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_RUNLOCK(&udbinfo); badunlocked: m_freem(m); @@ -570,6 +578,12 @@ udp_notify(struct inpcb *inp, int errno) { + /* + * XXXRW: Could be rlock assert, but in_pcbnotifyall() acquires a + * wlock due to TCP. + */ + INP_LOCK_ASSERT(inp); + inp->inp_socket->so_error = errno; sorwakeup(inp->inp_socket); sowwakeup(inp->inp_socket); @@ -606,15 +620,18 @@ 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); if (inp != NULL) { - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_socket != NULL) { udp_notify(inp, inetctlerrmap[cmd]); } - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } INP_INFO_RUNLOCK(&udbinfo); } else @@ -647,6 +664,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,14 +689,17 @@ 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)) { - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt && cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) inp_list[i++] = inp; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } INP_INFO_RUNLOCK(&udbinfo); n = i; @@ -684,7 +707,7 @@ error = 0; for (i = 0; i < n; i++) { inp = inp_list[i]; - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt) { struct xinpcb xi; bzero(&xi, sizeof(xi)); @@ -694,10 +717,10 @@ if (inp->inp_socket) sotoxsocket(inp->inp_socket, &xi.xi_socket); xi.xi_inp.inp_gencnt = inp->inp_gencnt; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); error = SYSCTL_OUT(req, &xi, sizeof xi); } else - INP_UNLOCK(inp); + INP_RUNLOCK(inp); } if (!error) { /* @@ -706,6 +729,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 +760,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); @@ -835,12 +864,33 @@ return (error); } - if (src.sin_family == AF_INET || addr != NULL) { + /* + * We may enter binding/connecting routines and manipulate global + * address lists if a source address is requested explicitly, or if + * an explicit destination is requested and a connect has not yet + * been performed. In these cases, acquire the global lock. + * + * XXXRW: In some of these cases, if may be sufficient to acquire a + * read lock? + * + * XXXRW: This isn't right, as we are looking at the inp values + * before acquiring the pcbinfo lock. In the future, we'll want to + * detect this race and handle it... + */ + if (addr != NULL && (inp->inp_laddr.s_addr == INADDR_ANY && + inp->inp_lport == 0)) { INP_INFO_WLOCK(&udbinfo); + INP_WLOCK(inp); + unlock_udbinfo = 2; + } else if ((addr != NULL && (inp->inp_laddr.s_addr == INADDR_ANY || + inp->inp_lport == 0)) || src.sin_family == AF_INET) { + INP_INFO_RLOCK(&udbinfo); + INP_RLOCK(inp); unlock_udbinfo = 1; - } else + } else { unlock_udbinfo = 0; - INP_LOCK(inp); + INP_RLOCK(inp); + } #ifdef MAC mac_inpcb_create_mbuf(inp, m); @@ -854,6 +904,10 @@ laddr = inp->inp_laddr; lport = inp->inp_lport; if (src.sin_family == AF_INET) { + /* + * XXXRW: lock assert OK. + */ + INP_INFO_LOCK_ASSERT(&udbinfo); if ((lport == 0) || (laddr.s_addr == INADDR_ANY && src.sin_addr.s_addr == INADDR_ANY)) { @@ -866,35 +920,82 @@ goto release; } + /* + * If a UDP socket has been connected, then a local address/port will + * have been selected and bound. + * + * If a UDP socket has not been connected to, then an explicit + * destination address must be used, in which case local address/port + * may not have been selected and bound. + */ if (addr) { + if (inp->inp_faddr.s_addr != INADDR_ANY) { + error = EISCONN; + goto release; + } + + /* + * Jail may rewrite the destination address, so let it do + * that before we use it. + */ sin = (struct sockaddr_in *)addr; if (jailed(td->td_ucred)) prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr); - if (inp->inp_faddr.s_addr != INADDR_ANY) { - error = EISCONN; - goto release; - } - error = in_pcbconnect_setup(inp, addr, &laddr.s_addr, &lport, - &faddr.s_addr, &fport, NULL, td->td_ucred); - if (error) - goto release; - /* Commit the local port if newly assigned. */ - if (inp->inp_laddr.s_addr == INADDR_ANY && + /* + * If local address or port hasn't yet been selected, do that + * now. Once a port is selected, we commit the binding back + * to the socket; we also commit the binding of the address + * if in jail. + */ + if (inp->inp_laddr.s_addr == INADDR_ANY || inp->inp_lport == 0) { /* - * Remember addr if jailed, to prevent rebinding. + * XXXRW: lock assert OK. */ - if (jailed(td->td_ucred)) - inp->inp_laddr = laddr; - inp->inp_lport = lport; - if (in_pcbinshash(inp) != 0) { - inp->inp_lport = 0; - error = EAGAIN; + INP_INFO_LOCK_ASSERT(&udbinfo); + error = in_pcbconnect_setup(inp, addr, &laddr.s_addr, + &lport, &faddr.s_addr, &fport, NULL, + td->td_ucred); + if (error) goto release; + + /* + * XXXRW: Why not commit the port if the address is + * !INADDR_ANY? + */ + /* Commit the local port if newly assigned. */ + if (inp->inp_laddr.s_addr == INADDR_ANY && + inp->inp_lport == 0) { + /* + * XXXRW: wlock assert OK. + */ + INP_INFO_WLOCK_ASSERT(&udbinfo); + INP_WLOCK_ASSERT(inp); + /* + * Remember addr if jailed, to prevent + * rebinding. + */ + if (jailed(td->td_ucred)) + inp->inp_laddr = laddr; + inp->inp_lport = lport; + if (in_pcbinshash(inp) != 0) { + inp->inp_lport = 0; + error = EAGAIN; + goto release; + } + inp->inp_flags |= INP_ANONPORT; } - inp->inp_flags |= INP_ANONPORT; + } else { + /* + * XXXRW: Is it OK that we haven't checked for a + * colliding binding for these foreign address and + * port combined with the existing binding for local + * address and port? + */ + faddr = sin->sin_addr; + fport = sin->sin_port; } } else { faddr = inp->inp_faddr; @@ -967,17 +1068,27 @@ ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */ udpstat.udps_opackets++; - if (unlock_udbinfo) + if (unlock_udbinfo == 2) INP_INFO_WUNLOCK(&udbinfo); + else if (unlock_udbinfo == 1) + INP_INFO_RUNLOCK(&udbinfo); error = ip_output(m, inp->inp_options, NULL, ipflags, inp->inp_moptions, inp); - INP_UNLOCK(inp); + if (unlock_udbinfo == 2) + INP_WUNLOCK(inp); + else + INP_RUNLOCK(inp); return (error); release: - INP_UNLOCK(inp); - if (unlock_udbinfo) + if (unlock_udbinfo == 2) { + INP_WUNLOCK(inp); + INP_INFO_WUNLOCK(&udbinfo); + } else if (unlock_udbinfo == 1) { + INP_RUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); + } else + INP_RUNLOCK(inp); m_freem(m); return (error); } @@ -990,13 +1101,13 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_abort: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_faddr.s_addr != INADDR_ANY) { in_pcbdisconnect(inp); inp->inp_laddr.s_addr = INADDR_ANY; soisdisconnected(so); } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); } @@ -1022,7 +1133,7 @@ INP_INFO_WUNLOCK(&udbinfo); inp->inp_vflag |= INP_IPV4; inp->inp_ip_ttl = ip_defttl; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (0); } @@ -1035,9 +1146,9 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_bind: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); error = in_pcbbind(inp, nam, td->td_ucred); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (error); } @@ -1050,13 +1161,13 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_close: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_faddr.s_addr != INADDR_ANY) { in_pcbdisconnect(inp); inp->inp_laddr.s_addr = INADDR_ANY; soisdisconnected(so); } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); } @@ -1070,9 +1181,9 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_connect: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_faddr.s_addr != INADDR_ANY) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (EISCONN); } @@ -1082,7 +1193,7 @@ error = in_pcbconnect(inp, nam, td->td_ucred); if (error == 0) soisconnected(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (error); } @@ -1097,7 +1208,7 @@ KASSERT(inp->inp_faddr.s_addr == INADDR_ANY, ("udp_detach: not disconnected")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); in_pcbdetach(inp); in_pcbfree(inp); INP_INFO_WUNLOCK(&udbinfo); @@ -1111,10 +1222,10 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_disconnect: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->inp_faddr.s_addr == INADDR_ANY) { + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); - INP_UNLOCK(inp); return (ENOTCONN); } @@ -1123,7 +1234,7 @@ SOCK_LOCK(so); so->so_state &= ~SS_ISCONNECTED; /* XXX */ SOCK_UNLOCK(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (0); } @@ -1144,11 +1255,14 @@ { struct inpcb *inp; + /* + * XXXRW: Possibly could be rlock. + */ inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_shutdown: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); socantsendmore(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (0); } --- netinet6/icmp6.c 2007/12/10 16:07:50 +++ netinet6/icmp6.c 2008/01/06 23:09:29 @@ -1889,12 +1889,15 @@ return (IPPROTO_DONE); } + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(&ripcbinfo); LIST_FOREACH(in6p, &ripcb, inp_list) { - INP_LOCK(in6p); + INP_RLOCK(in6p); if ((in6p->inp_vflag & INP_IPV6) == 0) { docontinue: - INP_UNLOCK(in6p); + INP_RUNLOCK(in6p); continue; } if (in6p->in6p_ip6_nxt != IPPROTO_ICMPV6) @@ -1965,7 +1968,7 @@ sorwakeup_locked(last->in6p_socket); opts = NULL; } - INP_UNLOCK(last); + INP_RUNLOCK(last); } last = in6p; } @@ -2003,7 +2006,7 @@ SOCKBUF_UNLOCK(&last->in6p_socket->so_rcv); } else sorwakeup_locked(last->in6p_socket); - INP_UNLOCK(last); + INP_RUNLOCK(last); } else { m_freem(m); ip6stat.ip6s_delivered--; --- netinet6/in6_pcb.c 2007/12/17 17:22:20 +++ netinet6/in6_pcb.c 2008/01/06 23:09:29 @@ -122,7 +122,7 @@ int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); INP_INFO_WLOCK_ASSERT(pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (!in6_ifaddr) /* XXX broken! */ return (EADDRNOTAVAIL); @@ -288,7 +288,7 @@ int scope_ambiguous = 0; INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (nam->sa_len != sizeof (*sin6)) return (EINVAL); @@ -354,7 +354,7 @@ int error; INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); /* * Call inner routine, to assign local interface address. @@ -396,7 +396,7 @@ { INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); bzero((caddr_t)&inp->in6p_faddr, sizeof(inp->in6p_faddr)); inp->inp_fport = 0; @@ -421,7 +421,7 @@ KASSERT(inp->inp_socket == NULL, ("in6_pcbfree: inp_socket != NULL")); INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); #ifdef IPSEC if (inp->in6p_sp != NULL) @@ -440,7 +440,7 @@ #ifdef MAC mac_inpcb_destroy(inp); #endif - INP_UNLOCK(inp); + INP_WUNLOCK(inp); uma_zfree(ipi->ipi_zone, inp); } @@ -489,10 +489,10 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("in6_getsockaddr: inp == NULL")); - INP_LOCK(inp); + INP_RLOCK(inp); port = inp->inp_lport; addr = inp->in6p_laddr; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); *nam = in6_sockaddr(port, &addr); return 0; @@ -508,10 +508,10 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("in6_getpeeraddr: inp == NULL")); - INP_LOCK(inp); + INP_RLOCK(inp); port = inp->inp_fport; addr = inp->in6p_faddr; - INP_UNLOCK(inp); + INP_RUNLOCK(inp); *nam = in6_sockaddr(port, &addr); return 0; @@ -613,11 +613,11 @@ head = pcbinfo->ipi_listhead; INP_INFO_WLOCK(pcbinfo); for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { - INP_LOCK(inp); + INP_WLOCK(inp); ninp = LIST_NEXT(inp, inp_list); if ((inp->inp_vflag & INP_IPV6) == 0) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); continue; } @@ -658,16 +658,16 @@ !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &sa6_src.sin6_addr)) || (fport && inp->inp_fport != fport)) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); continue; } do_notify: if (notify) { if ((*notify)(inp, errno)) - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } else - INP_UNLOCK(inp); + INP_WUNLOCK(inp); } INP_INFO_WUNLOCK(pcbinfo); } @@ -767,9 +767,12 @@ 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); + INP_WLOCK(in6p); im6o = in6p->in6p_moptions; if ((in6p->inp_vflag & INP_IPV6) && im6o) { @@ -796,7 +799,7 @@ } } } - INP_UNLOCK(in6p); + INP_WUNLOCK(in6p); } INP_INFO_RUNLOCK(pcbinfo); } @@ -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); --- netinet6/in6_src.c 2007/12/10 16:07:50 +++ netinet6/in6_src.c 2008/01/06 23:09:29 @@ -748,7 +748,7 @@ struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; INP_INFO_WLOCK_ASSERT(pcbinfo); - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); /* XXX: this is redundant when called from in6_pcbbind */ if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) --- netinet6/raw_ip6.c 2007/12/10 16:07:50 +++ netinet6/raw_ip6.c 2008/01/06 23:09:29 @@ -152,12 +152,15 @@ init_sin6(&fromsa, m); /* general init */ + /* + * XXXRW: rlock OK. + */ INP_INFO_RLOCK(&ripcbinfo); LIST_FOREACH(in6p, &ripcb, inp_list) { - INP_LOCK(in6p); + INP_RLOCK(in6p); if ((in6p->in6p_vflag & INP_IPV6) == 0) { docontinue: - INP_UNLOCK(in6p); + INP_RUNLOCK(in6p); continue; } if (in6p->in6p_ip6_nxt && @@ -207,7 +210,7 @@ sorwakeup(last->in6p_socket); opts = NULL; } - INP_UNLOCK(last); + INP_RUNLOCK(last); } last = in6p; } @@ -220,7 +223,7 @@ ipsec6stat.in_polvio++; ip6stat.ip6s_delivered--; /* do not inject data into pcb */ - INP_UNLOCK(last); + INP_RUNLOCK(last); } else #endif /* IPSEC */ if (last) { @@ -237,7 +240,7 @@ rip6stat.rip6s_fullsock++; } else sorwakeup(last->in6p_socket); - INP_UNLOCK(last); + INP_RUNLOCK(last); } else { rip6stat.rip6s_nosock++; if (m->m_flags & M_MCAST) @@ -335,8 +338,13 @@ control = va_arg(ap, struct mbuf *); va_end(ap); + /* + * XXXRW: wlock here is unfortunate, but due to in6_selectsrc() + * storing its results in in6p->in6p_laddr rather than a local + * variable. + */ in6p = sotoin6pcb(so); - INP_LOCK(in6p); + INP_WLOCK(in6p); priv = 0; if (suser_cred(so->so_cred, 0) == 0) @@ -469,7 +477,7 @@ ip6_clearpktopts(&opt, -1); m_freem(control); } - INP_UNLOCK(in6p); + INP_WUNLOCK(in6p); return (error); } @@ -572,7 +580,7 @@ inp->in6p_cksum = -1; inp->in6p_icmp6filt = filter; ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return 0; } @@ -588,7 +596,7 @@ ip6_mrouter_done(); /* xxx: RSVP */ INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (inp->in6p_icmp6filt) { FREE(inp->in6p_icmp6filt, M_PCB); inp->in6p_icmp6filt = NULL; @@ -659,9 +667,9 @@ return (EADDRNOTAVAIL); } INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); inp->in6p_laddr = addr->sin6_addr; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); return 0; } @@ -697,13 +705,13 @@ return(error); INP_INFO_WLOCK(&ripcbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); /* Source address selection. XXX: need pcblookup? */ in6a = in6_selectsrc(addr, inp->in6p_outputopts, inp->in6p_moptions, NULL, &inp->in6p_laddr, &ifp, &error); if (in6a == NULL) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); return (error ? error : EADDRNOTAVAIL); } @@ -711,14 +719,14 @@ /* XXX: see above */ if (ifp && scope_ambiguous && (error = in6_setscope(&addr->sin6_addr, ifp, NULL)) != 0) { - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); return(error); } inp->in6p_faddr = addr->sin6_addr; inp->in6p_laddr = *in6a; soisconnected(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&ripcbinfo); return 0; } @@ -728,11 +736,14 @@ { struct inpcb *inp; + /* + * XXXRW: Technically, could use an rlock here. + */ inp = sotoinpcb(so); KASSERT(inp != NULL, ("rip6_shutdown: inp == NULL")); - INP_LOCK(inp); + INP_WLOCK(inp); socantsendmore(so); - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return 0; } --- netinet6/udp6_usrreq.c 2007/12/10 16:07:50 +++ netinet6/udp6_usrreq.c 2008/01/06 23:09:29 @@ -129,6 +129,9 @@ struct socket *so; struct mbuf *opts; + /* + * XXXRW: lock assert OK. + */ INP_LOCK_ASSERT(inp); #ifdef IPSEC @@ -227,6 +230,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; @@ -277,9 +283,9 @@ struct mbuf *n; if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { - INP_LOCK(last); + INP_RLOCK(last); udp6_append(last, n, off, &fromsa); - INP_UNLOCK(last); + INP_RUNLOCK(last); } } last = inp; @@ -306,9 +312,9 @@ udpstat.udps_noportmcast++; goto badheadlocked; } - INP_LOCK(last); + INP_RLOCK(last); udp6_append(last, m, off, &fromsa); - INP_UNLOCK(last); + INP_RUNLOCK(last); INP_INFO_RUNLOCK(&udbinfo); return (IPPROTO_DONE); } @@ -343,9 +349,9 @@ icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); return (IPPROTO_DONE); } - INP_LOCK(inp); + INP_RLOCK(inp); udp6_append(inp, m, off, &fromsa); - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_RUNLOCK(&udbinfo); return (IPPROTO_DONE); @@ -445,6 +451,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, @@ -453,7 +462,7 @@ INP_INFO_RUNLOCK(&udbinfo); return (ENOENT); } - INP_LOCK(inp); + INP_RLOCK(inp); if (inp->inp_socket == NULL) { error = ENOENT; goto out; @@ -463,7 +472,7 @@ goto out; cru2x(inp->inp_socket->so_cred, &xuc); out: - INP_UNLOCK(inp); + INP_RUNLOCK(inp); INP_INFO_RUNLOCK(&udbinfo); if (error == 0) error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); @@ -493,7 +502,12 @@ int flags; struct sockaddr_in6 tmp; - INP_LOCK_ASSERT(inp); + /* + * XXXRW: Could be rlock except for in6_selectsrc()? + * + * XXXRW: Check this. + */ + INP_WLOCK_ASSERT(inp); priv = 0; if (td && !suser(td)) @@ -713,13 +727,13 @@ #endif INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) { in6_pcbdisconnect(inp); inp->in6p_laddr = in6addr_any; soisdisconnected(so); } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); } @@ -757,7 +771,7 @@ * which may match an IPv4-mapped IPv6 address. */ inp->inp_ip_ttl = ip_defttl; - INP_UNLOCK(inp); + INP_WUNLOCK(inp); return (0); } @@ -771,7 +785,7 @@ KASSERT(inp != NULL, ("udp6_bind: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); inp->inp_vflag &= ~INP_IPV4; inp->inp_vflag |= INP_IPV6; if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) { @@ -795,7 +809,7 @@ error = in6_pcbbind(inp, nam, td->td_ucred); out: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (error); } @@ -818,13 +832,13 @@ } #endif INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) { in6_pcbdisconnect(inp); inp->in6p_laddr = in6addr_any; soisdisconnected(so); } - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); } @@ -838,7 +852,7 @@ KASSERT(inp != NULL, ("udp6_connect: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) { struct sockaddr_in6 *sin6_p; @@ -875,7 +889,7 @@ soisconnected(so); } out: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (error); } @@ -889,7 +903,7 @@ KASSERT(inp != NULL, ("udp6_detach: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); in6_pcbdetach(inp); in6_pcbfree(inp); INP_INFO_WUNLOCK(&udbinfo); @@ -905,7 +919,7 @@ KASSERT(inp != NULL, ("udp6_disconnect: inp == NULL")); INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); #ifdef INET if (inp->inp_vflag & INP_IPV4) { @@ -927,7 +941,7 @@ /* XXXRW: so_state locking? */ so->so_state &= ~SS_ISCONNECTED; /* XXX */ out: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (0); } @@ -942,8 +956,11 @@ inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp6_send: inp == NULL")); + /* + * XXXRW: When udp6_output() is rlock, make this rlock. + */ INP_INFO_WLOCK(&udbinfo); - INP_LOCK(inp); + INP_WLOCK(inp); if (addr) { if (addr->sa_len != sizeof(struct sockaddr_in6)) { error = EINVAL; @@ -996,12 +1013,12 @@ #endif error = udp6_output(inp, m, addr, control, td); out: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); return (error); bad: - INP_UNLOCK(inp); + INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&udbinfo); m_freem(m); return (error); --- security/audit/audit_arg.c 2007/06/27 17:03:26 +++ security/audit/audit_arg.c 2008/01/06 23:09:29 @@ -648,7 +648,7 @@ so->so_proto->pr_protocol; SOCK_UNLOCK(so); pcb = (struct inpcb *)so->so_pcb; - INP_LOCK(pcb); + INP_RLOCK(pcb); ar->k_ar.ar_arg_sockinfo.so_raddr = pcb->inp_faddr.s_addr; ar->k_ar.ar_arg_sockinfo.so_laddr = @@ -657,7 +657,7 @@ pcb->inp_fport; ar->k_ar.ar_arg_sockinfo.so_lport = pcb->inp_lport; - INP_UNLOCK(pcb); + INP_RUNLOCK(pcb); ARG_SET_VALID(ar, ARG_SOCKINFO); } break; --- security/mac/mac_inet.c 2007/10/28 17:17:19 +++ security/mac/mac_inet.c 2008/01/06 23:09:29 @@ -201,7 +201,7 @@ { struct label *mlabel; - INP_LOCK_ASSERT(inp); + INP_RLOCK_ASSERT(inp); mlabel = mac_mbuf_to_label(m); MAC_PERFORM(inpcb_create_mbuf, inp, inp->inp_label, m, mlabel); @@ -306,7 +306,7 @@ mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp) { - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); SOCK_LOCK_ASSERT(so); MAC_PERFORM(inpcb_sosetlabel, so, so->so_label, inp, inp->inp_label); } @@ -376,7 +376,7 @@ mac_syncache_create(struct label *label, struct inpcb *inp) { - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); MAC_PERFORM(syncache_create, label, inp); }