On 27.08.22 10:36, John Hubbard wrote: > pin_user_page() is an externally-usable version of try_grab_page(), but > with semantics that match get_page(), so that it can act as a drop-in > replacement for get_page(). Specifically, pin_user_page() has a void > return type. > > pin_user_page() elevates a page's refcount using FOLL_PIN rules. This > means that the caller must release the page via unpin_user_page(). > > Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx> > --- > include/linux/mm.h | 1 + > mm/gup.c | 33 +++++++++++++++++++++++++++++++++ > 2 files changed, 34 insertions(+) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 982f2607180b..85a105157334 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1869,6 +1869,7 @@ long pin_user_pages_remote(struct mm_struct *mm, > long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas); > +void pin_user_page(struct page *page); > long pin_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas); > diff --git a/mm/gup.c b/mm/gup.c > index 5abdaf487460..245ccb41ed8c 100644 > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -3213,6 +3213,39 @@ long pin_user_pages(unsigned long start, unsigned long nr_pages, > } > EXPORT_SYMBOL(pin_user_pages); > > +/** > + * pin_user_page() - apply a FOLL_PIN reference to a page > + * > + * @page: the page to be pinned. > + * > + * This is similar to get_user_pages(), except that the page's refcount is > + * elevated using FOLL_PIN, instead of FOLL_GET. > + * > + * IMPORTANT: The caller must release the page via unpin_user_page(). > + * > + */ > +void pin_user_page(struct page *page) > +{ > + struct folio *folio = page_folio(page); > + > + WARN_ON_ONCE(folio_ref_count(folio) <= 0); > + We should warn if the page is anon and !exclusive. I assume the intend is to use pin_user_page() only to duplicate pins, right? -- Thanks, David / dhildenb