diff mbox series

[v2,12/35] mm: separate mmap locked assertion from find_vma

Message ID 20220128131006.67712-13-michel@lespinasse.org (mailing list archive)
State New
Headers show
Series Speculative page faults | expand

Commit Message

Michel Lespinasse Jan. 28, 2022, 1:09 p.m. UTC
This adds a new __find_vma() function, which implements find_vma minus
the mmap_assert_locked() assertion.

find_vma() is then implemented as an inline wrapper around __find_vma().

Signed-off-by: Michel Lespinasse <michel@lespinasse.org>
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 4 ++--
 include/linux/mm.h                    | 9 ++++++++-
 mm/mmap.c                             | 5 ++---
 3 files changed, 12 insertions(+), 6 deletions(-)

Comments

kernel test robot Jan. 29, 2022, 12:08 a.m. UTC | #1
Hi Michel,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.17-rc1 next-20220128]
[cannot apply to tip/x86/mm arm64/for-next/core powerpc/next hnaz-mm/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Michel-Lespinasse/Speculative-page-faults/20220128-212122
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 145d9b498fc827b79c1260b4caa29a8e59d4c2b9
config: arm-randconfig-c002-20220124 (https://download.01.org/0day-ci/archive/20220129/202201290752.GKB0XPLn-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 33b45ee44b1f32ffdbc995e6fec806271b4b3ba4)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/d9d603df22594c13d340d1036653e0b039f975eb
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Michel-Lespinasse/Speculative-page-faults/20220128-212122
        git checkout d9d603df22594c13d340d1036653e0b039f975eb
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> mm/nommu.c:666:24: error: redefinition of 'find_vma'
   struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
                          ^
   include/linux/mm.h:2759:24: note: previous definition is here
   struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
                          ^
   1 error generated.


vim +/find_vma +666 mm/nommu.c

8feae13110d60cc David Howells     2009-01-08  661  
8feae13110d60cc David Howells     2009-01-08  662  /*
8feae13110d60cc David Howells     2009-01-08  663   * look up the first VMA in which addr resides, NULL if none
c1e8d7c6a7a682e Michel Lespinasse 2020-06-08  664   * - should be called with mm->mmap_lock at least held readlocked
8feae13110d60cc David Howells     2009-01-08  665   */
8feae13110d60cc David Howells     2009-01-08 @666  struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
8feae13110d60cc David Howells     2009-01-08  667  {
8feae13110d60cc David Howells     2009-01-08  668  	struct vm_area_struct *vma;
8feae13110d60cc David Howells     2009-01-08  669  
8feae13110d60cc David Howells     2009-01-08  670  	/* check the cache first */
615d6e8756c8714 Davidlohr Bueso   2014-04-07  671  	vma = vmacache_find(mm, addr);
615d6e8756c8714 Davidlohr Bueso   2014-04-07  672  	if (likely(vma))
8feae13110d60cc David Howells     2009-01-08  673  		return vma;
8feae13110d60cc David Howells     2009-01-08  674  
e922c4c5360980b Namhyung Kim      2011-05-24  675  	/* trawl the list (there may be multiple mappings in which addr
8feae13110d60cc David Howells     2009-01-08  676  	 * resides) */
e922c4c5360980b Namhyung Kim      2011-05-24  677  	for (vma = mm->mmap; vma; vma = vma->vm_next) {
8feae13110d60cc David Howells     2009-01-08  678  		if (vma->vm_start > addr)
8feae13110d60cc David Howells     2009-01-08  679  			return NULL;
8feae13110d60cc David Howells     2009-01-08  680  		if (vma->vm_end > addr) {
615d6e8756c8714 Davidlohr Bueso   2014-04-07  681  			vmacache_update(addr, vma);
8feae13110d60cc David Howells     2009-01-08  682  			return vma;
8feae13110d60cc David Howells     2009-01-08  683  		}
8feae13110d60cc David Howells     2009-01-08  684  	}
8feae13110d60cc David Howells     2009-01-08  685  
8feae13110d60cc David Howells     2009-01-08  686  	return NULL;
8feae13110d60cc David Howells     2009-01-08  687  }
8feae13110d60cc David Howells     2009-01-08  688  EXPORT_SYMBOL(find_vma);
8feae13110d60cc David Howells     2009-01-08  689  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Michel Lespinasse Jan. 29, 2022, 12:33 a.m. UTC | #2
On Sat, Jan 29, 2022 at 08:08:15AM +0800, kernel test robot wrote:
> >> mm/nommu.c:666:24: error: redefinition of 'find_vma'
>    struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
>                           ^
>    include/linux/mm.h:2759:24: note: previous definition is here
>    struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
>                           ^
>    1 error generated.

Nice catch. The following amended patch should fix this:
(I only added the mm/nommu.c changes)

----------------------------------- 8< ----------------------------------

mm: separate mmap locked assertion from find_vma

This adds a new __find_vma() function, which implements find_vma minus
the mmap_assert_locked() assertion.

find_vma() is then implemented as an inline wrapper around __find_vma().

Signed-off-by: Michel Lespinasse <michel@lespinasse.org>
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 4 ++--
 include/linux/mm.h                    | 9 ++++++++-
 mm/mmap.c                             | 5 ++---
 mm/nommu.c                            | 4 ++--
 4 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 5ae812d60abe..94ab71a9b493 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -515,7 +515,7 @@ static void error_print_context(struct drm_i915_error_state_buf *m,
 }
 
 static struct i915_vma_coredump *
-__find_vma(struct i915_vma_coredump *vma, const char *name)
+__i915_find_vma(struct i915_vma_coredump *vma, const char *name)
 {
 	while (vma) {
 		if (strcmp(vma->name, name) == 0)
@@ -529,7 +529,7 @@ __find_vma(struct i915_vma_coredump *vma, const char *name)
 static struct i915_vma_coredump *
 find_batch(const struct intel_engine_coredump *ee)
 {
-	return __find_vma(ee->vma, "batch");
+	return __i915_find_vma(ee->vma, "batch");
 }
 
 static void error_print_engine(struct drm_i915_error_state_buf *m,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 4600dbb98cef..6f7712179503 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2751,10 +2751,17 @@ extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
 #endif
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
-extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
+extern struct vm_area_struct * __find_vma(struct mm_struct * mm, unsigned long addr);
 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
 					     struct vm_area_struct **pprev);
 
+static inline
+struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+{
+	mmap_assert_locked(mm);
+	return __find_vma(mm, addr);
+}
+
 /**
  * find_vma_intersection() - Look up the first VMA which intersects the interval
  * @mm: The process address space.
diff --git a/mm/mmap.c b/mm/mmap.c
index 1e8fdb0b51ed..b09a2c875507 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2276,12 +2276,11 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
 EXPORT_SYMBOL(get_unmapped_area);
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
-struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+struct vm_area_struct *__find_vma(struct mm_struct *mm, unsigned long addr)
 {
 	struct rb_node *rb_node;
 	struct vm_area_struct *vma;
 
-	mmap_assert_locked(mm);
 	/* Check the cache first. */
 	vma = vmacache_find(mm, addr);
 	if (likely(vma))
@@ -2308,7 +2307,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
 	return vma;
 }
 
-EXPORT_SYMBOL(find_vma);
+EXPORT_SYMBOL(__find_vma);
 
 /*
  * Same as find_vma, but also return a pointer to the previous VMA in *pprev.
diff --git a/mm/nommu.c b/mm/nommu.c
index 55a9e48a7a02..8d2582ff319f 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -663,7 +663,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
  * look up the first VMA in which addr resides, NULL if none
  * - should be called with mm->mmap_lock at least held readlocked
  */
-struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+struct vm_area_struct *__find_vma(struct mm_struct *mm, unsigned long addr)
 {
 	struct vm_area_struct *vma;
 
@@ -685,7 +685,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
 
 	return NULL;
 }
-EXPORT_SYMBOL(find_vma);
+EXPORT_SYMBOL(__find_vma);
 
 /*
  * find a VMA
Matthew Wilcox Jan. 31, 2022, 2:44 p.m. UTC | #3
On Fri, Jan 28, 2022 at 05:09:43AM -0800, Michel Lespinasse wrote:
> This adds a new __find_vma() function, which implements find_vma minus
> the mmap_assert_locked() assertion.
> 
> find_vma() is then implemented as an inline wrapper around __find_vma().

You might like to take inspiration from the maple tree patches
where we assert that either the RCU lock is held or the mmap_lock
is held.
Michel Lespinasse Feb. 4, 2022, 10:41 p.m. UTC | #4
On Mon, Jan 31, 2022 at 02:44:55PM +0000, Matthew Wilcox wrote:
> On Fri, Jan 28, 2022 at 05:09:43AM -0800, Michel Lespinasse wrote:
> > This adds a new __find_vma() function, which implements find_vma minus
> > the mmap_assert_locked() assertion.
> > 
> > find_vma() is then implemented as an inline wrapper around __find_vma().
> 
> You might like to take inspiration from the maple tree patches
> where we assert that either the RCU lock is held or the mmap_lock
> is held.

I've been considering it, but I'm not sure we want to go that way:
it's not sufficient for the caller to have an RCU read lock,
they also need to do the proper mmap_seq_read_check() after
dereferencing the vma... So I think having this different set of
expectations for the two cases warrants using a different name
to keep things more explicit.

--
Michel "walken" Lespinasse
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 5ae812d60abe..94ab71a9b493 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -515,7 +515,7 @@  static void error_print_context(struct drm_i915_error_state_buf *m,
 }
 
 static struct i915_vma_coredump *
-__find_vma(struct i915_vma_coredump *vma, const char *name)
+__i915_find_vma(struct i915_vma_coredump *vma, const char *name)
 {
 	while (vma) {
 		if (strcmp(vma->name, name) == 0)
@@ -529,7 +529,7 @@  __find_vma(struct i915_vma_coredump *vma, const char *name)
 static struct i915_vma_coredump *
 find_batch(const struct intel_engine_coredump *ee)
 {
-	return __find_vma(ee->vma, "batch");
+	return __i915_find_vma(ee->vma, "batch");
 }
 
 static void error_print_engine(struct drm_i915_error_state_buf *m,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 4600dbb98cef..6f7712179503 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2751,10 +2751,17 @@  extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
 #endif
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
-extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
+extern struct vm_area_struct * __find_vma(struct mm_struct * mm, unsigned long addr);
 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
 					     struct vm_area_struct **pprev);
 
+static inline
+struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+{
+	mmap_assert_locked(mm);
+	return __find_vma(mm, addr);
+}
+
 /**
  * find_vma_intersection() - Look up the first VMA which intersects the interval
  * @mm: The process address space.
diff --git a/mm/mmap.c b/mm/mmap.c
index 1e8fdb0b51ed..b09a2c875507 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2276,12 +2276,11 @@  get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
 EXPORT_SYMBOL(get_unmapped_area);
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
-struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+struct vm_area_struct *__find_vma(struct mm_struct *mm, unsigned long addr)
 {
 	struct rb_node *rb_node;
 	struct vm_area_struct *vma;
 
-	mmap_assert_locked(mm);
 	/* Check the cache first. */
 	vma = vmacache_find(mm, addr);
 	if (likely(vma))
@@ -2308,7 +2307,7 @@  struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
 	return vma;
 }
 
-EXPORT_SYMBOL(find_vma);
+EXPORT_SYMBOL(__find_vma);
 
 /*
  * Same as find_vma, but also return a pointer to the previous VMA in *pprev.