Do not free the page in swap_page() Do not free the page in swap_page() to allow the page to be managed by the caller of migrate_page(). If the page count dropped to 1 then rely on the next loop in migrate_pages() to deal with the page of freeing it directly. Some whitespace cleanup. Signed-off-by: Christoph Lameter Index: linux-2.6.15-rc1-mm2/mm/vmscan.c =================================================================== --- linux-2.6.15-rc1-mm2.orig/mm/vmscan.c 2005-11-18 09:47:15.000000000 -0800 +++ linux-2.6.15-rc1-mm2/mm/vmscan.c 2005-11-18 10:04:05.000000000 -0800 @@ -627,41 +627,32 @@ static int swap_page(struct page *page) case PAGE_KEEP: case PAGE_ACTIVATE: goto unlock_retry; + case PAGE_SUCCESS: goto retry; + case PAGE_CLEAN: ; /* try to free the page below */ } } if (PagePrivate(page)) { - if (!try_to_release_page(page, GFP_KERNEL)) + if (!try_to_release_page(page, GFP_KERNEL) || + (!mapping && page_count(page) == 1)) goto unlock_retry; - if (!mapping && page_count(page) == 1) - goto free_it; } - if (!remove_mapping(mapping, page)) - goto unlock_retry; /* truncate got there first */ - -free_it: - /* - * We may free pages that were taken off the active list - * by isolate_lru_page. However, free_hot_cold_page will check - * if the active bit is set. So clear it. - */ - ClearPageActive(page); - - list_del(&page->lru); - unlock_page(page); - put_page(page); - return 0; + if (remove_mapping(mapping, page)) { + /* Success */ + unlock_page(page); + return 0; + } unlock_retry: unlock_page(page); retry: - return 1; + return 1; } /* * migrate_pages