The branch main has been updated by glebius:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b93e930ca233e3b3cb5e017bc9b09086f8909800

commit b93e930ca233e3b3cb5e017bc9b09086f8909800
Author:     Gleb Smirnoff <gleb...@freebsd.org>
AuthorDate: 2025-07-25 20:06:28 +0000
Commit:     Gleb Smirnoff <gleb...@freebsd.org>
CommitDate: 2025-07-25 20:06:28 +0000

    sendfile: retire M_BLOCKED
    
    Follow unix(4) commit 51ac5ee0d57f and retire M_BLOCKED for TCP sockets as
    well.  The M_BLOCKED flag was introduced back 2016 together with non-
    blocking sendfile(2).  It marked mbufs in a sending socket buffer that
    could be ready to sent, but are sitting behind an M_NOTREADY mbuf(s), that
    blocks them.
    
    You may consider this flag as an INVARIANT flag that helped to ensure
    socket buffer consistency.  Or maybe the socket code was so convoluted
    back then, that it was unclear if sbfree() may be called on an mbuf that
    is in the middle of the buffer, and I decided to introduce the flag to
    protect against that.  With today state of socket buffer code it became
    clear that the latter cannot happen.  And this commit adds an assertion
    proving that.
    
    Reviewed by:            markj
    Differential Revision:  https://reviews.freebsd.org/D50728
---
 sys/dev/cxgbe/tom/t4_cpl_io.c |  6 +++---
 sys/dev/cxgbe/tom/t4_tls.c    |  4 ++--
 sys/kern/uipc_ktls.c          |  2 +-
 sys/kern/uipc_sockbuf.c       | 42 +++++++++++++++---------------------------
 sys/kern/uipc_socket.c        |  2 +-
 sys/sys/sockbuf.h             |  2 --
 6 files changed, 22 insertions(+), 36 deletions(-)

diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c
index 8547f21586e1..7a6b1cbdd736 100644
--- a/sys/dev/cxgbe/tom/t4_cpl_io.c
+++ b/sys/dev/cxgbe/tom/t4_cpl_io.c
@@ -703,7 +703,7 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep, int 
drop)
                for (m = sndptr; m != NULL; m = m->m_next) {
                        int n;
 
-                       if ((m->m_flags & M_NOTAVAIL) != 0)
+                       if ((m->m_flags & M_NOTREADY) != 0)
                                break;
                        if (m->m_flags & M_EXTPG) {
 #ifdef KERN_TLS
@@ -787,7 +787,7 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep, int 
drop)
 
                /* nothing to send */
                if (plen == 0) {
-                       KASSERT(m == NULL || (m->m_flags & M_NOTAVAIL) != 0,
+                       KASSERT(m == NULL || (m->m_flags & M_NOTREADY) != 0,
                            ("%s: nothing to send, but m != NULL is ready",
                            __func__));
                        break;
@@ -880,7 +880,7 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep, int 
drop)
                toep->txsd_avail--;
 
                t4_l2t_send(sc, wr, toep->l2te);
-       } while (m != NULL && (m->m_flags & M_NOTAVAIL) == 0);
+       } while (m != NULL && (m->m_flags & M_NOTREADY) == 0);
 
        /* Send a FIN if requested, but only if there's no more data to send */
        if (m == NULL && toep->flags & TPF_SEND_FIN)
diff --git a/sys/dev/cxgbe/tom/t4_tls.c b/sys/dev/cxgbe/tom/t4_tls.c
index c6377980fca9..27c16b9988ae 100644
--- a/sys/dev/cxgbe/tom/t4_tls.c
+++ b/sys/dev/cxgbe/tom/t4_tls.c
@@ -563,7 +563,7 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int 
drop)
                 * If there is no ready data to send, wait until more
                 * data arrives.
                 */
-               if (m == NULL || (m->m_flags & M_NOTAVAIL) != 0) {
+               if (m == NULL || (m->m_flags & M_NOTREADY) != 0) {
                        if (sowwakeup)
                                sowwakeup_locked(so);
                        else
@@ -614,7 +614,7 @@ t4_push_ktls(struct adapter *sc, struct toepcb *toep, int 
drop)
 
                /* Shove if there is no additional data pending. */
                shove = ((m->m_next == NULL ||
-                   (m->m_next->m_flags & M_NOTAVAIL) != 0)) &&
+                   (m->m_next->m_flags & M_NOTREADY) != 0)) &&
                    (tp->t_flags & TF_MORETOCOME) == 0;
 
                if (sb->sb_flags & SB_AUTOSIZE &&
diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c
index ce09042abdac..66ce1b5a081d 100644
--- a/sys/kern/uipc_ktls.c
+++ b/sys/kern/uipc_ktls.c
@@ -1207,7 +1207,7 @@ sb_mark_notready(struct sockbuf *sb)
        for (; m != NULL; m = m->m_next) {
                KASSERT(m->m_nextpkt == NULL, ("%s: m_nextpkt != NULL",
                    __func__));
-               KASSERT((m->m_flags & M_NOTAVAIL) == 0, ("%s: mbuf not avail",
+               KASSERT((m->m_flags & M_NOTREADY) == 0, ("%s: mbuf not ready",
                    __func__));
                KASSERT(sb->sb_acc >= m->m_len, ("%s: sb_acc < m->m_len",
                    __func__));
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index ffaa9b800592..745702bd4a4f 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -195,14 +195,14 @@ int
 sbready(struct sockbuf *sb, struct mbuf *m0, int count)
 {
        struct mbuf *m;
-       u_int blocker;
+       bool blocker;
 
        SOCKBUF_LOCK_ASSERT(sb);
        KASSERT(sb->sb_fnrdy != NULL, ("%s: sb %p NULL fnrdy", __func__, sb));
        KASSERT(count > 0, ("%s: invalid count %d", __func__, count));
 
        m = m0;
-       blocker = (sb->sb_fnrdy == m) ? M_BLOCKED : 0;
+       blocker = (sb->sb_fnrdy == m);
 
        while (count > 0) {
                KASSERT(m->m_flags & M_NOTREADY,
@@ -217,8 +217,7 @@ sbready(struct sockbuf *sb, struct mbuf *m0, int count)
                        m->m_epg_nrdy = 0;
                } else
                        count--;
-
-               m->m_flags &= ~(M_NOTREADY | blocker);
+               m->m_flags &= ~M_NOTREADY;
                if (blocker)
                        sb->sb_acc += m->m_len;
                m = m->m_next;
@@ -240,12 +239,8 @@ sbready(struct sockbuf *sb, struct mbuf *m0, int count)
        }
 
        /* This one was blocking all the queue. */
-       for (; m && (m->m_flags & M_NOTREADY) == 0; m = m->m_next) {
-               KASSERT(m->m_flags & M_BLOCKED,
-                   ("%s: m %p !M_BLOCKED", __func__, m));
-               m->m_flags &= ~M_BLOCKED;
+       for (; m && (m->m_flags & M_NOTREADY) == 0; m = m->m_next)
                sb->sb_acc += m->m_len;
-       }
 
        sb->sb_fnrdy = m;
        sbready_compress(sb, m0, m);
@@ -269,8 +264,7 @@ sballoc(struct sockbuf *sb, struct mbuf *m)
                        sb->sb_fnrdy = m;
                else
                        sb->sb_acc += m->m_len;
-       } else
-               m->m_flags |= M_BLOCKED;
+       }
 
        if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA)
                sb->sb_ctl += m->m_len;
@@ -287,29 +281,29 @@ sballoc(struct sockbuf *sb, struct mbuf *m)
 void
 sbfree(struct sockbuf *sb, struct mbuf *m)
 {
+       struct mbuf *n;
 
 #if 0  /* XXX: not yet: soclose() call path comes here w/o lock. */
        SOCKBUF_LOCK_ASSERT(sb);
 #endif
-
        sb->sb_ccc -= m->m_len;
 
-       if (!(m->m_flags & M_NOTAVAIL))
-               sb->sb_acc -= m->m_len;
-
        if (m == sb->sb_fnrdy) {
-               struct mbuf *n;
-
                KASSERT(m->m_flags & M_NOTREADY,
                    ("%s: m %p !M_NOTREADY", __func__, m));
 
                n = m->m_next;
                while (n != NULL && !(n->m_flags & M_NOTREADY)) {
-                       n->m_flags &= ~M_BLOCKED;
                        sb->sb_acc += n->m_len;
                        n = n->m_next;
                }
                sb->sb_fnrdy = n;
+       } else {
+               /* Assert that mbuf is not behind sb_fnrdy. */
+               for (n = sb->sb_fnrdy; n != NULL; n = n->m_next)
+                       KASSERT(n != m, ("%s: sb %p freeing %p behind sb_fnrdy",
+                           __func__, sb, m));
+               sb->sb_acc -= m->m_len;
        }
 
        if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA)
@@ -1129,13 +1123,7 @@ sbcheck(struct sockbuf *sb, const char *file, int line)
                        }
                        fnrdy = m;
                }
-               if (fnrdy) {
-                       if (!(m->m_flags & M_NOTAVAIL)) {
-                               printf("sb %p: fnrdy %p, m %p is avail\n",
-                                   sb, sb->sb_fnrdy, m);
-                               goto fail;
-                       }
-               } else
+               if (fnrdy == NULL)
                        acc += m->m_len;
                ccc += m->m_len;
                mbcnt += MSIZE;
@@ -1602,8 +1590,8 @@ sbcut_internal(struct sockbuf *sb, int len)
                        next = m->m_nextpkt;
                }
                if (m->m_len > len) {
-                       KASSERT(!(m->m_flags & M_NOTAVAIL),
-                           ("%s: m %p M_NOTAVAIL", __func__, m));
+                       KASSERT(!(m->m_flags & M_NOTREADY),
+                           ("%s: m %p M_NOTREADY", __func__, m));
                        m->m_len -= len;
                        m->m_data += len;
                        sb->sb_ccc -= len;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 4e8c179acee9..17b456deb71f 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -3342,7 +3342,7 @@ deliver:
                        for (m = sb->sb_mb;
                             m != NULL && m->m_len <= len;
                             m = m->m_next) {
-                               KASSERT(!(m->m_flags & M_NOTAVAIL),
+                               KASSERT(!(m->m_flags & M_NOTREADY),
                                    ("%s: m %p not available", __func__, m));
                                len -= m->m_len;
                                uio->uio_resid -= m->m_len;
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index 2fed44bc9825..b4593f38f592 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -210,8 +210,6 @@ typedef enum { SO_RCV, SO_SND } sb_which;
  * Socket buffer private mbuf(9) flags.
  */
 #define        M_NOTREADY      M_PROTO1        /* m_data not populated yet */
-#define        M_BLOCKED       M_PROTO2        /* M_NOTREADY in front of m */
-#define        M_NOTAVAIL      (M_NOTREADY | M_BLOCKED)
 
 void   sbappend(struct sockbuf *sb, struct mbuf *m, int flags);
 void   sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags);

Reply via email to