|
@@ -23,28 +23,44 @@
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
+static int mm_counter(struct page *page)
|
|
|
+{
|
|
|
+ return PageAnon(page) ? MM_ANONPAGES : MM_FILEPAGES;
|
|
|
+}
|
|
|
+
|
|
|
static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
|
unsigned long addr, pte_t *ptep)
|
|
|
{
|
|
|
pte_t pte = *ptep;
|
|
|
+ struct page *page;
|
|
|
+ swp_entry_t entry;
|
|
|
|
|
|
if (pte_present(pte)) {
|
|
|
- struct page *page;
|
|
|
-
|
|
|
flush_cache_page(vma, addr, pte_pfn(pte));
|
|
|
pte = ptep_clear_flush(vma, addr, ptep);
|
|
|
page = vm_normal_page(vma, addr, pte);
|
|
|
if (page) {
|
|
|
if (pte_dirty(pte))
|
|
|
set_page_dirty(page);
|
|
|
+ update_hiwater_rss(mm);
|
|
|
+ dec_mm_counter(mm, mm_counter(page));
|
|
|
page_remove_rmap(page);
|
|
|
page_cache_release(page);
|
|
|
+ }
|
|
|
+ } else { /* zap_pte() is not called when pte_none() */
|
|
|
+ if (!pte_file(pte)) {
|
|
|
update_hiwater_rss(mm);
|
|
|
- dec_mm_counter(mm, MM_FILEPAGES);
|
|
|
+ entry = pte_to_swp_entry(pte);
|
|
|
+ if (non_swap_entry(entry)) {
|
|
|
+ if (is_migration_entry(entry)) {
|
|
|
+ page = migration_entry_to_page(entry);
|
|
|
+ dec_mm_counter(mm, mm_counter(page));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ free_swap_and_cache(entry);
|
|
|
+ dec_mm_counter(mm, MM_SWAPENTS);
|
|
|
+ }
|
|
|
}
|
|
|
- } else {
|
|
|
- if (!pte_file(pte))
|
|
|
- free_swap_and_cache(pte_to_swp_entry(pte));
|
|
|
pte_clear_not_present_full(mm, addr, ptep, 0);
|
|
|
}
|
|
|
}
|