From: Brice Goglin <Brice.Goglin@inria.fr>
To: Christoph Lameter <cl@linux-foundation.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
linux-mm@kvack.org, Andrew Morton <akpm@osdl.org>,
Nathalie Furmento <nathalie.furmento@labri.fr>
Subject: [PATCH 3/5] mm: extract do_pages_move() out of sys_move_pages()
Date: Mon, 13 Oct 2008 22:22:13 +0200 [thread overview]
Message-ID: <48F3ADF5.1060609@inria.fr> (raw)
In-Reply-To: <48F3AD47.1050301@inria.fr>
To prepare the chunking, move the sys_move_pages() code that
is used when nodes!=NULL into do_pages_move().
And rename do_move_pages() into do_move_page_to_node_array().
Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
---
mm/migrate.c | 152 +++++++++++++++++++++++++++++++++-------------------------
1 files changed, 86 insertions(+), 66 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index e92e4f1..dffc98b 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -858,9 +858,11 @@ static struct page *new_page_node(struct page *p, unsigned long private,
* Move a set of pages as indicated in the pm array. The addr
* field must be set to the virtual address of the page to be moved
* and the node number must contain a valid target node.
+ * The pm array ends with node = MAX_NUMNODES.
*/
-static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
- int migrate_all)
+static int do_move_page_to_node_array(struct mm_struct *mm,
+ struct page_to_node *pm,
+ int migrate_all)
{
int err;
struct page_to_node *pp;
@@ -936,6 +938,81 @@ set_status:
}
/*
+ * Migrate an array of page address onto an array of nodes and fill
+ * the corresponding array of status.
+ */
+static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
+ unsigned long nr_pages,
+ const void __user * __user *pages,
+ const int __user *nodes,
+ int __user *status, int flags)
+{
+ struct page_to_node *pm = NULL;
+ nodemask_t task_nodes;
+ int err = 0;
+ int i;
+
+ task_nodes = cpuset_mems_allowed(task);
+
+ /* Limit nr_pages so that the multiplication may not overflow */
+ if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
+ err = -E2BIG;
+ goto out;
+ }
+
+ pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
+ if (!pm) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Get parameters from user space and initialize the pm
+ * array. Return various errors if the user did something wrong.
+ */
+ for (i = 0; i < nr_pages; i++) {
+ const void __user *p;
+
+ err = -EFAULT;
+ if (get_user(p, pages + i))
+ goto out_pm;
+
+ pm[i].addr = (unsigned long)p;
+ if (nodes) {
+ int node;
+
+ if (get_user(node, nodes + i))
+ goto out_pm;
+
+ err = -ENODEV;
+ if (!node_state(node, N_HIGH_MEMORY))
+ goto out_pm;
+
+ err = -EACCES;
+ if (!node_isset(node, task_nodes))
+ goto out_pm;
+
+ pm[i].node = node;
+ } else
+ pm[i].node = 0; /* anything to not match MAX_NUMNODES */
+ }
+ /* End marker */
+ pm[nr_pages].node = MAX_NUMNODES;
+
+ err = do_move_page_to_node_array(mm, pm, flags & MPOL_MF_MOVE_ALL);
+ if (err >= 0)
+ /* Return status information */
+ for (i = 0; i < nr_pages; i++)
+ if (put_user(pm[i].status, status + i))
+ err = -EFAULT;
+
+out_pm:
+ vfree(pm);
+out:
+ return err;
+}
+
+/*
* 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, unsigned long nr_pages,
@@ -993,12 +1070,9 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
const int __user *nodes,
int __user *status, int flags)
{
- int err = 0;
- int i;
struct task_struct *task;
- nodemask_t task_nodes;
struct mm_struct *mm;
- struct page_to_node *pm = NULL;
+ int err;
/* Check flags */
if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
@@ -1030,75 +1104,21 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
(current->uid != task->suid) && (current->uid != task->uid) &&
!capable(CAP_SYS_NICE)) {
err = -EPERM;
- goto out2;
+ goto out;
}
err = security_task_movememory(task);
if (err)
- goto out2;
+ goto out;
- if (!nodes) {
+ if (nodes) {
+ err = do_pages_move(mm, task, nr_pages, pages, nodes, status,
+ flags);
+ } else {
err = do_pages_stat(mm, nr_pages, pages, status);
- goto out2;
- }
-
- task_nodes = cpuset_mems_allowed(task);
-
- /* Limit nr_pages so that the multiplication may not overflow */
- if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
- err = -E2BIG;
- goto out2;
}
- pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
- if (!pm) {
- err = -ENOMEM;
- goto out2;
- }
-
- /*
- * Get parameters from user space and initialize the pm
- * array. Return various errors if the user did something wrong.
- */
- for (i = 0; i < nr_pages; i++) {
- const void __user *p;
-
- err = -EFAULT;
- if (get_user(p, pages + i))
- goto out;
-
- pm[i].addr = (unsigned long)p;
- if (nodes) {
- int node;
-
- if (get_user(node, nodes + i))
- goto out;
-
- err = -ENODEV;
- if (!node_state(node, N_HIGH_MEMORY))
- goto out;
-
- err = -EACCES;
- if (!node_isset(node, task_nodes))
- goto out;
-
- pm[i].node = node;
- } else
- pm[i].node = 0; /* anything to not match MAX_NUMNODES */
- }
- /* End marker */
- pm[nr_pages].node = MAX_NUMNODES;
-
- err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL);
- if (err >= 0)
- /* Return status information */
- for (i = 0; i < nr_pages; i++)
- if (put_user(pm[i].status, status + i))
- err = -EFAULT;
-
out:
- vfree(pm);
-out2:
mmput(mm);
return err;
}
--
1.5.6.5
WARNING: multiple messages have this Message-ID (diff)
From: Brice Goglin <Brice.Goglin@inria.fr>
To: Christoph Lameter <cl@linux-foundation.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
linux-mm@kvack.org, Andrew Morton <akpm@osdl.org>,
Nathalie Furmento <nathalie.furmento@labri.fr>
Subject: [PATCH 3/5] mm: extract do_pages_move() out of sys_move_pages()
Date: Mon, 13 Oct 2008 22:22:13 +0200 [thread overview]
Message-ID: <48F3ADF5.1060609@inria.fr> (raw)
In-Reply-To: <48F3AD47.1050301@inria.fr>
To prepare the chunking, move the sys_move_pages() code that
is used when nodes!=NULL into do_pages_move().
And rename do_move_pages() into do_move_page_to_node_array().
Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
---
mm/migrate.c | 152 +++++++++++++++++++++++++++++++++-------------------------
1 files changed, 86 insertions(+), 66 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index e92e4f1..dffc98b 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -858,9 +858,11 @@ static struct page *new_page_node(struct page *p, unsigned long private,
* Move a set of pages as indicated in the pm array. The addr
* field must be set to the virtual address of the page to be moved
* and the node number must contain a valid target node.
+ * The pm array ends with node = MAX_NUMNODES.
*/
-static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
- int migrate_all)
+static int do_move_page_to_node_array(struct mm_struct *mm,
+ struct page_to_node *pm,
+ int migrate_all)
{
int err;
struct page_to_node *pp;
@@ -936,6 +938,81 @@ set_status:
}
/*
+ * Migrate an array of page address onto an array of nodes and fill
+ * the corresponding array of status.
+ */
+static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
+ unsigned long nr_pages,
+ const void __user * __user *pages,
+ const int __user *nodes,
+ int __user *status, int flags)
+{
+ struct page_to_node *pm = NULL;
+ nodemask_t task_nodes;
+ int err = 0;
+ int i;
+
+ task_nodes = cpuset_mems_allowed(task);
+
+ /* Limit nr_pages so that the multiplication may not overflow */
+ if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
+ err = -E2BIG;
+ goto out;
+ }
+
+ pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
+ if (!pm) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Get parameters from user space and initialize the pm
+ * array. Return various errors if the user did something wrong.
+ */
+ for (i = 0; i < nr_pages; i++) {
+ const void __user *p;
+
+ err = -EFAULT;
+ if (get_user(p, pages + i))
+ goto out_pm;
+
+ pm[i].addr = (unsigned long)p;
+ if (nodes) {
+ int node;
+
+ if (get_user(node, nodes + i))
+ goto out_pm;
+
+ err = -ENODEV;
+ if (!node_state(node, N_HIGH_MEMORY))
+ goto out_pm;
+
+ err = -EACCES;
+ if (!node_isset(node, task_nodes))
+ goto out_pm;
+
+ pm[i].node = node;
+ } else
+ pm[i].node = 0; /* anything to not match MAX_NUMNODES */
+ }
+ /* End marker */
+ pm[nr_pages].node = MAX_NUMNODES;
+
+ err = do_move_page_to_node_array(mm, pm, flags & MPOL_MF_MOVE_ALL);
+ if (err >= 0)
+ /* Return status information */
+ for (i = 0; i < nr_pages; i++)
+ if (put_user(pm[i].status, status + i))
+ err = -EFAULT;
+
+out_pm:
+ vfree(pm);
+out:
+ return err;
+}
+
+/*
* 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, unsigned long nr_pages,
@@ -993,12 +1070,9 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
const int __user *nodes,
int __user *status, int flags)
{
- int err = 0;
- int i;
struct task_struct *task;
- nodemask_t task_nodes;
struct mm_struct *mm;
- struct page_to_node *pm = NULL;
+ int err;
/* Check flags */
if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
@@ -1030,75 +1104,21 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
(current->uid != task->suid) && (current->uid != task->uid) &&
!capable(CAP_SYS_NICE)) {
err = -EPERM;
- goto out2;
+ goto out;
}
err = security_task_movememory(task);
if (err)
- goto out2;
+ goto out;
- if (!nodes) {
+ if (nodes) {
+ err = do_pages_move(mm, task, nr_pages, pages, nodes, status,
+ flags);
+ } else {
err = do_pages_stat(mm, nr_pages, pages, status);
- goto out2;
- }
-
- task_nodes = cpuset_mems_allowed(task);
-
- /* Limit nr_pages so that the multiplication may not overflow */
- if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
- err = -E2BIG;
- goto out2;
}
- pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
- if (!pm) {
- err = -ENOMEM;
- goto out2;
- }
-
- /*
- * Get parameters from user space and initialize the pm
- * array. Return various errors if the user did something wrong.
- */
- for (i = 0; i < nr_pages; i++) {
- const void __user *p;
-
- err = -EFAULT;
- if (get_user(p, pages + i))
- goto out;
-
- pm[i].addr = (unsigned long)p;
- if (nodes) {
- int node;
-
- if (get_user(node, nodes + i))
- goto out;
-
- err = -ENODEV;
- if (!node_state(node, N_HIGH_MEMORY))
- goto out;
-
- err = -EACCES;
- if (!node_isset(node, task_nodes))
- goto out;
-
- pm[i].node = node;
- } else
- pm[i].node = 0; /* anything to not match MAX_NUMNODES */
- }
- /* End marker */
- pm[nr_pages].node = MAX_NUMNODES;
-
- err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL);
- if (err >= 0)
- /* Return status information */
- for (i = 0; i < nr_pages; i++)
- if (put_user(pm[i].status, status + i))
- err = -EFAULT;
-
out:
- vfree(pm);
-out2:
mmput(mm);
return err;
}
--
1.5.6.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2008-10-13 20:23 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-13 20:19 [PATCH 0/5] mm: rework sys_move_pages() to avoid vmalloc and reduce the overhead Brice Goglin
2008-10-13 20:19 ` Brice Goglin
2008-10-13 20:21 ` [PATCH 1/5] mm: stop returning -ENOENT from sys_move_pages() if nothing got migrated Brice Goglin
2008-10-13 20:21 ` Brice Goglin
2008-10-16 19:34 ` Christoph Lameter
2008-10-16 19:34 ` Christoph Lameter
2008-10-13 20:21 ` [PATCH 2/5] mm: don't vmalloc a huge page_to_node array for do_pages_stat() Brice Goglin
2008-10-13 20:21 ` Brice Goglin
2008-10-16 19:39 ` Christoph Lameter
2008-10-16 19:39 ` Christoph Lameter
2008-10-13 20:22 ` Brice Goglin [this message]
2008-10-13 20:22 ` [PATCH 3/5] mm: extract do_pages_move() out of sys_move_pages() Brice Goglin
2008-10-16 19:40 ` Christoph Lameter
2008-10-16 19:40 ` Christoph Lameter
2008-10-13 20:22 ` [PATCH 4/5] mm: rework do_pages_move() to work on page_sized chunks Brice Goglin
2008-10-13 20:22 ` Brice Goglin
2008-10-16 19:51 ` Christoph Lameter
2008-10-16 19:51 ` Christoph Lameter
2008-10-16 21:18 ` Brice Goglin
2008-10-16 21:18 ` Brice Goglin
2008-10-17 11:35 ` [RESEND][PATCH] " Brice Goglin
2008-10-17 11:35 ` Brice Goglin
2008-10-17 13:10 ` Christoph Lameter
2008-10-17 13:10 ` Christoph Lameter
2008-10-13 20:23 ` [PATCH 5/5] mm: move_pages: no need to set pp->page to ZERO_PAGE(0) by default Brice Goglin
2008-10-13 20:23 ` Brice Goglin
2008-10-16 19:42 ` Christoph Lameter
2008-10-16 19:42 ` Christoph Lameter
2008-10-14 20:53 ` [PATCH 0/5] mm: rework sys_move_pages() to avoid vmalloc and reduce the overhead Brice Goglin
2008-10-14 20:53 ` Brice Goglin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48F3ADF5.1060609@inria.fr \
--to=brice.goglin@inria.fr \
--cc=akpm@osdl.org \
--cc=cl@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nathalie.furmento@labri.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.