aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Weitz <konstantin.weitz@gmail.com>2013-04-17 07:59:32 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-02-21 02:50:18 -0500
commit45961722f8e30ceab9d135b1ddc0947d53aef7c3 (patch)
treecfc391e0bcb2958625565ebbc480fe11ef95bcaf
parent53e857f30867918b3618d8e18902e63291946ef4 (diff)
mm: add support for discard of unused ptes
In a virtualized environment and given an appropriate interface the guest can mark pages as unused while they are free (for the s390 implementation see git commit 45e576b1c3d00206 "guest page hinting light"). For the host the unused state is a property of the pte. This patch adds the primitive 'pte_unused' and code to the host swap out handler so that pages marked as unused by all mappers are not swapped out but discarded instead, thus saving one IO for swap out and potentially another one for swap in. [ Martin Schwidefsky: patch reordering and simplification ] Signed-off-by: Konstantin Weitz <konstantin.weitz@gmail.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--include/asm-generic/pgtable.h13
-rw-r--r--mm/rmap.c10
2 files changed, 23 insertions, 0 deletions
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 34c7bdc06014..1ec08c198b66 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -193,6 +193,19 @@ static inline int pte_same(pte_t pte_a, pte_t pte_b)
193} 193}
194#endif 194#endif
195 195
196#ifndef __HAVE_ARCH_PTE_UNUSED
197/*
198 * Some architectures provide facilities to virtualization guests
199 * so that they can flag allocated pages as unused. This allows the
200 * host to transparently reclaim unused pages. This function returns
201 * whether the pte's page is unused.
202 */
203static inline int pte_unused(pte_t pte)
204{
205 return 0;
206}
207#endif
208
196#ifndef __HAVE_ARCH_PMD_SAME 209#ifndef __HAVE_ARCH_PMD_SAME
197#ifdef CONFIG_TRANSPARENT_HUGEPAGE 210#ifdef CONFIG_TRANSPARENT_HUGEPAGE
198static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) 211static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
diff --git a/mm/rmap.c b/mm/rmap.c
index d9d42316a99a..9056a1f00b87 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1165,6 +1165,16 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
1165 } 1165 }
1166 set_pte_at(mm, address, pte, 1166 set_pte_at(mm, address, pte,
1167 swp_entry_to_pte(make_hwpoison_entry(page))); 1167 swp_entry_to_pte(make_hwpoison_entry(page)));
1168 } else if (pte_unused(pteval)) {
1169 /*
1170 * The guest indicated that the page content is of no
1171 * interest anymore. Simply discard the pte, vmscan
1172 * will take care of the rest.
1173 */
1174 if (PageAnon(page))
1175 dec_mm_counter(mm, MM_ANONPAGES);
1176 else
1177 dec_mm_counter(mm, MM_FILEPAGES);
1168 } else if (PageAnon(page)) { 1178 } else if (PageAnon(page)) {
1169 swp_entry_t entry = { .val = page_private(page) }; 1179 swp_entry_t entry = { .val = page_private(page) };
1170 pte_t swp_pte; 1180 pte_t swp_pte;