This allows the get_user_pages_fast slow path to release the mmap_sem
before blocking.

Signed-off-by: Andrea Arcangeli <aarca...@redhat.com>
---
 arch/mips/mm/gup.c  |  8 +++-----
 arch/s390/mm/gup.c  |  6 ++----
 arch/sh/mm/gup.c    |  6 ++----
 arch/sparc/mm/gup.c |  6 ++----
 arch/x86/mm/gup.c   |  7 +++----
 mm/gup.c            |  6 ++----
 mm/util.c           | 10 ++--------
 7 files changed, 16 insertions(+), 33 deletions(-)

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 @@ slow_irqon:
        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 @@ int get_user_pages_fast(unsigned long start, int nr_pages, 
int write,
        /* 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 @@ slow_irqon:
                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 @@ slow:
                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 d754782..4548dd8 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -388,10 +388,9 @@ slow_irqon:
                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 d616811..da200a1 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1252,10 +1252,8 @@ int get_user_pages_fast(unsigned long start, int 
nr_pages, int write,
                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 __weak get_user_pages_fast(unsigned long start,
                                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);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to