From c9054b5a522ca6eacc144c6546f58f94ae9bd286 Mon Sep 17 00:00:00 2001 From: mvs Date: Mon, 5 Feb 2024 20:21:38 +0000 Subject: [PATCH] Use `sb_mtx' mutex(9) to protect `sb_timeo_nsecs'. In most places solock() is still held because other 'sockbuf' members require it, but in so{g,s}etopt() paths solock() is avoided. ok bluhm --- sys/kern/uipc_socket.c | 12 +++++++----- sys/kern/uipc_socket2.c | 10 ++++++++-- sys/nfs/nfs_socket.c | 12 ++++++++---- sys/nfs/nfs_syscalls.c | 6 +++++- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index aa28062e180..86dbd160af2 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.316 2024/02/03 22:50:08 mvs Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.317 2024/02/05 20:21:38 mvs Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -1224,7 +1224,9 @@ sorflush(struct socket *so) m = sb->sb_mb; memset(&sb->sb_startzero, 0, (caddr_t)&sb->sb_endzero - (caddr_t)&sb->sb_startzero); + mtx_enter(&sb->sb_mtx); sb->sb_timeo_nsecs = INFSLP; + mtx_leave(&sb->sb_mtx); sbunlock(so, sb); if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) (*pr->pr_domain->dom_dispose)(m); @@ -1907,9 +1909,9 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m) if (nsecs == 0) nsecs = INFSLP; - solock(so); + mtx_enter(&sb->sb_mtx); sb->sb_timeo_nsecs = nsecs; - sounlock(so); + mtx_leave(&sb->sb_mtx); break; } @@ -2047,9 +2049,9 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) struct timeval tv; uint64_t nsecs; - solock_shared(so); + mtx_enter(&sb->sb_mtx); nsecs = sb->sb_timeo_nsecs; - sounlock_shared(so); + mtx_leave(&sb->sb_mtx); m->m_len = sizeof(struct timeval); memset(&tv, 0, sizeof(tv)); diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index a86dd7d8632..cc809f67e16 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.141 2024/02/03 22:50:08 mvs Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.142 2024/02/05 20:21:38 mvs Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -216,10 +216,14 @@ sonewconn(struct socket *head, int connstatus, int wait) goto fail; so->so_snd.sb_wat = head->so_snd.sb_wat; so->so_snd.sb_lowat = head->so_snd.sb_lowat; + mtx_enter(&head->so_snd.sb_mtx); so->so_snd.sb_timeo_nsecs = head->so_snd.sb_timeo_nsecs; + mtx_leave(&head->so_snd.sb_mtx); so->so_rcv.sb_wat = head->so_rcv.sb_wat; so->so_rcv.sb_lowat = head->so_rcv.sb_lowat; + mtx_enter(&head->so_rcv.sb_mtx); so->so_rcv.sb_timeo_nsecs = head->so_rcv.sb_timeo_nsecs; + mtx_leave(&head->so_rcv.sb_mtx); sigio_copy(&so->so_sigio, &head->so_sigio); @@ -506,15 +510,17 @@ sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg, int sbwait(struct socket *so, struct sockbuf *sb) { + uint64_t timeo_nsecs; int prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH; soassertlocked(so); mtx_enter(&sb->sb_mtx); + timeo_nsecs = sb->sb_timeo_nsecs; sb->sb_flags |= SB_WAIT; mtx_leave(&sb->sb_mtx); - return sosleep_nsec(so, &sb->sb_cc, prio, "netio", sb->sb_timeo_nsecs); + return sosleep_nsec(so, &sb->sb_cc, prio, "netio", timeo_nsecs); } int diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 80dfaa699c9..26adde1a849 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_socket.c,v 1.144 2023/08/03 09:49:09 mvs Exp $ */ +/* $OpenBSD: nfs_socket.c,v 1.145 2024/02/05 20:21:39 mvs Exp $ */ /* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */ /* @@ -295,7 +295,6 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) goto bad; } - solock(so); /* * Protocols that do not require connections may be optionally left * unconnected for servers that reply from a port other than NFS_PORT. @@ -303,9 +302,10 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) if (nmp->nm_flag & NFSMNT_NOCONN) { if (nmp->nm_soflags & PR_CONNREQUIRED) { error = ENOTCONN; - goto bad_locked; + goto bad; } } else { + solock(so); error = soconnect(so, nmp->nm_nam); if (error) goto bad_locked; @@ -330,17 +330,21 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) so->so_error = 0; goto bad_locked; } + sounlock(so); } /* * Always set receive timeout to detect server crash and reconnect. * Otherwise, we can get stuck in soreceive forever. */ + mtx_enter(&so->so_rcv.sb_mtx); so->so_rcv.sb_timeo_nsecs = SEC_TO_NSEC(5); + mtx_leave(&so->so_rcv.sb_mtx); + mtx_enter(&so->so_snd.sb_mtx); if (nmp->nm_flag & (NFSMNT_SOFT | NFSMNT_INT)) so->so_snd.sb_timeo_nsecs = SEC_TO_NSEC(5); else so->so_snd.sb_timeo_nsecs = INFSLP; - sounlock(so); + mtx_leave(&so->so_snd.sb_mtx); if (nmp->nm_sotype == SOCK_DGRAM) { sndreserve = nmp->nm_wsize + NFS_MAXPKTHDR; rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) + diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c index b19bc3653b3..67539ec23bf 100644 --- a/sys/nfs/nfs_syscalls.c +++ b/sys/nfs/nfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_syscalls.c,v 1.120 2024/01/12 08:47:46 ratchov Exp $ */ +/* $OpenBSD: nfs_syscalls.c,v 1.121 2024/02/05 20:21:39 mvs Exp $ */ /* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */ /* @@ -277,9 +277,13 @@ nfssvc_addsock(struct file *fp, struct mbuf *mynam) } solock(so); so->so_rcv.sb_flags &= ~SB_NOINTR; + mtx_enter(&so->so_rcv.sb_mtx); 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_timeo_nsecs = INFSLP; + mtx_leave(&so->so_snd.sb_mtx); sounlock(so); if (tslp) slp = tslp; -- 2.20.1