Skip to content

Commit 5afb4bf

Browse files
isilenceaxboe
authored andcommitted
io_uring/rsrc: fix folio unpinning
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]>
1 parent 88a8006 commit 5afb4bf

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
@@ -112,8 +112,11 @@ static void io_release_ubuf(void *priv)
112112
struct io_mapped_ubuf *imu = priv;
113113
unsigned int i;
114114

115-
for (i = 0; i < imu->nr_bvecs; i++)
116-
unpin_user_page(imu->bvec[i].bv_page);
115+
for (i = 0; i < imu->nr_bvecs; i++) {
116+
struct folio *folio = page_folio(imu->bvec[i].bv_page);
117+
118+
unpin_user_folio(folio, 1);
119+
}
117120
}
118121

119122
static struct io_mapped_ubuf *io_alloc_imu(struct io_ring_ctx *ctx,
@@ -840,8 +843,10 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
840843
if (ret) {
841844
if (imu)
842845
io_free_imu(ctx, imu);
843-
if (pages)
844-
unpin_user_pages(pages, nr_pages);
846+
if (pages) {
847+
for (i = 0; i < nr_pages; i++)
848+
unpin_user_folio(page_folio(pages[i]), 1);
849+
}
845850
io_cache_free(&ctx->node_cache, node);
846851
node = ERR_PTR(ret);
847852
}

0 commit comments

Comments
 (0)