mm/gup: introduce pin_user_pages_fast_only()
This is the FOLL_PIN equivalent of __get_user_pages_fast(), except with a more descriptive name, and gup_flags instead of a boolean "write" in the argument list. Signed-off-by: John Hubbard <jhubbard@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: David Airlie <airlied@linux.ie> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: "Joonas Lahtinen" <joonas.lahtinen@linux.intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Souptick Joarder <jrdr.linux@gmail.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: http://lkml.kernel.org/r/20200519002124.2025955-4-jhubbard@nvidia.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
376a34efa4
commit
104acc3276
@ -1827,6 +1827,8 @@ extern int mprotect_fixup(struct vm_area_struct *vma,
|
|||||||
*/
|
*/
|
||||||
int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||||
struct page **pages);
|
struct page **pages);
|
||||||
|
int pin_user_pages_fast_only(unsigned long start, int nr_pages,
|
||||||
|
unsigned int gup_flags, struct page **pages);
|
||||||
/*
|
/*
|
||||||
* per-process(per-mm_struct) statistics.
|
* per-process(per-mm_struct) statistics.
|
||||||
*/
|
*/
|
||||||
|
36
mm/gup.c
36
mm/gup.c
@ -2917,6 +2917,42 @@ int pin_user_pages_fast(unsigned long start, int nr_pages,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pin_user_pages_fast);
|
EXPORT_SYMBOL_GPL(pin_user_pages_fast);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the FOLL_PIN equivalent of __get_user_pages_fast(). Behavior is the
|
||||||
|
* same, except that this one sets FOLL_PIN instead of FOLL_GET.
|
||||||
|
*
|
||||||
|
* The API rules are the same, too: no negative values may be returned.
|
||||||
|
*/
|
||||||
|
int pin_user_pages_fast_only(unsigned long start, int nr_pages,
|
||||||
|
unsigned int gup_flags, struct page **pages)
|
||||||
|
{
|
||||||
|
int nr_pinned;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FOLL_GET and FOLL_PIN are mutually exclusive. Note that the API
|
||||||
|
* rules require returning 0, rather than -errno:
|
||||||
|
*/
|
||||||
|
if (WARN_ON_ONCE(gup_flags & FOLL_GET))
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
|
* FOLL_FAST_ONLY is required in order to match the API description of
|
||||||
|
* this routine: no fall back to regular ("slow") GUP.
|
||||||
|
*/
|
||||||
|
gup_flags |= (FOLL_PIN | FOLL_FAST_ONLY);
|
||||||
|
nr_pinned = internal_get_user_pages_fast(start, nr_pages, gup_flags,
|
||||||
|
pages);
|
||||||
|
/*
|
||||||
|
* This routine is not allowed to return negative values. However,
|
||||||
|
* internal_get_user_pages_fast() *can* return -errno. Therefore,
|
||||||
|
* correct for that here:
|
||||||
|
*/
|
||||||
|
if (nr_pinned < 0)
|
||||||
|
nr_pinned = 0;
|
||||||
|
|
||||||
|
return nr_pinned;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pin_user_pages_fast_only);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pin_user_pages_remote() - pin pages of a remote process (task != current)
|
* pin_user_pages_remote() - pin pages of a remote process (task != current)
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user