Index: linux-2.6.16-rc4/mm/vmscan.c =================================================================== --- linux-2.6.16-rc4.orig/mm/vmscan.c 2006-02-17 14:23:45.000000000 -0800 +++ linux-2.6.16-rc4/mm/vmscan.c 2006-02-24 15:35:55.000000000 -0800 @@ -699,9 +699,11 @@ int migrate_page_remove_references(struc * indicates that the page is in use or truncate has removed * the page. */ - if (!mapping || page_mapcount(page) + nr_refs != page_count(page)) - return 1; - + if (!mapping || page_mapcount(page) + nr_refs != page_count(page)) { + printk("RR Retry %p: mapping=%p page_count=%d nr_refs=%d page_count=%d\n", + page, mapping, page_mapcount(page), nr_refs, page_count(page)); + return -EAGAIN; + } /* * Establish swap ptes for anonymous pages or destroy pte * maps for files. @@ -721,13 +723,20 @@ int migrate_page_remove_references(struc * If the page was not migrated then the PageSwapCache bit * is still set and the operation may continue. */ - try_to_unmap(page, 1); + if (try_to_unmap(page, 1) == SWAP_FAIL) + /* mlocked page */ + return -EPERM; /* * Give up if we were unable to remove all mappings. */ - if (page_mapcount(page)) - return 1; + if (page_mapcount(page)) { + /* + * Extremely busy pages typically fail here.... + */ + printk("RR mapcount (%d) not zero after unmapping.\n", page_mapcount(page)); + return -EAGAIN; + } write_lock_irq(&mapping->tree_lock); @@ -738,7 +747,9 @@ int migrate_page_remove_references(struc if (!page_mapping(page) || page_count(page) != nr_refs || *radix_pointer != page) { write_unlock_irq(&mapping->tree_lock); - return 1; + printk("RR failure under lock mapping=%p page_count=%d refs=%d radix_pointer=%p page=%p", + page_mapping(page), page_count(page), nr_refs, *radix_pointer, page); + return -EAGAIN; } /* @@ -813,10 +824,14 @@ EXPORT_SYMBOL(migrate_page_copy); */ int migrate_page(struct page *newpage, struct page *page) { + int rc; + BUG_ON(PageWriteback(page)); /* Writeback must be complete */ - if (migrate_page_remove_references(newpage, page, 2)) - return -EAGAIN; + rc = migrate_page_remove_references(newpage, page, 2); + + if (rc) + return rc; migrate_page_copy(newpage, page); @@ -922,14 +937,18 @@ redo: newpage = lru_to_page(to); lock_page(newpage); + printk(KERN_ERR "Migrating %p (node %ld)->%p (node %ld)\n", page, page_to_nid(page), + newpage, page_to_nid(newpage)); /* * Pages are properly locked and writeback is complete. * Try to migrate the page. */ mapping = page_mapping(page); - if (!mapping) + if (!mapping) { + printk("No mapping\n"); goto unlock_both; + } if (mapping->a_ops->migratepage) { /* @@ -939,6 +958,7 @@ redo: * own migration function. This is the most common * path for page migration. */ + printk("Using Migration function %p\n", mapping->a_ops->migratepage); rc = mapping->a_ops->migratepage(newpage, page); goto unlock_both; } @@ -949,13 +969,16 @@ redo: * pages so try to write out any dirty pages first. */ if (PageDirty(page)) { + printk("Page Dirty.\n"); switch (pageout(page, mapping)) { case PAGE_KEEP: case PAGE_ACTIVATE: + printk("Pageout says keep page\n"); goto unlock_both; case PAGE_SUCCESS: unlock_page(newpage); + printk("Pageout success but it unlocked\n"); goto next; case PAGE_CLEAN: @@ -969,6 +992,7 @@ redo: */ if (!page_has_buffers(page) || try_to_release_page(page, GFP_KERNEL)) { + printk("Default migration function.\n"); rc = migrate_page(newpage, page); goto unlock_both; } @@ -987,6 +1011,7 @@ redo: */ unlock_page(newpage); newpage = NULL; + printk("Fall back to swap\n"); rc = swap_page(page); goto next; } @@ -998,18 +1023,22 @@ unlock_page: unlock_page(page); next: + printk("End %p\n",page); if (rc == -EAGAIN) { + printk("* Need to retry page %p\n",page); retry++; } else if (rc) { /* Permanent failure */ list_move(&page->lru, failed); nr_failed++; + printk("* Permanent failure on %p\n",page); } else { if (newpage) { /* Successful migration. Return page to LRU */ move_to_lru(newpage); } list_move(&page->lru, moved); + printk("* Successfully migrated %p\n",page); } } if (retry && pass++ < 10) Index: linux-2.6.16-rc4/mm/mempolicy.c =================================================================== --- linux-2.6.16-rc4.orig/mm/mempolicy.c 2006-02-24 14:32:02.000000000 -0800 +++ linux-2.6.16-rc4/mm/mempolicy.c 2006-02-24 15:00:21.000000000 -0800 @@ -624,6 +624,7 @@ int migrate_to_node(struct mm_struct *mm LIST_HEAD(pagelist); int err = 0; + printk(KERN_ERR "--Migrating pages from node %d to %d\n", source, dest); nodes_clear(nmask); node_set(source, nmask); @@ -940,7 +941,8 @@ asmlinkage long sys_migrate_pages(pid_t goto out; } - err = do_migrate_pages(mm, &old, &new, MPOL_MF_MOVE); + err = do_migrate_pages(mm, &old, &new, + capable(CAP_SYS_ADMIN) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); out: mmput(mm); return err; Index: linux-2.6.16-rc4/fs/buffer.c =================================================================== --- linux-2.6.16-rc4.orig/fs/buffer.c 2006-02-17 14:23:45.000000000 -0800 +++ linux-2.6.16-rc4/fs/buffer.c 2006-02-24 15:35:35.000000000 -0800 @@ -3060,6 +3060,7 @@ int buffer_migrate_page(struct page *new { struct address_space *mapping = page->mapping; struct buffer_head *bh, *head; + int rc; if (!mapping) return -EAGAIN; @@ -3069,8 +3070,9 @@ int buffer_migrate_page(struct page *new head = page_buffers(page); - if (migrate_page_remove_references(newpage, page, 3)) - return -EAGAIN; + rc = migrate_page_remove_references(newpage, page, 3); + if (rc) + return rc; bh = head; do {