diff options
author | John Hubbard <[email protected]> | 2020-06-03 15:56:34 -0700 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2020-06-03 20:09:42 -0700 |
commit | 104acc327648b347d1716374586803e82fa1dc95 (patch) | |
tree | 8dc73114b720c35f0af7521fdf0300bae94dab98 | |
parent | 376a34efa4eeb699d285c1a741b186d44b44c429 (diff) |
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 <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Reviewed-by: Chris Wilson <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: David Airlie <[email protected]>
Cc: Jani Nikula <[email protected]>
Cc: "Joonas Lahtinen" <[email protected]>
Cc: Matthew Auld <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Rodrigo Vivi <[email protected]>
Cc: Souptick Joarder <[email protected]>
Cc: Tvrtko Ursulin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r-- | include/linux/mm.h | 2 | ||||
-rw-r--r-- | mm/gup.c | 36 |
2 files changed, 38 insertions, 0 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index e6b884715da1..6c236c5b0015 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -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, 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. */ @@ -2917,6 +2917,42 @@ int pin_user_pages_fast(unsigned long start, int nr_pages, } 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) * |