From: Jens Axboe <axboe@kernel.dk>
To: io-uring@vger.kernel.org
Cc: dw@davidwei.uk, hengyul@cs.unc.edu, Jens Axboe <axboe@kernel.dk>,
stable@vger.kernel.org
Subject: [PATCH 2/2] io_uring/memmap: only charge pinned user memory to RLIMIT_MEMLOCK
Date: Wed, 7 Oct 2026 15:38:57 -0600 [thread overview]
Message-ID: <20261007213903.445430-3-axboe@kernel.dk> (raw)
In-Reply-To: <20261007213903.445430-1-axboe@kernel.dk>
io_create_region() charges every region to RLIMIT_MEMLOCK. This was
correct when the only region type was the user provided parameter region, but the SQ/CQ
rings and provided buffer rings have since been converted to regions as
well. Those we have tradionally excluded from that. Kernel allocated
ring memory is memcg accounted, and never counted against the memlock
limit. Since 6.14 an unprivileged user runs out of the 8MB default after
a couple of dozen rings.
Charge RLIMIT_MEMLOCK only for regions backed by pinned user memory, which
is what the limit is for, and leave kernel allocations to memcg. User
provided ring memory keeps being charged, it is pinned.
Reported-by: Hengyu Liang <hengyul@cs.unc.edu>
Link: https://lore.kernel.org/io-uring/20261006125732.3425762-1-hengyul@cs.unc.edu/
Fixes: 8078486e1d53 ("io_uring: use region api for SQ")
Fixes: 81a4058e0cd0 ("io_uring: use region api for CQ")
Fixes: ef62de3c4ad5 ("io_uring/kbuf: use region api for pbuf rings")
Cc: stable@vger.kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
io_uring/memmap.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/io_uring/memmap.c b/io_uring/memmap.c
index 23e8a85111bc..da2328b52b38 100644
--- a/io_uring/memmap.c
+++ b/io_uring/memmap.c
@@ -105,7 +105,7 @@ void io_free_region(struct user_struct *user, struct io_mapped_region *mr)
}
if ((mr->flags & IO_REGION_F_VMAP) && mr->ptr)
vunmap(mr->ptr);
- if (mr->nr_pages && user)
+ if ((mr->flags & IO_REGION_F_USER_PROVIDED) && user)
__io_unaccount_mem(user, mr->nr_pages);
memset(mr, 0, sizeof(*mr));
@@ -132,11 +132,12 @@ static int io_region_init_ptr(struct io_mapped_region *mr)
}
static int io_region_pin_pages(struct io_mapped_region *mr,
- struct io_uring_region_desc *reg)
+ struct io_uring_region_desc *reg,
+ struct user_struct *user)
{
size_t size = io_region_size(mr);
struct page **pages;
- int nr_pages;
+ int nr_pages, ret;
pages = io_pin_pages(reg->user_addr, size, &nr_pages);
if (IS_ERR(pages))
@@ -144,6 +145,16 @@ static int io_region_pin_pages(struct io_mapped_region *mr,
if (WARN_ON_ONCE(nr_pages != mr->nr_pages))
return -EFAULT;
+ /* pinned user memory is what RLIMIT_MEMLOCK is for */
+ if (user) {
+ ret = __io_account_mem(user, nr_pages);
+ if (ret) {
+ unpin_user_pages(pages, nr_pages);
+ kvfree(pages);
+ return ret;
+ }
+ }
+
mr->pages = pages;
mr->flags |= IO_REGION_F_USER_PROVIDED;
return 0;
@@ -207,15 +218,14 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
return -EOVERFLOW;
nr_pages = reg->size >> PAGE_SHIFT;
- if (ctx->user) {
- ret = __io_account_mem(ctx->user, nr_pages);
- if (ret)
- return ret;
- }
mr->nr_pages = nr_pages;
+ /*
+ * Only pinned user memory counts against RLIMIT_MEMLOCK, kernel
+ * allocated regions are memcg accounted through GFP_KERNEL_ACCOUNT.
+ */
if (reg->flags & IORING_MEM_REGION_TYPE_USER)
- ret = io_region_pin_pages(mr, reg);
+ ret = io_region_pin_pages(mr, reg, ctx->user);
else
ret = io_region_allocate_pages(mr, reg, mmap_offset);
if (ret)
--
2.55.0
next prev parent reply other threads:[~2026-10-07 21:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 21:38 [PATCHSET 0/2] Fix memlock account for kernel backed memory Jens Axboe
2026-10-07 21:38 ` [PATCH 1/2] Revert "io_uring/memmap: account the pages a compound region really uses" Jens Axboe
2026-10-07 21:38 ` Jens Axboe [this message]
2026-10-08 4:57 ` [PATCH 2/2] io_uring/memmap: only charge pinned user memory to RLIMIT_MEMLOCK Hengyu Liang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261007213903.445430-3-axboe@kernel.dk \
--to=axboe@kernel.dk \
--cc=dw@davidwei.uk \
--cc=hengyul@cs.unc.edu \
--cc=io-uring@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox