mm: gup: use get_user_pages_unlocked within get_user_pages_fast This allows the get_user_pages_fast slow path to release the mmap_sem before blocking. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Andres Lagar-Cavilla <andreslc@google.com> Cc: Peter Feiner <pfeiner@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index 70795a6..349995d 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c
@@ -301,11 +301,9 @@ start += nr << PAGE_SHIFT; pages += nr; - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - (end - start) >> PAGE_SHIFT, - write, 0, pages, NULL); - up_read(&mm->mmap_sem); + ret = get_user_pages_unlocked(current, mm, start, + (end - start) >> PAGE_SHIFT, + write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) {
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 639fce46..5c586c7 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c
@@ -235,10 +235,8 @@ /* Try to get the remaining pages with get_user_pages */ start += nr << PAGE_SHIFT; pages += nr; - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - nr_pages - nr, write, 0, pages, NULL); - up_read(&mm->mmap_sem); + ret = get_user_pages_unlocked(current, mm, start, + nr_pages - nr, write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) ret = (ret < 0) ? nr : ret + nr;
diff --git a/arch/sh/mm/gup.c b/arch/sh/mm/gup.c index 37458f3..e15f52a 100644 --- a/arch/sh/mm/gup.c +++ b/arch/sh/mm/gup.c
@@ -257,10 +257,8 @@ start += nr << PAGE_SHIFT; pages += nr; - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - (end - start) >> PAGE_SHIFT, write, 0, pages, NULL); - up_read(&mm->mmap_sem); + ret = get_user_pages_unlocked(current, mm, start, + (end - start) >> PAGE_SHIFT, write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) {
diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index ae6ce38..2e5c4fc 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c
@@ -249,10 +249,8 @@ start += nr << PAGE_SHIFT; pages += nr; - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - (end - start) >> PAGE_SHIFT, write, 0, pages, NULL); - up_read(&mm->mmap_sem); + ret = get_user_pages_unlocked(current, mm, start, + (end - start) >> PAGE_SHIFT, write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) {
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index 224b142..89df70e 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c
@@ -388,10 +388,9 @@ start += nr << PAGE_SHIFT; pages += nr; - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - (end - start) >> PAGE_SHIFT, write, 0, pages, NULL); - up_read(&mm->mmap_sem); + ret = get_user_pages_unlocked(current, mm, start, + (end - start) >> PAGE_SHIFT, + write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) {
diff --git a/mm/gup.c b/mm/gup.c index dad5875..c2da116 100644 --- a/mm/gup.c +++ b/mm/gup.c
@@ -1243,10 +1243,8 @@ start += nr << PAGE_SHIFT; pages += nr; - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - nr_pages - nr, write, 0, pages, NULL); - up_read(&mm->mmap_sem); + ret = get_user_pages_unlocked(current, mm, start, + nr_pages - nr, write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) {
diff --git a/mm/util.c b/mm/util.c index fec39d4..f3ef639 100644 --- a/mm/util.c +++ b/mm/util.c
@@ -240,14 +240,8 @@ int nr_pages, int write, struct page **pages) { struct mm_struct *mm = current->mm; - int ret; - - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, nr_pages, - write, 0, pages, NULL); - up_read(&mm->mmap_sem); - - return ret; + return get_user_pages_unlocked(current, mm, start, nr_pages, + write, 0, pages); } EXPORT_SYMBOL_GPL(get_user_pages_fast);