Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758795AbYJMUW5 (ORCPT ); Mon, 13 Oct 2008 16:22:57 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758410AbYJMUWk (ORCPT ); Mon, 13 Oct 2008 16:22:40 -0400 Received: from iona.labri.fr ([147.210.8.143]:48043 "EHLO iona.labri.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755187AbYJMUWi (ORCPT ); Mon, 13 Oct 2008 16:22:38 -0400 Message-ID: <48F3ADD4.60307@inria.fr> Date: Mon, 13 Oct 2008 22:21:40 +0200 From: Brice Goglin User-Agent: Mozilla-Thunderbird 2.0.0.16 (X11/20080724) MIME-Version: 1.0 To: Christoph Lameter CC: LKML , linux-mm@kvack.org, Andrew Morton , Nathalie Furmento Subject: [PATCH 2/5] mm: don't vmalloc a huge page_to_node array for do_pages_stat() References: <48F3AD47.1050301@inria.fr> In-Reply-To: <48F3AD47.1050301@inria.fr> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2775 Lines: 106 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: Brice Goglin --- mm/migrate.c | 40 +++++++++++++++++++++++++--------------- 1 files changed, 25 insertions(+), 15 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index e505b2f..e92e4f1 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -936,25 +936,33 @@ set_status: } /* - * Determine the nodes of a list of pages. The addr in the pm array - * must have been set to the virtual address of which we want to determine - * the node number. + * Determine the nodes of an array of pages and store it in an array of status. */ -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); - 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 page *page; - int err; 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) goto set_status; - page = follow_page(vma, pm->addr, 0); + page = follow_page(vma, addr, 0); err = PTR_ERR(page); if (IS_ERR(page)) @@ -967,11 +975,13 @@ static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm) err = page_to_nid(page); set_status: - pm->status = err; + put_user(err, status+i); } + err = 0; +out: up_read(&mm->mmap_sem); - return 0; + return err; } /* @@ -1027,6 +1037,10 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, if (err) goto out2; + if (!nodes) { + err = do_pages_stat(mm, nr_pages, pages, status); + goto out2; + } task_nodes = cpuset_mems_allowed(task); @@ -1075,11 +1089,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, /* End marker */ pm[nr_pages].node = MAX_NUMNODES; - if (nodes) - err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL); - else - err = do_pages_stat(mm, pm); - + err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL); if (err >= 0) /* Return status information */ for (i = 0; i < nr_pages; i++) -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/