io_uring/rsrc: add huge page accounting for registered buffers
authorJens Axboe <axboe@kernel.dk>
Sat, 24 Jan 2026 17:02:41 +0000 (10:02 -0700)
committerJens Axboe <axboe@kernel.dk>
Thu, 14 May 2026 14:11:53 +0000 (08:11 -0600)
commitdf0a52537c0f95d5441eb0ba1bdbd2d864e6def9
tree81d8afef583e3689371453bf697c579ab85bc49f
parent899bea8248cee35d54760a5e7d61a76af8e64411
io_uring/rsrc: add huge page accounting for registered buffers

Track huge page references in a per-ring xarray to prevent double
accounting when the same huge page is used by multiple registered
buffers, either within the same ring or across cloned rings.

When registering buffers backed by huge pages, we need to account for
RLIMIT_MEMLOCK. But if multiple buffers share the same huge page (common
with cloned buffers), we must not account for the same page multiple
times. Similarly, we must only unaccount when the last reference to a
huge page is released.

Maintain a per-ring xarray (hpage_acct) that tracks reference counts for
each huge page. When registering a buffer, for each unique huge page,
increment its accounting reference count, and only account pages that
are newly added.

When unregistering a buffer, for each unique huge page, decrement its
refcount. Once the refcount hits zero, the page is unaccounted.

Note: any account is done against the ctx->user that was assigned when
the ring was setup. As before, if root is running the operation, no
accounting is done.

With these changes, any use of imu->acct_pages is also dead, hence kill
it from struct io_mapped_ubuf. This shrinks it from 56b to 48b on a
64-bit arch. Additionally, hpage_already_acct() is gone, which was an
O(M*M) scan over current + previous registrations.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/linux/io_uring_types.h
io_uring/io_uring.c
io_uring/rsrc.c
io_uring/rsrc.h