Commit 2f007e74 authored by Brice Goglin's avatar Brice Goglin Committed by Linus Torvalds

mm: don't vmalloc a huge page_to_node array for do_pages_stat()

do_pages_stat() does not need any page_to_node entry for real.  Just pass
the pointers to the user-space page address array and to the user-space
status array, and have do_pages_stat() traverse the former and fill the
latter directly.
Signed-off-by: default avatarBrice Goglin <Brice.Goglin@inria.fr>
Acked-by: default avatarChristoph Lameter <cl@linux-foundation.org>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e78bbfa8
...@@ -906,25 +906,33 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm, ...@@ -906,25 +906,33 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
} }
/* /*
* Determine the nodes of a list of pages. The addr in the pm array * Determine the nodes of an array of pages and store it in an array of status.
* must have been set to the virtual address of which we want to determine
* the node number.
*/ */
static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm) static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
const void __user * __user *pages,
int __user *status)
{ {
unsigned long i;
int err;
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
for ( ; pm->node != MAX_NUMNODES; pm++) { for (i = 0; i < nr_pages; i++) {
const void __user *p;
unsigned long addr;
struct vm_area_struct *vma; struct vm_area_struct *vma;
struct page *page; struct page *page;
int err;
err = -EFAULT; err = -EFAULT;
vma = find_vma(mm, pm->addr); if (get_user(p, pages+i))
goto out;
addr = (unsigned long) p;
vma = find_vma(mm, addr);
if (!vma) if (!vma)
goto set_status; goto set_status;
page = follow_page(vma, pm->addr, 0); page = follow_page(vma, addr, 0);
err = PTR_ERR(page); err = PTR_ERR(page);
if (IS_ERR(page)) if (IS_ERR(page))
...@@ -937,11 +945,13 @@ static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm) ...@@ -937,11 +945,13 @@ static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm)
err = page_to_nid(page); err = page_to_nid(page);
set_status: set_status:
pm->status = err; put_user(err, status+i);
} }
err = 0;
out:
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
return 0; return err;
} }
/* /*
...@@ -997,6 +1007,10 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, ...@@ -997,6 +1007,10 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
if (err) if (err)
goto out2; goto out2;
if (!nodes) {
err = do_pages_stat(mm, nr_pages, pages, status);
goto out2;
}
task_nodes = cpuset_mems_allowed(task); task_nodes = cpuset_mems_allowed(task);
...@@ -1045,11 +1059,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, ...@@ -1045,11 +1059,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
/* End marker */ /* End marker */
pm[nr_pages].node = MAX_NUMNODES; pm[nr_pages].node = MAX_NUMNODES;
if (nodes) err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL);
err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL);
else
err = do_pages_stat(mm, pm);
if (err >= 0) if (err >= 0)
/* Return status information */ /* Return status information */
for (i = 0; i < nr_pages; i++) for (i = 0; i < nr_pages; i++)
......
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