Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: gup: use get_user_pages_unlocked

This allows those get_user_pages calls to pass FAULT_FLAG_ALLOW_RETRY to
the page fault in order to release the mmap_sem during the I/O.

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>

authored by

Andrea Arcangeli and committed by
Linus Torvalds
7e339128 a7b78075

+10 -22
+2 -4
drivers/media/pci/ivtv/ivtv-udma.c
··· 124 124 } 125 125 126 126 /* Get user pages for DMA Xfer */ 127 - down_read(&current->mm->mmap_sem); 128 - err = get_user_pages(current, current->mm, 129 - user_dma.uaddr, user_dma.page_count, 0, 1, dma->map, NULL); 130 - up_read(&current->mm->mmap_sem); 127 + err = get_user_pages_unlocked(current, current->mm, 128 + user_dma.uaddr, user_dma.page_count, 0, 1, dma->map); 131 129 132 130 if (user_dma.page_count != err) { 133 131 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
+2 -5
drivers/scsi/st.c
··· 4551 4551 return -ENOMEM; 4552 4552 4553 4553 /* Try to fault in all of the necessary pages */ 4554 - down_read(&current->mm->mmap_sem); 4555 4554 /* rw==READ means read from drive, write into memory area */ 4556 - res = get_user_pages( 4555 + res = get_user_pages_unlocked( 4557 4556 current, 4558 4557 current->mm, 4559 4558 uaddr, 4560 4559 nr_pages, 4561 4560 rw == READ, 4562 4561 0, /* don't force */ 4563 - pages, 4564 - NULL); 4565 - up_read(&current->mm->mmap_sem); 4562 + pages); 4566 4563 4567 4564 /* Errors and no page mapped should return here */ 4568 4565 if (res < nr_pages)
+2 -4
drivers/video/fbdev/pvr2fb.c
··· 686 686 if (!pages) 687 687 return -ENOMEM; 688 688 689 - down_read(&current->mm->mmap_sem); 690 - ret = get_user_pages(current, current->mm, (unsigned long)buf, 691 - nr_pages, WRITE, 0, pages, NULL); 692 - up_read(&current->mm->mmap_sem); 689 + ret = get_user_pages_unlocked(current, current->mm, (unsigned long)buf, 690 + nr_pages, WRITE, 0, pages); 693 691 694 692 if (ret < nr_pages) { 695 693 nr_pages = ret;
+2 -5
mm/process_vm_access.c
··· 99 99 size_t bytes; 100 100 101 101 /* Get the pages we're interested in */ 102 - down_read(&mm->mmap_sem); 103 - pages = get_user_pages(task, mm, pa, pages, 104 - vm_write, 0, process_pages, NULL); 105 - up_read(&mm->mmap_sem); 106 - 102 + pages = get_user_pages_unlocked(task, mm, pa, pages, 103 + vm_write, 0, process_pages); 107 104 if (pages <= 0) 108 105 return -EFAULT; 109 106
+2 -4
net/ceph/pagevec.c
··· 23 23 if (!pages) 24 24 return ERR_PTR(-ENOMEM); 25 25 26 - down_read(&current->mm->mmap_sem); 27 26 while (got < num_pages) { 28 - rc = get_user_pages(current, current->mm, 27 + rc = get_user_pages_unlocked(current, current->mm, 29 28 (unsigned long)data + ((unsigned long)got * PAGE_SIZE), 30 - num_pages - got, write_page, 0, pages + got, NULL); 29 + num_pages - got, write_page, 0, pages + got); 31 30 if (rc < 0) 32 31 break; 33 32 BUG_ON(rc == 0); 34 33 got += rc; 35 34 } 36 - up_read(&current->mm->mmap_sem); 37 35 if (rc < 0) 38 36 goto fail; 39 37 return pages;