Commit f3964599 authored by Jann Horn's avatar Jann Horn Committed by Linus Torvalds

mm/gup_benchmark: take the mmap lock around GUP

To be safe against concurrent changes to the VMA tree, we must take the
mmap lock around GUP operations (excluding the GUP-fast family of
operations, which will take the mmap lock by themselves if necessary).

This code is only for testing, and it's only reachable by root through
debugfs, so this doesn't really have any impact; however, if we want to
add lockdep asserts into the GUP path, we need to have clean locking here.
Signed-off-by: default avatarJann Horn <jannh@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarJohn Hubbard <jhubbard@nvidia.com>
Acked-by: default avatarMichel Lespinasse <walken@google.com>
Cc: "Eric W . Biederman" <ebiederm@xmission.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Link: https://lkml.kernel.org/r/CAG48ez3SG6ngZLtasxJ6LABpOnqCz5-QHqb0B4k44TQ8F9n6+w@mail.gmail.comSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fb8090b6
...@@ -72,6 +72,8 @@ static int __gup_benchmark_ioctl(unsigned int cmd, ...@@ -72,6 +72,8 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
int nr; int nr;
struct page **pages; struct page **pages;
int ret = 0; int ret = 0;
bool needs_mmap_lock =
cmd != GUP_FAST_BENCHMARK && cmd != PIN_FAST_BENCHMARK;
if (gup->size > ULONG_MAX) if (gup->size > ULONG_MAX)
return -EINVAL; return -EINVAL;
...@@ -81,6 +83,11 @@ static int __gup_benchmark_ioctl(unsigned int cmd, ...@@ -81,6 +83,11 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
if (!pages) if (!pages)
return -ENOMEM; return -ENOMEM;
if (needs_mmap_lock && mmap_read_lock_killable(current->mm)) {
ret = -EINTR;
goto free_pages;
}
i = 0; i = 0;
nr = gup->nr_pages_per_call; nr = gup->nr_pages_per_call;
start_time = ktime_get(); start_time = ktime_get();
...@@ -120,9 +127,8 @@ static int __gup_benchmark_ioctl(unsigned int cmd, ...@@ -120,9 +127,8 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
pages + i, NULL); pages + i, NULL);
break; break;
default: default:
kvfree(pages);
ret = -EINVAL; ret = -EINVAL;
goto out; goto unlock;
} }
if (nr <= 0) if (nr <= 0)
...@@ -150,8 +156,11 @@ static int __gup_benchmark_ioctl(unsigned int cmd, ...@@ -150,8 +156,11 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
end_time = ktime_get(); end_time = ktime_get();
gup->put_delta_usec = ktime_us_delta(end_time, start_time); gup->put_delta_usec = ktime_us_delta(end_time, start_time);
unlock:
if (needs_mmap_lock)
mmap_read_unlock(current->mm);
free_pages:
kvfree(pages); kvfree(pages);
out:
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment