mm/msync: exit early when the flags is an MS_ASYNC and start < vm_start
authorNikita Ermakov <sh1r4s3@mail.si-head.nl>
Fri, 30 Apr 2021 05:55:41 +0000 (22:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Apr 2021 18:20:37 +0000 (11:20 -0700)
If an unmapped region was found and the flag is MS_ASYNC (without
MS_INVALIDATE) there is nothing to do and the result would be always
-ENOMEM, so return immediately.

Link: https://lkml.kernel.org/r/20201025092901.56399-1-sh1r4s3@mail.si-head.nl
Signed-off-by: Nikita Ermakov <sh1r4s3@mail.si-head.nl>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/msync.c

index 69c6d20..137d1c1 100644 (file)
@@ -55,7 +55,9 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
                goto out;
        /*
         * If the interval [start,end) covers some unmapped address ranges,
-        * just ignore them, but return -ENOMEM at the end.
+        * just ignore them, but return -ENOMEM at the end. Besides, if the
+        * flag is MS_ASYNC (w/o MS_INVALIDATE) the result would be -ENOMEM
+        * anyway and there is nothing left to do, so return immediately.
         */
        mmap_read_lock(mm);
        vma = find_vma(mm, start);
@@ -69,6 +71,8 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
                        goto out_unlock;
                /* Here start < vma->vm_end. */
                if (start < vma->vm_start) {
+                       if (flags == MS_ASYNC)
+                               goto out_unlock;
                        start = vma->vm_start;
                        if (start >= end)
                                goto out_unlock;