Re: [PATCH 07/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN
On 11/25/19 12:44 AM, kbuild test robot wrote: > Hi John, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on rdma/for-next] > [cannot apply to v5.4 next-20191122] > [if your patch is applied to the wrong git tree, please drop us a note to help > improve the system. BTW, we also suggest to use '--base' option to specify the > base tree in git format-patch, please see > https://stackoverflow.com/a/37406982] > > url: > https://github.com/0day-ci/linux/commits/John-Hubbard/pin_user_pages-reduced-risk-series-for-Linux-5-5/20191125-125637 > base: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git for-next > config: arm-randconfig-a001-20191125 (attached as .config) > compiler: arm-linux-gnueabi-gcc (GCC) 7.4.0 > reproduce: > wget > https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O > ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > GCC_VERSION=7.4.0 make.cross ARCH=arm > > If you fix the issue, kindly add following tag > Reported-by: kbuild test robot > > All errors (new ones prefixed by >>): > >mm/gup.o: In function `pin_user_pages_remote': >>> mm/gup.c:2528: undefined reference to `get_user_pages_remote' > > vim +2528 mm/gup.c This, and the other (sh) report, is due to !CONFIG_MMU lacking a get_user_pages_remote(), but pin_user_pages_remote() needs it for a (temporary) implementation. I'll post the fix, in v2. thanks, -- John Hubbard NVIDIA
Re: [PATCH 07/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN
Hi John, Thank you for the patch! Yet something to improve: [auto build test ERROR on rdma/for-next] [cannot apply to v5.4 next-20191122] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/John-Hubbard/pin_user_pages-reduced-risk-series-for-Linux-5-5/20191125-125637 base: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git for-next config: arm-randconfig-a001-20191125 (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 7.4.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.4.0 make.cross ARCH=arm If you fix the issue, kindly add following tag Reported-by: kbuild test robot All errors (new ones prefixed by >>): mm/gup.o: In function `pin_user_pages_remote': >> mm/gup.c:2528: undefined reference to `get_user_pages_remote' vim +2528 mm/gup.c 2507 2508 /** 2509 * pin_user_pages_remote() - pin pages of a remote process (task != current) 2510 * 2511 * For now, this is a placeholder function, until various call sites are 2512 * converted to use the correct get_user_pages*() or pin_user_pages*() API. So, 2513 * this is identical to get_user_pages_remote(). 2514 * 2515 * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It 2516 * is NOT intended for Case 2 (RDMA: long-term pins). 2517 */ 2518 long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, 2519 unsigned long start, unsigned long nr_pages, 2520 unsigned int gup_flags, struct page **pages, 2521 struct vm_area_struct **vmas, int *locked) 2522 { 2523 /* 2524 * This is a placeholder, until the pin functionality is activated. 2525 * Until then, just behave like the corresponding get_user_pages*() 2526 * routine. 2527 */ > 2528 return get_user_pages_remote(tsk, mm, start, nr_pages, > gup_flags, pages, 2529 vmas, locked); 2530 } 2531 EXPORT_SYMBOL(pin_user_pages_remote); 2532 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 07/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN
Hi John, Thank you for the patch! Yet something to improve: [auto build test ERROR on rdma/for-next] [also build test ERROR on v5.4 next-20191122] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/John-Hubbard/pin_user_pages-reduced-risk-series-for-Linux-5-5/20191125-125637 base: https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git for-next config: sh-rsk7269_defconfig (attached as .config) compiler: sh4-linux-gcc (GCC) 7.4.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.4.0 make.cross ARCH=sh If you fix the issue, kindly add following tag Reported-by: kbuild test robot All errors (new ones prefixed by >>): mm/gup.o: In function `pin_user_pages_remote': >> gup.c:(.text+0x4a4): undefined reference to `get_user_pages_remote' --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org Intel Corporation .config.gz Description: application/gzip
[PATCH 07/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN
Introduce pin_user_pages*() variations of get_user_pages*() calls, and also pin_longterm_pages*() variations. For now, these are placeholder calls, until the various call sites are converted to use the correct get_user_pages*() or pin_user_pages*() API. These variants will eventually all set FOLL_PIN, which is also introduced, and thoroughly documented. pin_user_pages() pin_user_pages_remote() pin_user_pages_fast() All pages that are pinned via the above calls, must be unpinned via put_user_page(). The underlying rules are: * FOLL_PIN is a gup-internal flag, so the call sites should not directly set it. That behavior is enforced with assertions. * Call sites that want to indicate that they are going to do DirectIO ("DIO") or something with similar characteristics, should call a get_user_pages()-like wrapper call that sets FOLL_PIN. These wrappers will: * Start with "pin_user_pages" instead of "get_user_pages". That makes it easy to find and audit the call sites. * Set FOLL_PIN * For pages that are received via FOLL_PIN, those pages must be returned via put_user_page(). Thanks to Jan Kara and Vlastimil Babka for explaining the 4 cases in this documentation. (I've reworded it and expanded upon it.) Reviewed-by: Jan Kara Reviewed-by: Mike Rapoport # Documentation Reviewed-by: Jérôme Glisse Cc: Jonathan Corbet Cc: Ira Weiny Signed-off-by: John Hubbard --- Documentation/core-api/index.rst | 1 + Documentation/core-api/pin_user_pages.rst | 233 ++ include/linux/mm.h| 63 -- mm/gup.c | 153 -- 4 files changed, 416 insertions(+), 34 deletions(-) create mode 100644 Documentation/core-api/pin_user_pages.rst diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index ab0eae1c153a..413f7d7c8642 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -31,6 +31,7 @@ Core utilities generic-radix-tree memory-allocation mm-api + pin_user_pages gfp_mask-from-fs-io timekeeping boot-time-mm diff --git a/Documentation/core-api/pin_user_pages.rst b/Documentation/core-api/pin_user_pages.rst new file mode 100644 index ..4f26637a5005 --- /dev/null +++ b/Documentation/core-api/pin_user_pages.rst @@ -0,0 +1,233 @@ +.. SPDX-License-Identifier: GPL-2.0 + + +pin_user_pages() and related calls + + +.. contents:: :local: + +Overview + + +This document describes the following functions: :: + + pin_user_pages + pin_user_pages_fast + pin_user_pages_remote + +Basic description of FOLL_PIN += + +FOLL_PIN and FOLL_LONGTERM are flags that can be passed to the get_user_pages*() +("gup") family of functions. FOLL_PIN has significant interactions and +interdependencies with FOLL_LONGTERM, so both are covered here. + +FOLL_PIN is internal to gup, meaning that it should not appear at the gup call +sites. This allows the associated wrapper functions (pin_user_pages*() and +others) to set the correct combination of these flags, and to check for problems +as well. + +FOLL_LONGTERM, on the other hand, *is* allowed to be set at the gup call sites. +This is in order to avoid creating a large number of wrapper functions to cover +all combinations of get*(), pin*(), FOLL_LONGTERM, and more. Also, the +pin_user_pages*() APIs are clearly distinct from the get_user_pages*() APIs, so +that's a natural dividing line, and a good point to make separate wrapper calls. +In other words, use pin_user_pages*() for DMA-pinned pages, and +get_user_pages*() for other cases. There are four cases described later on in +this document, to further clarify that concept. + +FOLL_PIN and FOLL_GET are mutually exclusive for a given gup call. However, +multiple threads and call sites are free to pin the same struct pages, via both +FOLL_PIN and FOLL_GET. It's just the call site that needs to choose one or the +other, not the struct page(s). + +The FOLL_PIN implementation is nearly the same as FOLL_GET, except that FOLL_PIN +uses a different reference counting technique. + +FOLL_PIN is a prerequisite to FOLL_LONGTGERM. Another way of saying that is, +FOLL_LONGTERM is a specific case, more restrictive case of FOLL_PIN. + +Which flags are set by each wrapper +=== + +For these pin_user_pages*() functions, FOLL_PIN is OR'd in with whatever gup +flags the caller provides. The caller is required to pass in a non-null struct +pages* array, and the function then pin pages by incrementing each by a special +value. For now, that value is +1, just like get_user_pages*().:: + + Function + + pin_user_pages FOLL_PIN is always set internally by this function. + pin_user_pages_fast FOLL_PIN is always set internally by this function. +