From: Christoph Lameter 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 Cc: Hugh Dickins Cc: Jes Sorensen Cc: KAMEZAWA Hiroyuki Cc: Lee Schermerhorn Cc: Andi Kleen Signed-off-by: Andrew Morton --- include/linux/migrate.h | 2 +- mm/mempolicy.c | 4 ++-- mm/migrate.c | 16 +++++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff -puN include/linux/migrate.h~page-migration-detailed-status-for-moving-of-individual-pages include/linux/migrate.h --- 25/include/linux/migrate.h~page-migration-detailed-status-for-moving-of-individual-pages Fri May 19 12:28:19 2006 +++ 25-akpm/include/linux/migrate.h Fri May 19 12:28:19 2006 @@ -3,7 +3,7 @@ #include -typedef struct page *new_page_t(struct page *, unsigned long private); +typedef struct page *new_page_t(struct page *, unsigned long private, int **); #ifdef CONFIG_MIGRATION extern int isolate_lru_page(struct page *p, struct list_head *pagelist); diff -puN mm/mempolicy.c~page-migration-detailed-status-for-moving-of-individual-pages mm/mempolicy.c --- 25/mm/mempolicy.c~page-migration-detailed-status-for-moving-of-individual-pages Fri May 19 12:28:19 2006 +++ 25-akpm/mm/mempolicy.c Fri May 19 12:28:19 2006 @@ -588,7 +588,7 @@ static void migrate_page_add(struct page isolate_lru_page(page, pagelist); } -static struct page *new_node_page(struct page *page, unsigned long node) +static struct page *new_node_page(struct page *page, unsigned long node, int **x) { return alloc_pages_node(node, GFP_HIGHUSER, 0); } @@ -698,7 +698,7 @@ int do_migrate_pages(struct mm_struct *m } -static struct page *new_vma_page(struct page *page, unsigned long private) +static struct page *new_vma_page(struct page *page, unsigned long private, int **x) { struct vm_area_struct *vma = (struct vm_area_struct *)private; diff -puN mm/migrate.c~page-migration-detailed-status-for-moving-of-individual-pages mm/migrate.c --- 25/mm/migrate.c~page-migration-detailed-status-for-moving-of-individual-pages Fri May 19 12:28:19 2006 +++ 25-akpm/mm/migrate.c Fri May 19 12:28:19 2006 @@ -589,7 +589,8 @@ static int unmap_and_move(new_page_t get struct page *page, int force) { int rc = 0; - struct page *newpage = get_new_page(page, private); + int *result = NULL; + struct page *newpage = get_new_page(page, private, &result); if (!newpage) return -ENOMEM; @@ -643,6 +644,12 @@ move_newpage: * then this will free the page. */ move_to_lru(newpage); + if (result) { + if (rc) + *result = rc; + else + *result = page_to_nid(newpage); + } return rc; } @@ -721,7 +728,8 @@ struct page_to_node { int status; }; -static struct page *new_page_node(struct page *p, unsigned long private) +static struct page *new_page_node(struct page *p, unsigned long private, + int **result) { struct page_to_node *pm = (struct page_to_node *)private; @@ -731,6 +739,8 @@ static struct page *new_page_node(struct if (!pm->page) return NULL; + *result = &pm->status; + return alloc_pages_node(pm->node, GFP_HIGHUSER, 0); } @@ -847,7 +857,7 @@ asmlinkage long sys_move_pages(int pid, goto remove; pm[i].node = node; - err = 0; + err = -EAGAIN; if (node != page_to_nid(page)) goto set_status; _