[PATCH 22 of 25] split_huge_page paging

Andrea Arcangeli
2009-11-14T18:10:25Z

Paging logic that splits the page before it is unmapped and added to swap to
ensure backwards compatibility with the legacy swap code. Eventually swap
should natively pageout the hugepages to increase performance and decrease
seeking and fragmentation of swap space. swapoff can just skip over huge pmd as
they cannot be part of swap yet.

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
---

diff --git a/mm/rmap.c b/mm/rmap.c
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1248,6 +1248,10 @@ int try_to_unmap(struct page *page, enum

BUG_ON(!PageLocked(page));

+ if (unlikely(PageCompound(page)))
+ if (unlikely(split_huge_page(page)))
+ return SWAP_AGAIN;
+
if (PageAnon(page))
ret = try_to_unmap_anon(page, flags);
else
diff --git a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -152,6 +152,10 @@ int add_to_swap(struct page *page)
VM_BUG_ON(!PageLocked(page));
VM_BUG_ON(!PageUptodate(page));

+ if (unlikely(PageCompound(page)))
+ if (unlikely(split_huge_page(page)))
+ return 0;
+
entry = get_swap_page();
if (!entry.val)
return 0;
diff --git a/mm/swapfile.c b/mm/swapfile.c
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -896,6 +896,8 @@ static inline int unuse_pmd_range(struct
pmd = pmd_offset(pud, addr);
do {
next = pmd_addr_end(addr, end);
+ if (unlikely(pmd_trans_huge(*pmd)))
+ continue;
if (pmd_none_or_clear_bad(pmd))
continue;
ret = unuse_pte_range(vma, pmd, addr, next, entry, page);