diff options
Diffstat (limited to 'mm/fremap.c')
| -rw-r--r-- | mm/fremap.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/mm/fremap.c b/mm/fremap.c index bbc4d660221a..34feba60a17e 100644 --- a/mm/fremap.c +++ b/mm/fremap.c | |||
| @@ -23,28 +23,44 @@ | |||
| 23 | 23 | ||
| 24 | #include "internal.h" | 24 | #include "internal.h" |
| 25 | 25 | ||
| 26 | static int mm_counter(struct page *page) | ||
| 27 | { | ||
| 28 | return PageAnon(page) ? MM_ANONPAGES : MM_FILEPAGES; | ||
| 29 | } | ||
| 30 | |||
| 26 | static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma, | 31 | static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma, |
| 27 | unsigned long addr, pte_t *ptep) | 32 | unsigned long addr, pte_t *ptep) |
| 28 | { | 33 | { |
| 29 | pte_t pte = *ptep; | 34 | pte_t pte = *ptep; |
| 35 | struct page *page; | ||
| 36 | swp_entry_t entry; | ||
| 30 | 37 | ||
| 31 | if (pte_present(pte)) { | 38 | if (pte_present(pte)) { |
| 32 | struct page *page; | ||
| 33 | |||
| 34 | flush_cache_page(vma, addr, pte_pfn(pte)); | 39 | flush_cache_page(vma, addr, pte_pfn(pte)); |
| 35 | pte = ptep_clear_flush(vma, addr, ptep); | 40 | pte = ptep_clear_flush(vma, addr, ptep); |
| 36 | page = vm_normal_page(vma, addr, pte); | 41 | page = vm_normal_page(vma, addr, pte); |
| 37 | if (page) { | 42 | if (page) { |
| 38 | if (pte_dirty(pte)) | 43 | if (pte_dirty(pte)) |
| 39 | set_page_dirty(page); | 44 | set_page_dirty(page); |
| 45 | update_hiwater_rss(mm); | ||
| 46 | dec_mm_counter(mm, mm_counter(page)); | ||
| 40 | page_remove_rmap(page); | 47 | page_remove_rmap(page); |
| 41 | page_cache_release(page); | 48 | page_cache_release(page); |
| 49 | } | ||
| 50 | } else { /* zap_pte() is not called when pte_none() */ | ||
| 51 | if (!pte_file(pte)) { | ||
| 42 | update_hiwater_rss(mm); | 52 | update_hiwater_rss(mm); |
| 43 | dec_mm_counter(mm, MM_FILEPAGES); | 53 | entry = pte_to_swp_entry(pte); |
| 54 | if (non_swap_entry(entry)) { | ||
| 55 | if (is_migration_entry(entry)) { | ||
| 56 | page = migration_entry_to_page(entry); | ||
| 57 | dec_mm_counter(mm, mm_counter(page)); | ||
| 58 | } | ||
| 59 | } else { | ||
| 60 | free_swap_and_cache(entry); | ||
| 61 | dec_mm_counter(mm, MM_SWAPENTS); | ||
| 62 | } | ||
| 44 | } | 63 | } |
| 45 | } else { | ||
| 46 | if (!pte_file(pte)) | ||
| 47 | free_swap_and_cache(pte_to_swp_entry(pte)); | ||
| 48 | pte_clear_not_present_full(mm, addr, ptep, 0); | 64 | pte_clear_not_present_full(mm, addr, ptep, 0); |
| 49 | } | 65 | } |
| 50 | } | 66 | } |
