Skip to content

Commit 68c678c

Browse files
isilencesmb49
authored andcommitted
io_uring/rsrc: fix folio unpinning
BugLink: https://bugs.launchpad.net/bugs/2121266 Commit 5afb4bf9fc62d828647647ec31745083637132e4 upstream. syzbot complains about an unmapping failure: [ 108.070381][ T14] kernel BUG at mm/gup.c:71! [ 108.070502][ T14] Internal error: Oops - BUG: 00000000f2000800 [#1] SMP [ 108.123672][ T14] Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20250221-8.fc42 02/21/2025 [ 108.127458][ T14] Workqueue: iou_exit io_ring_exit_work [ 108.174205][ T14] Call trace: [ 108.175649][ T14] sanity_check_pinned_pages+0x7cc/0x7d0 (P) [ 108.178138][ T14] unpin_user_page+0x80/0x10c [ 108.180189][ T14] io_release_ubuf+0x84/0xf8 [ 108.182196][ T14] io_free_rsrc_node+0x250/0x57c [ 108.184345][ T14] io_rsrc_data_free+0x148/0x298 [ 108.186493][ T14] io_sqe_buffers_unregister+0x84/0xa0 [ 108.188991][ T14] io_ring_ctx_free+0x48/0x480 [ 108.191057][ T14] io_ring_exit_work+0x764/0x7d8 [ 108.193207][ T14] process_one_work+0x7e8/0x155c [ 108.195431][ T14] worker_thread+0x958/0xed8 [ 108.197561][ T14] kthread+0x5fc/0x75c [ 108.199362][ T14] ret_from_fork+0x10/0x20 We can pin a tail page of a folio, but then io_uring will try to unpin the head page of the folio. While it should be fine in terms of keeping the page actually alive, mm folks say it's wrong and triggers a debug warning. Use unpin_user_folio() instead of unpin_user_page*. Cc: [email protected] Debugged-by: David Hildenbrand <[email protected]> Reported-by: [email protected] Closes: https://lkml.kernel.org/r/[email protected] Fixes: a8edbb4 ("io_uring/rsrc: enable multi-hugepage buffer coalescing") Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/io-uring/a28b0f87339ac2acf14a645dad1e95bbcbf18acd.1750771718.git.asml.silence@gmail.com/ [axboe: adapt to current tree, massage commit message] Signed-off-by: Jens Axboe <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> [nwager: Context change due to v6.13 commit: 7029acd ("io_uring/rsrc: get rid of per-ring io_rsrc_node list")] Signed-off-by: Noah Wager <[email protected]> Signed-off-by: Stefan Bader <[email protected]>
1 parent 8e216ad commit 68c678c

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

io_uring/rsrc.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,11 @@ static void io_buffer_unmap(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
110110

111111
if (!refcount_dec_and_test(&imu->refs))
112112
return;
113-
for (i = 0; i < imu->nr_bvecs; i++)
114-
unpin_user_page(imu->bvec[i].bv_page);
113+
for (i = 0; i < imu->nr_bvecs; i++) {
114+
struct folio *folio = page_folio(imu->bvec[i].bv_page);
115+
116+
unpin_user_folio(folio, 1);
117+
}
115118
if (imu->acct_pages)
116119
io_unaccount_mem(ctx, imu->acct_pages);
117120
kvfree(imu);
@@ -793,8 +796,10 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
793796
done:
794797
if (ret) {
795798
kvfree(imu);
796-
if (pages)
797-
unpin_user_pages(pages, nr_pages);
799+
if (pages) {
800+
for (i = 0; i < nr_pages; i++)
801+
unpin_user_folio(page_folio(pages[i]), 1);
802+
}
798803
if (node)
799804
io_put_rsrc_node(ctx, node);
800805
node = ERR_PTR(ret);

0 commit comments

Comments
 (0)