+ page-migration-support-moving-of-individual-pages.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     page migration: sys_move_pages(): support moving of individual pages

has been added to the -mm tree.  Its filename is

     page-migration-support-moving-of-individual-pages.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: page migration: sys_move_pages(): support moving of individual pages
From: Christoph Lameter <clameter@xxxxxxx>


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


Signed-off-by: Christoph Lameter <clameter@xxxxxxx>
Cc: Hugh Dickins <hugh@xxxxxxxxxxx>
Cc: Jes Sorensen <jes@xxxxxxxxxxxxxxxxxx>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx>
Cc: Lee Schermerhorn <lee.schermerhorn@xxxxxx>
Cc: Andi Kleen <ak@xxxxxx>
Cc: Michael Kerrisk <mtk-manpages@xxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 arch/ia64/kernel/entry.S  |    2 
 include/asm-ia64/unistd.h |    2 
 kernel/sys_ni.c           |    1 
 mm/migrate.c              |  174 ++++++++++++++++++++++++++++++++++++
 4 files changed, 177 insertions(+), 2 deletions(-)

diff -puN arch/ia64/kernel/entry.S~page-migration-support-moving-of-individual-pages arch/ia64/kernel/entry.S
--- 25/arch/ia64/kernel/entry.S~page-migration-support-moving-of-individual-pages	Wed May 24 13:20:32 2006
+++ 25-akpm/arch/ia64/kernel/entry.S	Wed May 24 13:20:32 2006
@@ -1584,7 +1584,7 @@ sys_call_table:
 	data8 sys_keyctl
 	data8 sys_ioprio_set
 	data8 sys_ioprio_get			// 1275
-	data8 sys_ni_syscall
+	data8 sys_move_pages
 	data8 sys_inotify_init
 	data8 sys_inotify_add_watch
 	data8 sys_inotify_rm_watch
diff -puN include/asm-ia64/unistd.h~page-migration-support-moving-of-individual-pages include/asm-ia64/unistd.h
--- 25/include/asm-ia64/unistd.h~page-migration-support-moving-of-individual-pages	Wed May 24 13:20:32 2006
+++ 25-akpm/include/asm-ia64/unistd.h	Wed May 24 13:20:32 2006
@@ -265,7 +265,7 @@
 #define __NR_keyctl			1273
 #define __NR_ioprio_set			1274
 #define __NR_ioprio_get			1275
-/* 1276 is available for reuse (was briefly sys_set_zone_reclaim) */
+#define __NR_move_pages			1276
 #define __NR_inotify_init		1277
 #define __NR_inotify_add_watch		1278
 #define __NR_inotify_rm_watch		1279
diff -puN kernel/sys_ni.c~page-migration-support-moving-of-individual-pages kernel/sys_ni.c
--- 25/kernel/sys_ni.c~page-migration-support-moving-of-individual-pages	Wed May 24 13:20:32 2006
+++ 25-akpm/kernel/sys_ni.c	Wed May 24 13:20:32 2006
@@ -87,6 +87,7 @@ cond_syscall(sys_inotify_init);
 cond_syscall(sys_inotify_add_watch);
 cond_syscall(sys_inotify_rm_watch);
 cond_syscall(sys_migrate_pages);
+cond_syscall(sys_move_pages);
 cond_syscall(sys_chown16);
 cond_syscall(sys_fchown16);
 cond_syscall(sys_getegid16);
diff -puN mm/migrate.c~page-migration-support-moving-of-individual-pages mm/migrate.c
--- 25/mm/migrate.c~page-migration-support-moving-of-individual-pages	Wed May 24 13:20:32 2006
+++ 25-akpm/mm/migrate.c	Wed May 24 13:23:41 2006
@@ -25,6 +25,7 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/writeback.h>
+#include <linux/mempolicy.h>
 
 #include "internal.h"
 
@@ -710,3 +711,176 @@ out:
 	return nr_failed + retry;
 }
 
+#ifdef CONFIG_NUMA
+/*
+ * Move a list of individual pages
+ */
+struct page_to_node {
+	struct page *page;
+	int node;
+	int status;
+};
+
+static struct page *new_page_node(struct page *p, unsigned long private)
+{
+	struct page_to_node *pm = (struct page_to_node *)private;
+
+	while (pm->page && pm->page != p)
+		pm++;
+
+	if (!pm->page)
+		return NULL;
+
+	return alloc_pages_node(pm->node, GFP_HIGHUSER, 0);
+}
+
+/*
+ * Move a list of pages in the address space of the currently executing
+ * process.
+ */
+asmlinkage long sys_move_pages(int pid, unsigned long nr_pages,
+			const unsigned long __user *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;
+	LIST_HEAD(pagelist);
+
+	/* Check flags */
+	if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
+		return -EINVAL;
+
+	if ((flags & MPOL_MF_MOVE_ALL) && !capable(CAP_SYS_NICE))
+		return -EPERM;
+
+	/* Find the mm_struct */
+	read_lock(&tasklist_lock);
+	task = pid ? find_task_by_pid(pid) : current;
+	if (!task) {
+		read_unlock(&tasklist_lock);
+		return -ESRCH;
+	}
+	mm = get_task_mm(task);
+	read_unlock(&tasklist_lock);
+
+	if (!mm)
+		return -EINVAL;
+
+	/*
+	 * Check if this process has the right to modify the specified
+	 * process. The right exists if the process has administrative
+	 * capabilities, superuser privileges or the same
+	 * userid as the target process.
+	 */
+	if ((current->euid != task->suid) && (current->euid != task->uid) &&
+	    (current->uid != task->suid) && (current->uid != task->uid) &&
+	    !capable(CAP_SYS_NICE)) {
+		err = -EPERM;
+		goto out2;
+	}
+
+	task_nodes = cpuset_mems_allowed(task);
+	pm = kmalloc(GFP_KERNEL, (nr_pages + 1) * sizeof(struct page_to_node));
+	if (!pm) {
+		err = -ENOMEM;
+		goto out2;
+	}
+
+	down_read(&mm->mmap_sem);
+
+	for(i = 0 ; i < nr_pages; i++) {
+		unsigned long addr;
+		int node;
+		struct vm_area_struct *vma;
+		struct page *page;
+
+		pm[i].page = ZERO_PAGE(0);
+
+		err = -EFAULT;
+		if (get_user(addr, pages + i))
+			goto putback;
+
+		vma = find_vma(mm, addr);
+		if (!vma)
+			goto set_status;
+
+		page = follow_page(vma, addr, FOLL_GET);
+		err = -ENOENT;
+		if (!page)
+			goto set_status;
+
+		pm[i].page = page;
+		if (!nodes) {
+			err = page_to_nid(page);
+			put_page(page);
+			goto set_status;
+		}
+
+		err = -EPERM;
+		if (page_mapcount(page) > 1 &&
+				!(flags & MPOL_MF_MOVE_ALL)) {
+			put_page(page);
+			goto set_status;
+		}
+
+
+		err = isolate_lru_page(page, &pagelist);
+		__put_page(page);
+		if (err)
+			goto remove;
+
+		err = -EFAULT;
+		if (get_user(node, nodes + i))
+			goto remove;
+
+		err = -ENOENT;
+		if (!node_online(node))
+			goto remove;
+
+		err = -EPERM;
+		if (!node_isset(node, task_nodes))
+			goto remove;
+
+		pm[i].node = node;
+		err = 0;
+		if (node != page_to_nid(page))
+			goto set_status;
+
+		err = node;
+remove:
+		list_del(&page->lru);
+		move_to_lru(page);
+set_status:
+		pm[i].status = err;
+	}
+	err = 0;
+	if (!nodes || list_empty(&pagelist))
+		goto out;
+
+	pm[nr_pages].page = NULL;
+
+	err = migrate_pages(&pagelist, new_page_node, (unsigned long)pm);
+	goto out;
+
+putback:
+	putback_lru_pages(&pagelist);
+
+out:
+	up_read(&mm->mmap_sem);
+	if (err >= 0)
+		/* Return status information */
+		for(i = 0; i < nr_pages; i++)
+			put_user(pm[i].status, status +i);
+
+	kfree(pm);
+out2:
+	mmput(mm);
+	return err;
+}
+#endif
+
_

Patches currently in -mm which might be from clameter@xxxxxxx are

origin.patch
page-migration-make-do_swap_page-redo-the-fault.patch
slab-extract-cache_free_alien-from-__cache_free.patch
migration-remove-unnecessary-pageswapcache-checks.patch
page-migration-cleanup-rename-ignrefs-to-migration.patch
page-migration-cleanup-group-functions.patch
page-migration-cleanup-remove-useless-definitions.patch
page-migration-cleanup-drop-nr_refs-in-remove_references.patch
page-migration-cleanup-extract-try_to_unmap-from-migration-functions.patch
page-migration-cleanup-extract-try_to_unmap-from-migration-functions-update-comments-7.patch
page-migration-cleanup-pass-mapping-to-migration-functions.patch
page-migration-cleanup-move-fallback-handling-into-special-function.patch
page-migration-cleanup-move-fallback-handling-into-special-function-update-comments-9.patch
swapless-pm-add-r-w-migration-entries.patch
swapless-pm-add-r-w-migration-entries-ifdefs.patch
swapless-pm-add-r-w-migration-entries-update-comments.patch
swapless-pm-add-r-w-migration-entries-update-comments-4.patch
swapless-pm-add-r-w-migration-entries-update-comments-6.patch
swapless-page-migration-rip-out-swap-based-logic.patch
swapless-page-migration-modify-core-logic.patch
swapless-page-migration-modify-core-logic-remove-useless-mapping-checks.patch
more-page-migration-do-not-inc-dec-rss-counters.patch
more-page-migration-use-migration-entries-for-file-pages.patch
more-page-migration-use-migration-entries-for-file-pages-fix.patch
more-page-migration-use-migration-entries-for-file-pages-update-comments-5.patch
more-page-migration-use-migration-entries-for-file-pages-update-comments-8.patch
more-page-migration-use-migration-entries-for-file-pages-remove_migration_ptes.patch
more-page-migration-use-migration-entries-for-file-pages-replace-call-to-pageout-with-writepage-2.patch
page-migration-update-documentation.patch
page-migration-simplify-migrate_pages.patch
page-migration-simplify-migrate_pages-tweaks.patch
page-migration-handle-freeing-of-pages-in-migrate_pages.patch
page-migration-use-allocator-function-for-migrate_pages.patch
page-migration-support-moving-of-individual-pages.patch
page-migration-detailed-status-for-moving-of-individual-pages.patch
page-migration-support-moving-of-individual-pages-fixes.patch
page-migration-support-a-vma-migration-function.patch
cpuset-remove-extra-cpuset_zone_allowed-check-in-__alloc_pages.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux