From c80eb4865bece54c3611046d77ba12a2c1f53f32 Mon Sep 17 00:00:00 2001 From: mvs Date: Sun, 31 Mar 2024 13:50:00 +0000 Subject: [PATCH] Mark `so_rcv' sockbuf of udp(4) sockets as SB_OWNLOCK. sbappend*() and soreceive() of SB_MTXLOCK marked sockets uses `sb_mtx' mutex(9) for protection, meanwhile buffer usage check and corresponding sbwait() sleep still serialized by solock(). Mark udp(4) as SB_OWNLOCK to avoid solock() serialization and rely to `sb_mtx' mutex(9). The `sb_state' and `sb_flags' modifications must be protected by `sb_mtx' too. ok bluhm --- sys/kern/sys_socket.c | 4 +++- sys/kern/uipc_socket.c | 10 +++++++++- sys/kern/uipc_socket2.c | 4 +++- sys/nfs/nfs_socket.c | 4 +++- sys/nfs/nfs_syscalls.c | 6 +++--- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index bba512b4321..e3b1a894353 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_socket.c,v 1.62 2024/03/26 09:46:47 mvs Exp $ */ +/* $OpenBSD: sys_socket.c,v 1.63 2024/03/31 13:50:00 mvs Exp $ */ /* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */ /* @@ -91,6 +91,7 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p) case FIOASYNC: solock(so); + mtx_enter(&so->so_rcv.sb_mtx); if (*(int *)data) { so->so_rcv.sb_flags |= SB_ASYNC; so->so_snd.sb_flags |= SB_ASYNC; @@ -98,6 +99,7 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p) so->so_rcv.sb_flags &= ~SB_ASYNC; so->so_snd.sb_flags &= ~SB_ASYNC; } + mtx_leave(&so->so_rcv.sb_mtx); sounlock(so); break; diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 1d8a101f107..a904ac02a83 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.323 2024/03/27 22:47:53 mvs Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.324 2024/03/31 13:50:00 mvs Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -155,6 +155,8 @@ soalloc(const struct protosw *prp, int wait) case AF_INET6: switch (prp->pr_type) { case SOCK_DGRAM: + so->so_rcv.sb_flags |= SB_OWNLOCK; + /* FALLTHROUGH */ case SOCK_RAW: so->so_rcv.sb_flags |= SB_MTXLOCK; break; @@ -1392,7 +1394,9 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) * we sleep, the socket buffers are not marked as spliced yet. */ if (somove(so, M_WAIT)) { + mtx_enter(&so->so_rcv.sb_mtx); so->so_rcv.sb_flags |= SB_SPLICE; + mtx_leave(&so->so_rcv.sb_mtx); sosp->so_snd.sb_flags |= SB_SPLICE; } @@ -1420,7 +1424,9 @@ sounsplice(struct socket *so, struct socket *sosp, int freeing) task_del(sosplice_taskq, &so->so_splicetask); timeout_del(&so->so_idleto); sosp->so_snd.sb_flags &= ~SB_SPLICE; + mtx_enter(&so->so_rcv.sb_mtx); so->so_rcv.sb_flags &= ~SB_SPLICE; + mtx_leave(&so->so_rcv.sb_mtx); so->so_sp->ssp_socket = sosp->so_sp->ssp_soback = NULL; /* Do not wakeup a socket that is about to be freed. */ if ((freeing & SOSP_FREEING_READ) == 0 && soreadable(so)) @@ -1678,6 +1684,7 @@ somove(struct socket *so, int wait) pru_rcvd(so); /* Receive buffer did shrink by len bytes, adjust oob. */ + mtx_enter(&so->so_rcv.sb_mtx); rcvstate = so->so_rcv.sb_state; so->so_rcv.sb_state &= ~SS_RCVATMARK; oobmark = so->so_oobmark; @@ -1688,6 +1695,7 @@ somove(struct socket *so, int wait) if (oobmark >= len) oobmark = 0; } + mtx_leave(&so->so_rcv.sb_mtx); /* * Handle oob data. If any malloc fails, ignore error. diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 4a9eaae346d..4fb48191b8d 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.146 2024/03/27 22:47:53 mvs Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.147 2024/03/31 13:50:00 mvs Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -351,7 +351,9 @@ void socantrcvmore(struct socket *so) { soassertlocked(so); + mtx_enter(&so->so_rcv.sb_mtx); so->so_rcv.sb_state |= SS_CANTRCVMORE; + mtx_leave(&so->so_rcv.sb_mtx); sorwakeup(so); } diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 1743a0e556a..9760db85492 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_socket.c,v 1.146 2024/03/22 07:15:04 claudio Exp $ */ +/* $OpenBSD: nfs_socket.c,v 1.147 2024/03/31 13:50:00 mvs Exp $ */ /* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */ /* @@ -371,7 +371,9 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) error = soreserve(so, sndreserve, rcvreserve); if (error) goto bad_locked; + mtx_enter(&so->so_rcv.sb_mtx); so->so_rcv.sb_flags |= SB_NOINTR; + mtx_leave(&so->so_rcv.sb_mtx); so->so_snd.sb_flags |= SB_NOINTR; sounlock(so); diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c index f3ccd3f5c16..32f28f021e0 100644 --- a/sys/nfs/nfs_syscalls.c +++ b/sys/nfs/nfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_syscalls.c,v 1.122 2024/03/22 07:15:04 claudio Exp $ */ +/* $OpenBSD: nfs_syscalls.c,v 1.123 2024/03/31 13:50:00 mvs Exp $ */ /* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */ /* @@ -297,12 +297,12 @@ nfssvc_addsock(struct file *fp, struct mbuf *mynam) m_freem(m); } solock(so); - so->so_rcv.sb_flags &= ~SB_NOINTR; mtx_enter(&so->so_rcv.sb_mtx); + so->so_rcv.sb_flags &= ~SB_NOINTR; so->so_rcv.sb_timeo_nsecs = INFSLP; mtx_leave(&so->so_rcv.sb_mtx); - so->so_snd.sb_flags &= ~SB_NOINTR; mtx_enter(&so->so_snd.sb_mtx); + so->so_snd.sb_flags &= ~SB_NOINTR; so->so_snd.sb_timeo_nsecs = INFSLP; mtx_leave(&so->so_snd.sb_mtx); sounlock(so); -- 2.20.1