Use `sb_mtx' mutex(9) to protect `sb_timeo_nsecs'. In most places
authormvs <mvs@openbsd.org>
Mon, 5 Feb 2024 20:21:38 +0000 (20:21 +0000)
committermvs <mvs@openbsd.org>
Mon, 5 Feb 2024 20:21:38 +0000 (20:21 +0000)
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
sys/kern/uipc_socket2.c
sys/nfs/nfs_socket.c
sys/nfs/nfs_syscalls.c

index aa28062..86dbd16 100644 (file)
@@ -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));
index a86dd7d..cc809f6 100644 (file)
@@ -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
index 80dfaa6..26adde1 100644 (file)
@@ -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) +
index b19bc36..67539ec 100644 (file)
@@ -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;