The branch main has been updated by jhb:

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

commit 314cb279959b08811543612a715e47266f685c7b
Author:     John Baldwin <j...@freebsd.org>
AuthorDate: 2024-10-31 20:32:31 +0000
Commit:     John Baldwin <j...@freebsd.org>
CommitDate: 2024-10-31 20:32:31 +0000

    mbuf: Don't force all M_EXTPG mbufs to be read-only
    
    Some M_EXTPG mbufs are read-only (e.g. those backing sendfile
    requests), but others are not.  Add a flags argument to
    mb_alloc_ext_pgs that can be used to set M_RDONLY when needed rather
    than setting it unconditionally.  Update mb_unmapped_to_ext to
    preserve M_RDONLY from the unmapped mbuf.
    
    Reviewed by:    gallatin
    Differential Revision:  https://reviews.freebsd.org/D46783
---
 sys/dev/cxgbe/cxgbei/icl_cxgbei.c | 2 +-
 sys/dev/cxgbe/tom/t4_cpl_io.c     | 2 +-
 sys/dev/iscsi/icl_soft.c          | 2 +-
 sys/dev/nvmf/nvmf_tcp.c           | 2 +-
 sys/fs/nfsclient/nfs_clrpcops.c   | 2 +-
 sys/kern/kern_mbuf.c              | 9 +++++----
 sys/kern/kern_sendfile.c          | 2 +-
 sys/kern/uipc_mbuf.c              | 4 ++--
 sys/sys/mbuf.h                    | 2 +-
 9 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c 
b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
index ab1428c06d87..c8592807f843 100644
--- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
@@ -651,7 +651,7 @@ icl_cxgbei_conn_pdu_append_bio(struct icl_conn *ic, struct 
icl_pdu *ip,
                while (len > 0) {
                        if (m == NULL) {
                                m = mb_alloc_ext_pgs(flags & ~ICL_NOCOPY,
-                                   cxgbei_free_mext_pg);
+                                   cxgbei_free_mext_pg, 0);
                                if (__predict_false(m == NULL))
                                        return (ENOMEM);
                                atomic_add_int(&icp->ref_cnt, 1);
diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c
index 0a40bbda3f3f..8cafac61fa8b 100644
--- a/sys/dev/cxgbe/tom/t4_cpl_io.c
+++ b/sys/dev/cxgbe/tom/t4_cpl_io.c
@@ -2126,7 +2126,7 @@ alloc_aiotx_mbuf(struct kaiocb *job, int len)
                if (npages < 0)
                        break;
 
-               m = mb_alloc_ext_pgs(M_WAITOK, aiotx_free_pgs);
+               m = mb_alloc_ext_pgs(M_WAITOK, aiotx_free_pgs, M_RDONLY);
                m->m_epg_1st_off = pgoff;
                m->m_epg_npgs = npages;
                if (npages == 1) {
diff --git a/sys/dev/iscsi/icl_soft.c b/sys/dev/iscsi/icl_soft.c
index 832ff8135ec5..812793a9fba3 100644
--- a/sys/dev/iscsi/icl_soft.c
+++ b/sys/dev/iscsi/icl_soft.c
@@ -1139,7 +1139,7 @@ icl_soft_conn_pdu_append_bio(struct icl_conn *ic, struct 
icl_pdu *request,
                while (len > 0) {
                        if (m == NULL) {
                                m = mb_alloc_ext_pgs(flags & ~ICL_NOCOPY,
-                                   icl_soft_free_mext_pg);
+                                   icl_soft_free_mext_pg, 0);
                                if (__predict_false(m == NULL))
                                        return (ENOMEM);
                                atomic_add_int(&isp->ref_cnt, 1);
diff --git a/sys/dev/nvmf/nvmf_tcp.c b/sys/dev/nvmf/nvmf_tcp.c
index 22275aaa835b..2e33334b92ee 100644
--- a/sys/dev/nvmf/nvmf_tcp.c
+++ b/sys/dev/nvmf/nvmf_tcp.c
@@ -884,7 +884,7 @@ nvmf_tcp_mext_pg(void *arg, int how)
        struct nvmf_tcp_command_buffer *cb = arg;
        struct mbuf *m;
 
-       m = mb_alloc_ext_pgs(how, nvmf_tcp_free_mext_pg);
+       m = mb_alloc_ext_pgs(how, nvmf_tcp_free_mext_pg, M_RDONLY);
        m->m_ext.ext_arg1 = cb;
        tcp_hold_command_buffer(cb);
        return (m);
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 7540893ce63c..e1c02a71939b 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -9402,7 +9402,7 @@ nfsm_split(struct mbuf *mp, uint64_t xfer)
        if (pgno == m->m_epg_npgs)
                panic("nfsm_split: eroneous ext_pgs mbuf");
 
-       m2 = mb_alloc_ext_pgs(M_WAITOK, mb_free_mext_pgs);
+       m2 = mb_alloc_ext_pgs(M_WAITOK, mb_free_mext_pgs, 0);
        m2->m_epg_flags |= EPG_FLAG_ANON;
 
        /*
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index 5c1c5b095449..73c98209474a 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -1014,7 +1014,8 @@ _mb_unmapped_to_ext(struct mbuf *m)
 
                ref_inc++;
                m_extadd(m_new, (char *)sf_buf_kva(sf), PAGE_SIZE,
-                   mb_unmapped_free_mext, sf, mref, M_RDONLY, EXT_SFBUF);
+                   mb_unmapped_free_mext, sf, mref, m->m_flags & M_RDONLY,
+                   EXT_SFBUF);
                m_new->m_data += segoff;
                m_new->m_len = seglen;
 
@@ -1119,7 +1120,7 @@ mb_unmapped_to_ext(struct mbuf *top)
  * freed.
  */
 struct mbuf *
-mb_alloc_ext_pgs(int how, m_ext_free_t ext_free)
+mb_alloc_ext_pgs(int how, m_ext_free_t ext_free, int flags)
 {
        struct mbuf *m;
 
@@ -1137,7 +1138,7 @@ mb_alloc_ext_pgs(int how, m_ext_free_t ext_free)
        m->m_epg_tls = NULL;
        m->m_epg_so = NULL;
        m->m_data = NULL;
-       m->m_flags |= (M_EXT | M_RDONLY | M_EXTPG);
+       m->m_flags |= M_EXT | M_EXTPG | flags;
        m->m_ext.ext_flags = EXT_FLAG_EMBREF;
        m->m_ext.ext_count = 1;
        m->m_ext.ext_size = 0;
@@ -1709,7 +1710,7 @@ mb_alloc_ext_plus_pages(int len, int how)
        vm_page_t pg;
        int i, npgs;
 
-       m = mb_alloc_ext_pgs(how, mb_free_mext_pgs);
+       m = mb_alloc_ext_pgs(how, mb_free_mext_pgs, 0);
        if (m == NULL)
                return (NULL);
        m->m_epg_flags |= EPG_FLAG_ANON;
diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
index 323e7fcde07b..05a820fe5ac1 100644
--- a/sys/kern/kern_sendfile.c
+++ b/sys/kern/kern_sendfile.c
@@ -1003,7 +1003,7 @@ retry_space:
                                ext_pgs_idx++;
                                if (ext_pgs_idx == max_pgs) {
                                        m0 = mb_alloc_ext_pgs(M_WAITOK,
-                                           sendfile_free_mext_pg);
+                                           sendfile_free_mext_pg, M_RDONLY);
 
                                        if (flags & SF_NOCACHE) {
                                                m0->m_ext.ext_flags |=
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index f6ce9b5cc74b..f3e2f13e89ec 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1887,7 +1887,7 @@ m_uiotombuf_nomap(struct uio *uio, int how, int len, int 
maxseg, int flags)
         * ciphersuites.
         */
        if (__predict_false(total == 0)) {
-               mb = mb_alloc_ext_pgs(how, mb_free_mext_pgs);
+               mb = mb_alloc_ext_pgs(how, mb_free_mext_pgs, 0);
                if (mb == NULL)
                        return (NULL);
                mb->m_epg_flags = EPG_FLAG_ANON;
@@ -1899,7 +1899,7 @@ m_uiotombuf_nomap(struct uio *uio, int how, int len, int 
maxseg, int flags)
         */
        m = NULL;
        while (total > 0) {
-               mb = mb_alloc_ext_pgs(how, mb_free_mext_pgs);
+               mb = mb_alloc_ext_pgs(how, mb_free_mext_pgs, 0);
                if (mb == NULL)
                        goto failed;
                if (m == NULL)
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index ab494a76833e..434f29feddcf 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -808,7 +808,7 @@ void                 mb_dupcl(struct mbuf *, struct mbuf *);
 void            mb_free_ext(struct mbuf *);
 void            mb_free_extpg(struct mbuf *);
 void            mb_free_mext_pgs(struct mbuf *);
-struct mbuf    *mb_alloc_ext_pgs(int, m_ext_free_t);
+struct mbuf    *mb_alloc_ext_pgs(int, m_ext_free_t, int);
 struct mbuf    *mb_alloc_ext_plus_pages(int, int);
 struct mbuf    *mb_mapped_to_unmapped(struct mbuf *, int, int, int,
                    struct mbuf **);

Reply via email to