When we converted most of the splsoftnet() to NET_LOCK() we ended up
with some "lock" inversions between the socket buffer "lock" and the
NET_LOCK().  At that time the KERNEL_LOCK() was serializing access to
`sb_flags'.

We're now moving towards running sockets functions w/o KERNEL_LOCK()
in protocol input paths.  So I'd like to assert that the socket lock
is held when sb_flags are modified.

There's currently one exception to this rule, FIFO kqueue filters,
that I'll address in a later diff.

ok?

Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.207
diff -u -p -r1.207 uipc_socket.c
--- kern/uipc_socket.c  4 Nov 2017 14:13:53 -0000       1.207
+++ kern/uipc_socket.c  22 Nov 2017 11:22:02 -0000
@@ -453,7 +453,7 @@ restart:
                    (atomic || space < so->so_snd.sb_lowat))) {
                        if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT))
                                snderr(EWOULDBLOCK);
-                       sbunlock(&so->so_snd);
+                       sbunlock(so, &so->so_snd);
                        error = sbwait(so, &so->so_snd);
                        so->so_state &= ~SS_ISSENDING;
                        if (error)
@@ -497,7 +497,7 @@ restart:
 
 release:
        so->so_state &= ~SS_ISSENDING;
-       sbunlock(&so->so_snd);
+       sbunlock(so, &so->so_snd);
 out:
        sounlock(s);
        m_freem(top);
@@ -736,7 +736,7 @@ restart:
                }
                SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1");
                SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
-               sbunlock(&so->so_rcv);
+               sbunlock(so, &so->so_rcv);
                error = sbwait(so, &so->so_rcv);
                sounlock(s);
                if (error)
@@ -957,7 +957,7 @@ dontblock:
                        SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
                        error = sbwait(so, &so->so_rcv);
                        if (error) {
-                               sbunlock(&so->so_rcv);
+                               sbunlock(so, &so->so_rcv);
                                sounlock(s);
                                return (0);
                        }
@@ -993,7 +993,7 @@ dontblock:
        }
        if (orig_resid == uio->uio_resid && orig_resid &&
            (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
-               sbunlock(&so->so_rcv);
+               sbunlock(so, &so->so_rcv);
                sounlock(s);
                goto restart;
        }
@@ -1004,7 +1004,7 @@ dontblock:
        if (flagsp)
                *flagsp |= flags;
 release:
-       sbunlock(&so->so_rcv);
+       sbunlock(so, &so->so_rcv);
        sounlock(s);
        return (error);
 }
@@ -1049,7 +1049,7 @@ sorflush(struct socket *so)
        /* with SB_NOINTR and M_WAITOK sblock() must not fail */
        KASSERT(error == 0);
        socantrcvmore(so);
-       sbunlock(sb);
+       sbunlock(so, sb);
        aso.so_proto = pr;
        aso.so_rcv = *sb;
        memset(sb, 0, sizeof (*sb));
@@ -1110,7 +1110,7 @@ sosplice(struct socket *so, int fd, off_
                }
                if (so->so_sp->ssp_socket)
                        sounsplice(so, so->so_sp->ssp_socket, 1);
-               sbunlock(&so->so_rcv);
+               sbunlock(so, &so->so_rcv);
                return (0);
        }
 
@@ -1139,7 +1139,7 @@ sosplice(struct socket *so, int fd, off_
                return (error);
        }
        if ((error = sblock(so, &sosp->so_snd, M_WAITOK)) != 0) {
-               sbunlock(&so->so_rcv);
+               sbunlock(so, &so->so_rcv);
                FRELE(fp, curproc);
                return (error);
        }
@@ -1183,8 +1183,8 @@ sosplice(struct socket *so, int fd, off_
        }
 
  release:
-       sbunlock(&sosp->so_snd);
-       sbunlock(&so->so_rcv);
+       sbunlock(sosp, &sosp->so_snd);
+       sbunlock(so, &so->so_rcv);
        FRELE(fp, curproc);
        return (error);
 }
Index: kern/uipc_socket2.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.86
diff -u -p -r1.86 uipc_socket2.c
--- kern/uipc_socket2.c 11 Aug 2017 21:24:19 -0000      1.86
+++ kern/uipc_socket2.c 22 Nov 2017 11:22:37 -0000
@@ -342,7 +342,6 @@ sblock(struct socket *so, struct sockbuf
 {
        int error, prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH;
 
-       KERNEL_ASSERT_LOCKED();
        soassertlocked(so);
 
        if ((sb->sb_flags & SB_LOCK) == 0) {
@@ -363,9 +362,9 @@ sblock(struct socket *so, struct sockbuf
 }
 
 void
-sbunlock(struct sockbuf *sb)
+sbunlock(struct socket *so, struct sockbuf *sb)
 {
-       KERNEL_ASSERT_LOCKED();
+       soassertlocked(so);
 
        sb->sb_flags &= ~SB_LOCK;
        if (sb->sb_flags & SB_WANT) {
Index: sys/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
retrieving revision 1.77
diff -u -p -r1.77 socketvar.h
--- sys/socketvar.h     4 Nov 2017 14:13:53 -0000       1.77
+++ sys/socketvar.h     22 Nov 2017 11:22:49 -0000
@@ -244,7 +244,7 @@ soreadable(struct socket *so)
 int sblock(struct socket *, struct sockbuf *, int);
 
 /* release lock on sockbuf sb */
-void sbunlock(struct sockbuf *);
+void sbunlock(struct socket *, struct sockbuf *);
 
 #define        SB_EMPTY_FIXUP(sb) do {                                         
\
        if ((sb)->sb_mb == NULL) {                                      \

Reply via email to