This patch introudes MIGRATE_DISCARD mode in migration.
It drop clean cache pages instead of migration so that
migration latency could be reduced. Of course, it could
evict code pages but latency of big contiguous memory
is more important than some background application's slow down
in mobile embedded enviroment.
Signed-off-by: Minchan Kim <minchan@xxxxxxxxxx>
@@ -799,12 +802,39 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
goto skip_unmap;
}
+ file = page_is_file_cache(page);
+ ttu_flags = TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS;
+
+ if (!(mode & MIGRATE_DISCARD) || !file || PageDirty(page))
+ ttu_flags |= TTU_MIGRATION;
+ else
+ discard_mode = true;
+
/* Establish migration ptes or remove ptes */
- try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
+ try_to_unmap(page, ttu_flags);
skip_unmap:
- if (!page_mapped(page))
- rc = move_to_new_page(newpage, page, remap_swapcache, mode);
+ if (!page_mapped(page)) {
+ if (!discard_mode)
+ rc = move_to_new_page(newpage, page, remap_swapcache, mode);
+ else {
+ struct address_space *mapping;
+ mapping = page_mapping(page);
+
+ if (page_has_private(page)) {
+ if (!try_to_release_page(page, GFP_KERNEL)) {
+ rc = -EAGAIN;
+ goto uncharge;
+ }
+ }
+
+ if (remove_mapping(mapping, page))
+ rc = 0;
+ else
+ rc = -EAGAIN;
+ goto uncharge;
+ }
+ }