Jens Axboe <axboe@xxxxxxxxx> writes: > Rather than use remap_pfn_range() for this and manually free later, > switch to using vm_insert_pages() and have it Just Work. > > If possible, allocate a single compound page that covers the range that > is needed. If that works, then we can just use page_address() on that > page. If we fail to get a compound page, allocate single pages and use > vmap() to map them into the kernel virtual address space. > > This just covers the rings/sqes, the other remaining user of the mmap > remap_pfn_range() user will be converted separately. Once that is done, > we can kill the old alloc/free code. > > Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> > --- > io_uring/io_uring.c | 136 +++++++++++++++++++++++++++++++++++++++++--- > io_uring/io_uring.h | 2 + > 2 files changed, 130 insertions(+), 8 deletions(-) > > diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c > index 104899522bc5..982545ca23f9 100644 > --- a/io_uring/io_uring.c > +++ b/io_uring/io_uring.c > @@ -2594,6 +2594,33 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, > return READ_ONCE(rings->cq.head) == READ_ONCE(rings->cq.tail) ? ret : 0; > } > > +static void io_pages_unmap(void *ptr, struct page ***pages, > + unsigned short *npages) > +{ > + bool do_vunmap = false; > + > + if (*npages) { > + struct page **to_free = *pages; > + int i; > + > + /* > + * Only did vmap for the non-compound multiple page case. > + * For the compound page, we just need to put the head. > + */ > + if (PageCompound(to_free[0])) > + *npages = 1; > + else if (*npages > 1) > + do_vunmap = true; > + for (i = 0; i < *npages; i++) > + put_page(to_free[i]); > + } Hi Jens, wouldn't it be simpler to handle the compound case separately as a folio? Then you folio_put the compound page here and just handle the non-continuous case after. -- Gabriel Krisman Bertazi