On 10/31/19 4:35 PM, Ira Weiny wrote: > On Wed, Oct 30, 2019 at 03:49:19PM -0700, John Hubbard wrote: >> Convert process_vm_access to use the new pin_user_pages_remote() >> call, which sets FOLL_PIN. Setting FOLL_PIN is now required for >> code that requires tracking of pinned pages. >> >> Also, release the pages via put_user_page*(). >> >> Also, rename "pages" to "pinned_pages", as this makes for >> easier reading of process_vm_rw_single_vec(). > > Ok... but it made review a bit harder... > Yes, sorry about that. After dealing with "pages means struct page *[]" for all this time, having an "int pages" just was a step too far for me here. :) Thanks for working through it. thanks, John Hubbard NVIDIA > Reviewed-by: Ira Weiny <ira.weiny@xxxxxxxxx> > >> >> Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx> >> --- >> mm/process_vm_access.c | 28 +++++++++++++++------------- >> 1 file changed, 15 insertions(+), 13 deletions(-) >> >> diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c >> index 357aa7bef6c0..fd20ab675b85 100644 >> --- a/mm/process_vm_access.c >> +++ b/mm/process_vm_access.c >> @@ -42,12 +42,11 @@ static int process_vm_rw_pages(struct page **pages, >> if (copy > len) >> copy = len; >> >> - if (vm_write) { >> + if (vm_write) >> copied = copy_page_from_iter(page, offset, copy, iter); >> - set_page_dirty_lock(page); >> - } else { >> + else >> copied = copy_page_to_iter(page, offset, copy, iter); >> - } >> + >> len -= copied; >> if (copied < copy && iov_iter_count(iter)) >> return -EFAULT; >> @@ -96,7 +95,7 @@ static int process_vm_rw_single_vec(unsigned long addr, >> flags |= FOLL_WRITE; >> >> while (!rc && nr_pages && iov_iter_count(iter)) { >> - int pages = min(nr_pages, max_pages_per_loop); >> + int pinned_pages = min(nr_pages, max_pages_per_loop); >> int locked = 1; >> size_t bytes; >> >> @@ -106,14 +105,15 @@ static int process_vm_rw_single_vec(unsigned long addr, >> * current/current->mm >> */ >> down_read(&mm->mmap_sem); >> - pages = get_user_pages_remote(task, mm, pa, pages, flags, >> - process_pages, NULL, &locked); >> + pinned_pages = pin_user_pages_remote(task, mm, pa, pinned_pages, >> + flags, process_pages, >> + NULL, &locked); >> if (locked) >> up_read(&mm->mmap_sem); >> - if (pages <= 0) >> + if (pinned_pages <= 0) >> return -EFAULT; >> >> - bytes = pages * PAGE_SIZE - start_offset; >> + bytes = pinned_pages * PAGE_SIZE - start_offset; >> if (bytes > len) >> bytes = len; >> >> @@ -122,10 +122,12 @@ static int process_vm_rw_single_vec(unsigned long addr, >> vm_write); >> len -= bytes; >> start_offset = 0; >> - nr_pages -= pages; >> - pa += pages * PAGE_SIZE; >> - while (pages) >> - put_page(process_pages[--pages]); >> + nr_pages -= pinned_pages; >> + pa += pinned_pages * PAGE_SIZE; >> + >> + /* If vm_write is set, the pages need to be made dirty: */ >> + put_user_pages_dirty_lock(process_pages, pinned_pages, >> + vm_write); >> } >> >> return rc; >> -- >> 2.23.0 >>