aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2024-10-31 20:32:31 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2024-10-31 20:32:31 +0000
commit314cb279959b08811543612a715e47266f685c7b (patch)
tree53037ff3092df219b7380b943ccd0c961c724b7f
parent7ab1a32cd43cbae61ad4dd435d6a482bbf61cb52 (diff)
downloadsrc-314cb279959b.tar.gz
src-314cb279959b.zip
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
-rw-r--r--sys/dev/cxgbe/cxgbei/icl_cxgbei.c2
-rw-r--r--sys/dev/cxgbe/tom/t4_cpl_io.c2
-rw-r--r--sys/dev/iscsi/icl_soft.c2
-rw-r--r--sys/dev/nvmf/nvmf_tcp.c2
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c2
-rw-r--r--sys/kern/kern_mbuf.c9
-rw-r--r--sys/kern/kern_sendfile.c2
-rw-r--r--sys/kern/uipc_mbuf.c4
-rw-r--r--sys/sys/mbuf.h2
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 **);