diff options
author | Christoph Lameter <clameter@sgi.com> | 2006-06-23 05:03:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-23 10:42:53 -0400 |
commit | 742755a1d8ce2b548428f7aacf1758b4bba50080 (patch) | |
tree | 53426657e14dc19a694d418274c9a6f4dcb8a997 /mm/mempolicy.c | |
parent | 95a402c3847cc16f4ba03013cd01404fa0f14c2e (diff) |
[PATCH] page migration: sys_move_pages(): support moving of individual pages
move_pages() is used to move individual pages of a process. The function can
be used to determine the location of pages and to move them onto the desired
node. move_pages() returns status information for each page.
long move_pages(pid, number_of_pages_to_move,
addresses_of_pages[],
nodes[] or NULL,
status[],
flags);
The addresses of pages is an array of void * pointing to the
pages to be moved.
The nodes array contains the node numbers that the pages should be moved
to. If a NULL is passed instead of an array then no pages are moved but
the status array is updated. The status request may be used to determine
the page state before issuing another move_pages() to move pages.
The status array will contain the state of all individual page migration
attempts when the function terminates. The status array is only valid if
move_pages() completed successfullly.
Possible page states in status[]:
0..MAX_NUMNODES The page is now on the indicated node.
-ENOENT Page is not present
-EACCES Page is mapped by multiple processes and can only
be moved if MPOL_MF_MOVE_ALL is specified.
-EPERM The page has been mlocked by a process/driver and
cannot be moved.
-EBUSY Page is busy and cannot be moved. Try again later.
-EFAULT Invalid address (no VMA or zero page).
-ENOMEM Unable to allocate memory on target node.
-EIO Unable to write back page. The page must be written
back in order to move it since the page is dirty and the
filesystem does not provide a migration function that
would allow the moving of dirty pages.
-EINVAL A dirty page cannot be moved. The filesystem does not provide
a migration function and has no ability to write back pages.
The flags parameter indicates what types of pages to move:
MPOL_MF_MOVE Move pages that are only mapped by the process.
MPOL_MF_MOVE_ALL Also move pages that are mapped by multiple processes.
Requires sufficient capabilities.
Possible return codes from move_pages()
-ENOENT No pages found that would require moving. All pages
are either already on the target node, not present, had an
invalid address or could not be moved because they were
mapped by multiple processes.
-EINVAL Flags other than MPOL_MF_MOVE(_ALL) specified or an attempt
to migrate pages in a kernel thread.
-EPERM MPOL_MF_MOVE_ALL specified without sufficient priviledges.
or an attempt to move a process belonging to another user.
-EACCES One of the target nodes is not allowed by the current cpuset.
-ENODEV One of the target nodes is not online.
-ESRCH Process does not exist.
-E2BIG Too many pages to move.
-ENOMEM Not enough memory to allocate control array.
-EFAULT Parameters could not be accessed.
A test program for move_pages() may be found with the patches
on ftp.kernel.org:/pub/linux/kernel/people/christoph/pmig/patches-2.6.17-rc4-mm3
From: Christoph Lameter <clameter@sgi.com>
Detailed results for sys_move_pages()
Pass a pointer to an integer to get_new_page() that may be used to
indicate where the completion status of a migration operation should be
placed. This allows sys_move_pags() to report back exactly what happened to
each page.
Wish there would be a better way to do this. Looks a bit hacky.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Jes Sorensen <jes@trained-monkey.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: Andi Kleen <ak@muc.de>
Cc: Michael Kerrisk <mtk-manpages@gmx.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index f432642e9e6..05b84acf0bb 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -588,7 +588,7 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist, | |||
588 | isolate_lru_page(page, pagelist); | 588 | isolate_lru_page(page, pagelist); |
589 | } | 589 | } |
590 | 590 | ||
591 | static struct page *new_node_page(struct page *page, unsigned long node) | 591 | static struct page *new_node_page(struct page *page, unsigned long node, int **x) |
592 | { | 592 | { |
593 | return alloc_pages_node(node, GFP_HIGHUSER, 0); | 593 | return alloc_pages_node(node, GFP_HIGHUSER, 0); |
594 | } | 594 | } |
@@ -698,7 +698,7 @@ int do_migrate_pages(struct mm_struct *mm, | |||
698 | 698 | ||
699 | } | 699 | } |
700 | 700 | ||
701 | static struct page *new_vma_page(struct page *page, unsigned long private) | 701 | static struct page *new_vma_page(struct page *page, unsigned long private, int **x) |
702 | { | 702 | { |
703 | struct vm_area_struct *vma = (struct vm_area_struct *)private; | 703 | struct vm_area_struct *vma = (struct vm_area_struct *)private; |
704 | 704 | ||