Index: linux-2.6.17-rc3-mm1/mm/migrate.c =================================================================== --- linux-2.6.17-rc3-mm1.orig/mm/migrate.c 2006-05-08 00:27:50.723881703 -0700 +++ linux-2.6.17-rc3-mm1/mm/migrate.c 2006-05-08 00:27:58.856190425 -0700 @@ -765,3 +765,64 @@ err_out: goto out; } +/* + * Move a list of pages in the address space of the currently executing + * process. + */ +asmlinkage long sys_move_pages(unsigned long nr_pages, unsigned long __user *pages, + int __user *nodes, int flags) +{ + int err = 0; + struct page**from = kmalloc(sizeof(void *)*nr_pages); + struct page**to = kmalloc(sizeof(void *)*nr_pages); + int *status = kmalloc(sizeof(int)*nr_pages); + + if (!from || !to || !status) + goto err_out; + + for(i = 0 ; i < nr_pages; i++) { + from[i] = follow_page(pages[i]); + if (!from[i]) + err = -ENOSYS; + goto out; + } + if (!(flags & MPOL_MF_MOVE)) + if (!nodeonline(nodes[i])) { + err = -ENOSRC; + goto out; + } + to[i] = alloc_pages_node(nodes[i], GFP_HIGHUSER, 0); + if (!to[i]) { + err = -ENOMEM; + goto out; + } + } else + nodes[i] = page_to_nid(from[i]); + } + + if (!(flagg && MPOL_MF_MOVE)) + goto out; + err = migrate_pages(nr_pages, from, to, status); + if (err < 0) + goto out; + + for(i = 0; i < nr_pages; i++) { + nodes[i] = status[i]; + if (status[i]) + put_page(to[i]); + move_to_lru(from[i]); + } + +out: + kfree(from); + kfree(to); + kfree(status); + return err; + +err_out: + putback_lru_pages(pagelist); + err = -ENOMEM; + goto out; +} + +