diff options
author | Andrea Arcangeli <aarcange@redhat.com> | 2011-01-14 02:47:00 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-14 04:32:43 +0300 |
commit | 21ae5b01750f14140809508a478a4413792e0261 (patch) | |
tree | 49fff503cf2e17e0f8e583e83e43b337f9728c23 /mm/ksm.c | |
parent | b15d00b6af617251cc70a908df983e9aff57e169 (diff) |
thp: skip transhuge pages in ksm for now
Skip transhuge pages in ksm for now.
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Reviewed-by: Rik van Riel <riel@redhat.com>
Acked-by: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/ksm.c')
-rw-r--r-- | mm/ksm.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -430,7 +430,7 @@ static struct page *get_mergeable_page(struct rmap_item *rmap_item) page = follow_page(vma, addr, FOLL_GET); if (IS_ERR_OR_NULL(page)) goto out; - if (PageAnon(page)) { + if (PageAnon(page) && !PageTransCompound(page)) { flush_anon_page(vma, page, addr); flush_dcache_page(page); } else { @@ -1279,7 +1279,19 @@ next_mm: if (ksm_test_exit(mm)) break; *page = follow_page(vma, ksm_scan.address, FOLL_GET); - if (!IS_ERR_OR_NULL(*page) && PageAnon(*page)) { + if (IS_ERR_OR_NULL(*page)) { + ksm_scan.address += PAGE_SIZE; + cond_resched(); + continue; + } + if (PageTransCompound(*page)) { + put_page(*page); + ksm_scan.address &= HPAGE_PMD_MASK; + ksm_scan.address += HPAGE_PMD_SIZE; + cond_resched(); + continue; + } + if (PageAnon(*page)) { flush_anon_page(vma, *page, ksm_scan.address); flush_dcache_page(*page); rmap_item = get_next_rmap_item(slot, @@ -1293,8 +1305,7 @@ next_mm: up_read(&mm->mmap_sem); return rmap_item; } - if (!IS_ERR_OR_NULL(*page)) - put_page(*page); + put_page(*page); ksm_scan.address += PAGE_SIZE; cond_resched(); } |