|
@@ -121,6 +121,7 @@ static int __init init_zero_pfn(void)
|
|
}
|
|
}
|
|
core_initcall(init_zero_pfn);
|
|
core_initcall(init_zero_pfn);
|
|
|
|
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* If a p?d_bad entry is found while walking page tables, report
|
|
* If a p?d_bad entry is found while walking page tables, report
|
|
* the error, before resetting entry to p?d_none. Usually (but
|
|
* the error, before resetting entry to p?d_none. Usually (but
|
|
@@ -376,12 +377,18 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss)
|
|
|
|
|
|
+static inline void init_rss_vec(int *rss)
|
|
{
|
|
{
|
|
- if (file_rss)
|
|
|
|
- add_mm_counter(mm, file_rss, file_rss);
|
|
|
|
- if (anon_rss)
|
|
|
|
- add_mm_counter(mm, anon_rss, anon_rss);
|
|
|
|
|
|
+ memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < NR_MM_COUNTERS; i++)
|
|
|
|
+ if (rss[i])
|
|
|
|
+ add_mm_counter(mm, i, rss[i]);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -632,7 +639,10 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
|
|
if (page) {
|
|
if (page) {
|
|
get_page(page);
|
|
get_page(page);
|
|
page_dup_rmap(page);
|
|
page_dup_rmap(page);
|
|
- rss[PageAnon(page)]++;
|
|
|
|
|
|
+ if (PageAnon(page))
|
|
|
|
+ rss[MM_ANONPAGES]++;
|
|
|
|
+ else
|
|
|
|
+ rss[MM_FILEPAGES]++;
|
|
}
|
|
}
|
|
|
|
|
|
out_set_pte:
|
|
out_set_pte:
|
|
@@ -648,11 +658,12 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
|
|
pte_t *src_pte, *dst_pte;
|
|
pte_t *src_pte, *dst_pte;
|
|
spinlock_t *src_ptl, *dst_ptl;
|
|
spinlock_t *src_ptl, *dst_ptl;
|
|
int progress = 0;
|
|
int progress = 0;
|
|
- int rss[2];
|
|
|
|
|
|
+ int rss[NR_MM_COUNTERS];
|
|
swp_entry_t entry = (swp_entry_t){0};
|
|
swp_entry_t entry = (swp_entry_t){0};
|
|
|
|
|
|
again:
|
|
again:
|
|
- rss[1] = rss[0] = 0;
|
|
|
|
|
|
+ init_rss_vec(rss);
|
|
|
|
+
|
|
dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
|
|
dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
|
|
if (!dst_pte)
|
|
if (!dst_pte)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
@@ -688,7 +699,7 @@ again:
|
|
arch_leave_lazy_mmu_mode();
|
|
arch_leave_lazy_mmu_mode();
|
|
spin_unlock(src_ptl);
|
|
spin_unlock(src_ptl);
|
|
pte_unmap_nested(orig_src_pte);
|
|
pte_unmap_nested(orig_src_pte);
|
|
- add_mm_rss(dst_mm, rss[0], rss[1]);
|
|
|
|
|
|
+ add_mm_rss_vec(dst_mm, rss);
|
|
pte_unmap_unlock(orig_dst_pte, dst_ptl);
|
|
pte_unmap_unlock(orig_dst_pte, dst_ptl);
|
|
cond_resched();
|
|
cond_resched();
|
|
|
|
|
|
@@ -816,8 +827,9 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
|
|
struct mm_struct *mm = tlb->mm;
|
|
struct mm_struct *mm = tlb->mm;
|
|
pte_t *pte;
|
|
pte_t *pte;
|
|
spinlock_t *ptl;
|
|
spinlock_t *ptl;
|
|
- int file_rss = 0;
|
|
|
|
- int anon_rss = 0;
|
|
|
|
|
|
+ int rss[NR_MM_COUNTERS];
|
|
|
|
+
|
|
|
|
+ init_rss_vec(rss);
|
|
|
|
|
|
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
|
|
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
|
|
arch_enter_lazy_mmu_mode();
|
|
arch_enter_lazy_mmu_mode();
|
|
@@ -863,14 +875,14 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
|
|
set_pte_at(mm, addr, pte,
|
|
set_pte_at(mm, addr, pte,
|
|
pgoff_to_pte(page->index));
|
|
pgoff_to_pte(page->index));
|
|
if (PageAnon(page))
|
|
if (PageAnon(page))
|
|
- anon_rss--;
|
|
|
|
|
|
+ rss[MM_ANONPAGES]--;
|
|
else {
|
|
else {
|
|
if (pte_dirty(ptent))
|
|
if (pte_dirty(ptent))
|
|
set_page_dirty(page);
|
|
set_page_dirty(page);
|
|
if (pte_young(ptent) &&
|
|
if (pte_young(ptent) &&
|
|
likely(!VM_SequentialReadHint(vma)))
|
|
likely(!VM_SequentialReadHint(vma)))
|
|
mark_page_accessed(page);
|
|
mark_page_accessed(page);
|
|
- file_rss--;
|
|
|
|
|
|
+ rss[MM_FILEPAGES]--;
|
|
}
|
|
}
|
|
page_remove_rmap(page);
|
|
page_remove_rmap(page);
|
|
if (unlikely(page_mapcount(page) < 0))
|
|
if (unlikely(page_mapcount(page) < 0))
|
|
@@ -893,7 +905,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
|
|
pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
|
|
pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
|
|
} while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));
|
|
} while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));
|
|
|
|
|
|
- add_mm_rss(mm, file_rss, anon_rss);
|
|
|
|
|
|
+ add_mm_rss_vec(mm, rss);
|
|
arch_leave_lazy_mmu_mode();
|
|
arch_leave_lazy_mmu_mode();
|
|
pte_unmap_unlock(pte - 1, ptl);
|
|
pte_unmap_unlock(pte - 1, ptl);
|
|
|
|
|
|
@@ -1527,7 +1539,7 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
|
|
|
|
|
|
/* Ok, finally just insert the thing.. */
|
|
/* Ok, finally just insert the thing.. */
|
|
get_page(page);
|
|
get_page(page);
|
|
- inc_mm_counter(mm, file_rss);
|
|
|
|
|
|
+ inc_mm_counter(mm, MM_FILEPAGES);
|
|
page_add_file_rmap(page);
|
|
page_add_file_rmap(page);
|
|
set_pte_at(mm, addr, pte, mk_pte(page, prot));
|
|
set_pte_at(mm, addr, pte, mk_pte(page, prot));
|
|
|
|
|
|
@@ -2163,11 +2175,11 @@ gotten:
|
|
if (likely(pte_same(*page_table, orig_pte))) {
|
|
if (likely(pte_same(*page_table, orig_pte))) {
|
|
if (old_page) {
|
|
if (old_page) {
|
|
if (!PageAnon(old_page)) {
|
|
if (!PageAnon(old_page)) {
|
|
- dec_mm_counter(mm, file_rss);
|
|
|
|
- inc_mm_counter(mm, anon_rss);
|
|
|
|
|
|
+ dec_mm_counter(mm, MM_FILEPAGES);
|
|
|
|
+ inc_mm_counter(mm, MM_ANONPAGES);
|
|
}
|
|
}
|
|
} else
|
|
} else
|
|
- inc_mm_counter(mm, anon_rss);
|
|
|
|
|
|
+ inc_mm_counter(mm, MM_ANONPAGES);
|
|
flush_cache_page(vma, address, pte_pfn(orig_pte));
|
|
flush_cache_page(vma, address, pte_pfn(orig_pte));
|
|
entry = mk_pte(new_page, vma->vm_page_prot);
|
|
entry = mk_pte(new_page, vma->vm_page_prot);
|
|
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
|
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
|
@@ -2604,7 +2616,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
* discarded at swap_free().
|
|
* discarded at swap_free().
|
|
*/
|
|
*/
|
|
|
|
|
|
- inc_mm_counter(mm, anon_rss);
|
|
|
|
|
|
+ inc_mm_counter(mm, MM_ANONPAGES);
|
|
pte = mk_pte(page, vma->vm_page_prot);
|
|
pte = mk_pte(page, vma->vm_page_prot);
|
|
if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) {
|
|
if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) {
|
|
pte = maybe_mkwrite(pte_mkdirty(pte), vma);
|
|
pte = maybe_mkwrite(pte_mkdirty(pte), vma);
|
|
@@ -2688,7 +2700,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
if (!pte_none(*page_table))
|
|
if (!pte_none(*page_table))
|
|
goto release;
|
|
goto release;
|
|
|
|
|
|
- inc_mm_counter(mm, anon_rss);
|
|
|
|
|
|
+ inc_mm_counter(mm, MM_ANONPAGES);
|
|
page_add_new_anon_rmap(page, vma, address);
|
|
page_add_new_anon_rmap(page, vma, address);
|
|
setpte:
|
|
setpte:
|
|
set_pte_at(mm, address, page_table, entry);
|
|
set_pte_at(mm, address, page_table, entry);
|
|
@@ -2842,10 +2854,10 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
if (flags & FAULT_FLAG_WRITE)
|
|
if (flags & FAULT_FLAG_WRITE)
|
|
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
|
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
|
|
if (anon) {
|
|
if (anon) {
|
|
- inc_mm_counter(mm, anon_rss);
|
|
|
|
|
|
+ inc_mm_counter(mm, MM_ANONPAGES);
|
|
page_add_new_anon_rmap(page, vma, address);
|
|
page_add_new_anon_rmap(page, vma, address);
|
|
} else {
|
|
} else {
|
|
- inc_mm_counter(mm, file_rss);
|
|
|
|
|
|
+ inc_mm_counter(mm, MM_FILEPAGES);
|
|
page_add_file_rmap(page);
|
|
page_add_file_rmap(page);
|
|
if (flags & FAULT_FLAG_WRITE) {
|
|
if (flags & FAULT_FLAG_WRITE) {
|
|
dirty_page = page;
|
|
dirty_page = page;
|