summaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
authorRafael Aquini <aquini@redhat.com>2012-12-11 19:02:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 20:22:27 -0500
commitbf6bddf1924eaebf2beb85e4249a89dd16d4eed6 (patch)
treee03b66a6779727a44f40c4e8f43a06c52d39a6ef /mm/migrate.c
parent18468d93e53b037e1a04ec58398eab763d054064 (diff)
mm: introduce compaction and migration for ballooned pages
Memory fragmentation introduced by ballooning might reduce significantly the number of 2MB contiguous memory blocks that can be used within a guest, thus imposing performance penalties associated with the reduced number of transparent huge pages that could be used by the guest workload. This patch introduces the helper functions as well as the necessary changes to teach compaction and migration bits how to cope with pages which are part of a guest memory balloon, in order to make them movable by memory compaction procedures. Signed-off-by: Rafael Aquini <aquini@redhat.com> Acked-by: Mel Gorman <mel@csn.ul.ie> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Rik van Riel <riel@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Minchan Kim <minchan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 33f5f82a6006..427343c0c296 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -35,6 +35,7 @@
35#include <linux/hugetlb.h> 35#include <linux/hugetlb.h>
36#include <linux/hugetlb_cgroup.h> 36#include <linux/hugetlb_cgroup.h>
37#include <linux/gfp.h> 37#include <linux/gfp.h>
38#include <linux/balloon_compaction.h>
38 39
39#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
40 41
@@ -79,7 +80,10 @@ void putback_lru_pages(struct list_head *l)
79 list_del(&page->lru); 80 list_del(&page->lru);
80 dec_zone_page_state(page, NR_ISOLATED_ANON + 81 dec_zone_page_state(page, NR_ISOLATED_ANON +
81 page_is_file_cache(page)); 82 page_is_file_cache(page));
82 putback_lru_page(page); 83 if (unlikely(balloon_page_movable(page)))
84 balloon_page_putback(page);
85 else
86 putback_lru_page(page);
83 } 87 }
84} 88}
85 89
@@ -768,6 +772,18 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
768 } 772 }
769 } 773 }
770 774
775 if (unlikely(balloon_page_movable(page))) {
776 /*
777 * A ballooned page does not need any special attention from
778 * physical to virtual reverse mapping procedures.
779 * Skip any attempt to unmap PTEs or to remap swap cache,
780 * in order to avoid burning cycles at rmap level, and perform
781 * the page migration right away (proteced by page lock).
782 */
783 rc = balloon_page_migrate(newpage, page, mode);
784 goto uncharge;
785 }
786
771 /* 787 /*
772 * Corner case handling: 788 * Corner case handling:
773 * 1. When a new swap-cache page is read into, it is added to the LRU 789 * 1. When a new swap-cache page is read into, it is added to the LRU
@@ -804,7 +820,9 @@ skip_unmap:
804 put_anon_vma(anon_vma); 820 put_anon_vma(anon_vma);
805 821
806uncharge: 822uncharge:
807 mem_cgroup_end_migration(mem, page, newpage, rc == MIGRATEPAGE_SUCCESS); 823 mem_cgroup_end_migration(mem, page, newpage,
824 (rc == MIGRATEPAGE_SUCCESS ||
825 rc == MIGRATEPAGE_BALLOON_SUCCESS));
808unlock: 826unlock:
809 unlock_page(page); 827 unlock_page(page);
810out: 828out:
@@ -836,6 +854,18 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
836 goto out; 854 goto out;
837 855
838 rc = __unmap_and_move(page, newpage, force, offlining, mode); 856 rc = __unmap_and_move(page, newpage, force, offlining, mode);
857
858 if (unlikely(rc == MIGRATEPAGE_BALLOON_SUCCESS)) {
859 /*
860 * A ballooned page has been migrated already.
861 * Now, it's the time to wrap-up counters,
862 * handle the page back to Buddy and return.
863 */
864 dec_zone_page_state(page, NR_ISOLATED_ANON +
865 page_is_file_cache(page));
866 balloon_page_free(page);
867 return MIGRATEPAGE_SUCCESS;
868 }
839out: 869out:
840 if (rc != -EAGAIN) { 870 if (rc != -EAGAIN) {
841 /* 871 /*