Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+25 −15
Original line number Original line Diff line number Diff line
@@ -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)


		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,
 	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,
	/* 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++)