aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/fremap.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/mm/fremap.c b/mm/fremap.c
index 224cc1598b35..7f08d10ceaff 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -20,34 +20,32 @@
20#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
21#include <asm/tlbflush.h> 21#include <asm/tlbflush.h>
22 22
23static inline void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma, 23static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
24 unsigned long addr, pte_t *ptep) 24 unsigned long addr, pte_t *ptep)
25{ 25{
26 pte_t pte = *ptep; 26 pte_t pte = *ptep;
27 struct page *page = NULL;
27 28
28 if (pte_none(pte))
29 return;
30 if (pte_present(pte)) { 29 if (pte_present(pte)) {
31 unsigned long pfn = pte_pfn(pte); 30 unsigned long pfn = pte_pfn(pte);
32 struct page *page;
33
34 flush_cache_page(vma, addr, pfn); 31 flush_cache_page(vma, addr, pfn);
35 pte = ptep_clear_flush(vma, addr, ptep); 32 pte = ptep_clear_flush(vma, addr, ptep);
36 if (unlikely(!pfn_valid(pfn))) { 33 if (unlikely(!pfn_valid(pfn))) {
37 print_bad_pte(vma, pte, addr); 34 print_bad_pte(vma, pte, addr);
38 return; 35 goto out;
39 } 36 }
40 page = pfn_to_page(pfn); 37 page = pfn_to_page(pfn);
41 if (pte_dirty(pte)) 38 if (pte_dirty(pte))
42 set_page_dirty(page); 39 set_page_dirty(page);
43 page_remove_rmap(page); 40 page_remove_rmap(page);
44 page_cache_release(page); 41 page_cache_release(page);
45 dec_mm_counter(mm, file_rss);
46 } else { 42 } else {
47 if (!pte_file(pte)) 43 if (!pte_file(pte))
48 free_swap_and_cache(pte_to_swp_entry(pte)); 44 free_swap_and_cache(pte_to_swp_entry(pte));
49 pte_clear(mm, addr, ptep); 45 pte_clear(mm, addr, ptep);
50 } 46 }
47out:
48 return !!page;
51} 49}
52 50
53/* 51/*
@@ -96,9 +94,9 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
96 if (page_mapcount(page) > INT_MAX/2) 94 if (page_mapcount(page) > INT_MAX/2)
97 goto err_unlock; 95 goto err_unlock;
98 96
99 zap_pte(mm, vma, addr, pte); 97 if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
98 inc_mm_counter(mm, file_rss);
100 99
101 inc_mm_counter(mm, file_rss);
102 flush_icache_page(vma, page); 100 flush_icache_page(vma, page);
103 set_pte_at(mm, addr, pte, mk_pte(page, prot)); 101 set_pte_at(mm, addr, pte, mk_pte(page, prot));
104 page_add_file_rmap(page); 102 page_add_file_rmap(page);
@@ -145,7 +143,8 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma,
145 if (!pte) 143 if (!pte)
146 goto err_unlock; 144 goto err_unlock;
147 145
148 zap_pte(mm, vma, addr, pte); 146 if (!pte_none(*pte) && zap_pte(mm, vma, addr, pte))
147 dec_mm_counter(mm, file_rss);
149 148
150 set_pte_at(mm, addr, pte, pgoff_to_pte(pgoff)); 149 set_pte_at(mm, addr, pte, pgoff_to_pte(pgoff));
151 pte_val = *pte; 150 pte_val = *pte;