Migration Cache 4/5 - use migration cache for lazy migration Separate migration cache patch for migrate_pages_unmap_only(). That function is only present when the MPOL_MF_LAZY feature of the "Migrate-on-Fault" patch series is present. Call __add_to_swap() with the 'migration' argument set to 1 to select the migration cache--if it's configured. Add removal from mig cache to error path if try_to_unmap() fails. This call is a no-op if any of the mappings to the page were successfully unmapped because the migration cache entry will have a non-zero ref count. Calling migration_remove_reference() with a decrement count of '0' will only remove the entry if it already has zero refs--i.e., no ptes reference it. Note that here is a case where the migration cache is visible outside of the swap infrastructure. Added a check for migration cache() entry to migration_remove_reference() to handle the case where a page is already in the real swap cache, but try_to_unmap() fails when called from migrate_pages_unmap_only(). We don't want to pass a real swap entry further down into the mig cache. Signed-off-by: Lee Schermerhorn <lee.schermerhorn@xxxxxx> mm/migrate.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) Index: linux-2.6.36-mmotm-101103-1217/mm/migrate.c =================================================================== --- linux-2.6.36-mmotm-101103-1217.orig/mm/migrate.c +++ linux-2.6.36-mmotm-101103-1217/mm/migrate.c @@ -952,7 +952,17 @@ int migrate_pages_unmap_only(struct list goto unlock_page; if (PageAnon(page)) { - if (!PageSwapCache(page) && !add_to_swap(page)) { + if (PageSwapCache(page)) { + /* + * add an extra ref while we hold the page + * lock so that do_swap_page() can't rip the + * entry out from under us. + */ + if (migration_add_reference_page(page)) { + nr_failed++; + goto unlock_page; + } + } else if (!__add_to_swap(page, 1)) { nr_failed++; goto unlock_page; } @@ -965,6 +975,11 @@ int migrate_pages_unmap_only(struct list ret = try_to_unmap(page, TTU_MIGRATE_DEFERRED|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS); + /* + * Remove extra ref. This will free the migration cache + * entry if try_to_unmap() failed to replace any ptes. + */ + migration_remove_reference_page(page); if (ret != SWAP_SUCCESS || page_mapped(page)) { nr_failed++; goto unlock_page; -- To unsubscribe from this list: send the line "unsubscribe linux-numa" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html