RE: find_get_page() VS pin_user_pages()

From: Teterevkov, Ivan
Date: Wed Apr 12 2023 - 05:43:57 EST


From: David Hildenbrand <david@xxxxxxxxxx>

> On 11.04.23 21:43, Teterevkov, Ivan wrote:
> >
> > I am studying the pin_user_pages*() family of functions, and I wonder if the
> > outlined workflow requires it. The hugepages do not page out, but they can move
> > as they may be allocated with GFP_HIGHUSER_MOVABLE. However, find_get_page()
> > must increment the page reference counter without mapping and prevent it from
> > moving. In particular, https://docs.kernel.org/mm/page_migration.html:
>
> I suspect that find_get_page() is not the kind of interface you want to
> use for the purpose you describe. find_get_page() is a wrapper around
> pagecache_get_page() and seems more like a helper for implementing an fs
> (looking at the users and the fact that it only considers pages that are
> in the pagecache).
>
> Instead, you might want to mmap the memfd and pass the user space
> address range to the ioctl. There, you'd call pin_user_pages_*().
>
> In general, for long-term pinning a page (possibly keeping the page
> pinned forever, controlled by user space, which seems to be what you are
> doing) you want so use pin_user_pages() with FOLL_LONGTERM. That will
> try migrating the page off of e.g., ZONE_MOVABLE or MIGRATE_CMA, where
> movability has to be guaranteed.
>

Thanks, David. As I am trying to outline to Alistair in another thread, our
application is designed with the kernel module driving memory allocation,
preferably backed by mappable hugepages. The kernel module might tell DMA about
the pages before the originating userspace application maps them so that the
kernel module does not have the start address for pin_user_pages*() at hand.

I believe that find_get_page() happens to work for the application because it
is backed by a file created by hugetlb_file_setup(). However, we should
consider aligning it with the API, as you explained above and stop abusing
find_get_page().

Thanks,
Ivan