mirror of
https://github.com/openbsd/src.git
synced 2024-12-21 23:18:00 -08:00
Use per-sockbuf mutex(9) to protect `so_rcv' buffer of tcp(4) sockets.
Only unlock soreceive() path, somove() path still locked exclusively. Also exclusive socket lock will be taken in the soreceive() path each time before pru_rcvd() call. Note, both socket and `sb_mtx' locks are held while SS_CANTRCVMORE modified, so socket lock is enough to check it in the protocol input path. ok bluhm
This commit is contained in:
parent
10d5b13ebf
commit
f1bf6f4e82
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: uipc_socket.c,v 1.346 2024/12/15 11:00:05 dlg Exp $ */
|
||||
/* $OpenBSD: uipc_socket.c,v 1.347 2024/12/19 22:11:35 mvs Exp $ */
|
||||
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -160,6 +160,8 @@ soalloc(const struct protosw *prp, int wait)
|
||||
case SOCK_RAW:
|
||||
case SOCK_DGRAM:
|
||||
so->so_snd.sb_flags |= SB_MTXLOCK;
|
||||
/* FALLTHROUGH */
|
||||
case SOCK_STREAM:
|
||||
so->so_rcv.sb_flags |= SB_MTXLOCK;
|
||||
break;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: uipc_socket2.c,v 1.159 2024/11/06 14:37:45 bluhm Exp $ */
|
||||
/* $OpenBSD: uipc_socket2.c,v 1.160 2024/12/19 22:11:35 mvs Exp $ */
|
||||
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -839,8 +839,7 @@ sbappend(struct socket *so, struct sockbuf *sb, struct mbuf *m)
|
||||
void
|
||||
sbappendstream(struct socket *so, struct sockbuf *sb, struct mbuf *m)
|
||||
{
|
||||
KASSERT(sb == &so->so_rcv || sb == &so->so_snd);
|
||||
soassertlocked(so);
|
||||
sbmtxassertlocked(so, sb);
|
||||
KDASSERT(m->m_nextpkt == NULL);
|
||||
KASSERT(sb->sb_mb == sb->sb_lastrecord);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_input.c,v 1.408 2024/11/08 21:40:39 bluhm Exp $ */
|
||||
/* $OpenBSD: tcp_input.c,v 1.409 2024/12/19 22:11:35 mvs Exp $ */
|
||||
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -334,8 +334,11 @@ tcp_flush_queue(struct tcpcb *tp)
|
||||
ND6_HINT(tp);
|
||||
if (so->so_rcv.sb_state & SS_CANTRCVMORE)
|
||||
m_freem(q->tcpqe_m);
|
||||
else
|
||||
else {
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
sbappendstream(so, &so->so_rcv, q->tcpqe_m);
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
}
|
||||
pool_put(&tcpqe_pool, q);
|
||||
q = nq;
|
||||
} while (q != NULL && q->tcpqe_tcp->th_seq == tp->rcv_nxt);
|
||||
@ -1051,7 +1054,9 @@ findpcb:
|
||||
} else
|
||||
tp->rfbuf_cnt += tlen;
|
||||
m_adj(m, iphlen + off);
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
sbappendstream(so, &so->so_rcv, m);
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
}
|
||||
tp->t_flags |= TF_BLOCKOUTPUT;
|
||||
sorwakeup(so);
|
||||
@ -1869,13 +1874,19 @@ step6:
|
||||
*/
|
||||
if ((tiflags & TH_URG) && th->th_urp &&
|
||||
TCPS_HAVERCVDFIN(tp->t_state) == 0) {
|
||||
u_long urgent;
|
||||
|
||||
/*
|
||||
* This is a kludge, but if we receive and accept
|
||||
* random urgent pointers, we'll crash in
|
||||
* soreceive. It's hard to imagine someone
|
||||
* actually wanting to send this much urgent data.
|
||||
*/
|
||||
if (th->th_urp + so->so_rcv.sb_cc > sb_max) {
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
urgent = th->th_urp + so->so_rcv.sb_cc;
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
|
||||
if (urgent > sb_max) {
|
||||
th->th_urp = 0; /* XXX */
|
||||
tiflags &= ~TH_URG; /* XXX */
|
||||
goto dodata; /* XXX */
|
||||
@ -1948,7 +1959,9 @@ dodata: /* XXX */
|
||||
m_freem(m);
|
||||
else {
|
||||
m_adj(m, hdroptlen);
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
sbappendstream(so, &so->so_rcv, m);
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
}
|
||||
tp->t_flags |= TF_BLOCKOUTPUT;
|
||||
sorwakeup(so);
|
||||
@ -2998,6 +3011,7 @@ tcp_mss_update(struct tcpcb *tp)
|
||||
(void)sbreserve(so, &so->so_snd, bufsize);
|
||||
}
|
||||
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
bufsize = so->so_rcv.sb_hiwat;
|
||||
if (bufsize > mss) {
|
||||
bufsize = roundup(bufsize, mss);
|
||||
@ -3005,6 +3019,7 @@ tcp_mss_update(struct tcpcb *tp)
|
||||
bufsize = sb_max;
|
||||
(void)sbreserve(so, &so->so_rcv, bufsize);
|
||||
}
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_output.c,v 1.145 2024/05/14 09:39:02 bluhm Exp $ */
|
||||
/* $OpenBSD: tcp_output.c,v 1.146 2024/12/19 22:11:35 mvs Exp $ */
|
||||
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
|
||||
|
||||
/*
|
||||
@ -195,7 +195,7 @@ int
|
||||
tcp_output(struct tcpcb *tp)
|
||||
{
|
||||
struct socket *so = tp->t_inpcb->inp_socket;
|
||||
long len, win, txmaxseg;
|
||||
long len, win, rcv_hiwat, txmaxseg;
|
||||
int off, flags, error;
|
||||
struct mbuf *m;
|
||||
struct tcphdr *th;
|
||||
@ -373,7 +373,10 @@ again:
|
||||
if (off + len < so->so_snd.sb_cc)
|
||||
flags &= ~TH_FIN;
|
||||
|
||||
win = sbspace(so, &so->so_rcv);
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
win = sbspace_locked(so, &so->so_rcv);
|
||||
rcv_hiwat = (long) so->so_rcv.sb_hiwat;
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
|
||||
/*
|
||||
* Sender silly window avoidance. If connection is idle
|
||||
@ -420,7 +423,7 @@ again:
|
||||
|
||||
if (adv >= (long) (2 * tp->t_maxseg))
|
||||
goto send;
|
||||
if (2 * adv >= (long) so->so_rcv.sb_hiwat)
|
||||
if (2 * adv >= rcv_hiwat)
|
||||
goto send;
|
||||
}
|
||||
|
||||
@ -854,7 +857,7 @@ send:
|
||||
* Calculate receive window. Don't shrink window,
|
||||
* but avoid silly window syndrome.
|
||||
*/
|
||||
if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
|
||||
if (win < (rcv_hiwat / 4) && win < (long)tp->t_maxseg)
|
||||
win = 0;
|
||||
if (win > (long)TCP_MAXWIN << tp->rcv_scale)
|
||||
win = (long)TCP_MAXWIN << tp->rcv_scale;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tcp_usrreq.c,v 1.232 2024/11/08 15:46:55 bluhm Exp $ */
|
||||
/* $OpenBSD: tcp_usrreq.c,v 1.233 2024/12/19 22:11:35 mvs Exp $ */
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -296,10 +296,12 @@ tcp_fill_info(struct tcpcb *tp, struct socket *so, struct mbuf *m)
|
||||
ti->tcpi_rfbuf_cnt = tp->rfbuf_cnt;
|
||||
ti->tcpi_rfbuf_ts = (now - tp->rfbuf_ts) * t;
|
||||
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
ti->tcpi_so_rcv_sb_cc = so->so_rcv.sb_cc;
|
||||
ti->tcpi_so_rcv_sb_hiwat = so->so_rcv.sb_hiwat;
|
||||
ti->tcpi_so_rcv_sb_lowat = so->so_rcv.sb_lowat;
|
||||
ti->tcpi_so_rcv_sb_wat = so->so_rcv.sb_wat;
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
ti->tcpi_so_snd_sb_cc = so->so_snd.sb_cc;
|
||||
ti->tcpi_so_snd_sb_hiwat = so->so_snd.sb_hiwat;
|
||||
ti->tcpi_so_snd_sb_lowat = so->so_snd.sb_lowat;
|
||||
@ -1044,7 +1046,9 @@ tcp_dodisconnect(struct tcpcb *tp)
|
||||
tp = tcp_drop(tp, 0);
|
||||
else {
|
||||
soisdisconnecting(so);
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
sbflush(so, &so->so_rcv);
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
tp = tcp_usrclosed(tp);
|
||||
if (tp)
|
||||
(void) tcp_output(tp);
|
||||
@ -1556,7 +1560,11 @@ void
|
||||
tcp_update_rcvspace(struct tcpcb *tp)
|
||||
{
|
||||
struct socket *so = tp->t_inpcb->inp_socket;
|
||||
u_long nmax = so->so_rcv.sb_hiwat;
|
||||
u_long nmax;
|
||||
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
|
||||
nmax = so->so_rcv.sb_hiwat;
|
||||
|
||||
if (sbchecklowmem()) {
|
||||
/* low on memory try to get rid of some */
|
||||
@ -1577,10 +1585,11 @@ tcp_update_rcvspace(struct tcpcb *tp)
|
||||
nmax < so->so_snd.sb_lowat)
|
||||
nmax = so->so_snd.sb_lowat;
|
||||
|
||||
if (nmax == so->so_rcv.sb_hiwat)
|
||||
return;
|
||||
if (nmax != so->so_rcv.sb_hiwat) {
|
||||
/* round to MSS boundary */
|
||||
nmax = roundup(nmax, tp->t_maxseg);
|
||||
sbreserve(so, &so->so_rcv, nmax);
|
||||
}
|
||||
|
||||
/* round to MSS boundary */
|
||||
nmax = roundup(nmax, tp->t_maxseg);
|
||||
sbreserve(so, &so->so_rcv, nmax);
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user