mm/madvise: split out madvise() behavior execution
authorSeongJae Park <sj@kernel.org>
Thu, 6 Feb 2025 06:15:16 +0000 (22:15 -0800)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 17 Mar 2025 05:06:04 +0000 (22:06 -0700)
Split out the madvise behavior applying logic from do_madvise() to make
it easier to reuse from the following change.

Link: https://lkml.kernel.org/r/20250206061517.2958-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Liam R. Howlett <howlett@gmail.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/madvise.c

index ca858b8a837b34efdb871bc30e0f1b495c840899..6e31e3202d7191744483725252996d08d51cc788 100644 (file)
@@ -1639,6 +1639,35 @@ static bool is_valid_madvise(unsigned long start, size_t len_in, int behavior)
        return true;
 }
 
+static int madvise_do_behavior(struct mm_struct *mm,
+               unsigned long start, size_t len_in, size_t len, int behavior)
+{
+       struct blk_plug plug;
+       unsigned long end;
+       int error;
+
+#ifdef CONFIG_MEMORY_FAILURE
+       if (behavior == MADV_HWPOISON || behavior == MADV_SOFT_OFFLINE)
+               return madvise_inject_error(behavior, start, start + len_in);
+#endif
+       start = untagged_addr_remote(mm, start);
+       end = start + len;
+
+       blk_start_plug(&plug);
+       switch (behavior) {
+       case MADV_POPULATE_READ:
+       case MADV_POPULATE_WRITE:
+               error = madvise_populate(mm, start, end, behavior);
+               break;
+       default:
+               error = madvise_walk_vmas(mm, start, end, behavior,
+                                         madvise_vma_behavior);
+               break;
+       }
+       blk_finish_plug(&plug);
+       return error;
+}
+
 /*
  * The madvise(2) system call.
  *
@@ -1716,7 +1745,6 @@ int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int beh
        unsigned long end;
        int error;
        size_t len;
-       struct blk_plug plug;
 
        if (!is_valid_madvise(start, len_in, behavior))
                return -EINVAL;
@@ -1730,28 +1758,7 @@ int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int beh
        error = madvise_lock(mm, behavior);
        if (error)
                return error;
-
-#ifdef CONFIG_MEMORY_FAILURE
-       if (behavior == MADV_HWPOISON || behavior == MADV_SOFT_OFFLINE)
-               return madvise_inject_error(behavior, start, start + len_in);
-#endif
-
-       start = untagged_addr_remote(mm, start);
-       end = start + len;
-
-       blk_start_plug(&plug);
-       switch (behavior) {
-       case MADV_POPULATE_READ:
-       case MADV_POPULATE_WRITE:
-               error = madvise_populate(mm, start, end, behavior);
-               break;
-       default:
-               error = madvise_walk_vmas(mm, start, end, behavior,
-                                         madvise_vma_behavior);
-               break;
-       }
-       blk_finish_plug(&plug);
-
+       error = madvise_do_behavior(mm, start, len_in, len, behavior);
        madvise_unlock(mm, behavior);
 
        return error;