Skip to content

Commit 6080d19

Browse files
xu xinakpm00
authored andcommitted
ksm: add ksm zero pages for each process
As the number of ksm zero pages is not included in ksm_merging_pages per process when enabling use_zero_pages, it's unclear of how many actual pages are merged by KSM. To let users accurately estimate their memory demands when unsharing KSM zero-pages, it's necessary to show KSM zero- pages per process. In addition, it help users to know the actual KSM profit because KSM-placed zero pages are also benefit from KSM. since unsharing zero pages placed by KSM accurately is achieved, then tracking empty pages merging and unmerging is not a difficult thing any longer. Since we already have /proc/<pid>/ksm_stat, just add the information of 'ksm_zero_pages' in it. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: xu xin <[email protected]> Acked-by: David Hildenbrand <[email protected]> Reviewed-by: Xiaokai Ran <[email protected]> Reviewed-by: Yang Yang <[email protected]> Cc: Claudio Imbrenda <[email protected]> Cc: Xuexin Jiang <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent e294206 commit 6080d19

File tree

6 files changed

+17
-8
lines changed

6 files changed

+17
-8
lines changed

fs/proc/base.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,6 +3207,7 @@ static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns,
32073207
mm = get_task_mm(task);
32083208
if (mm) {
32093209
seq_printf(m, "ksm_rmap_items %lu\n", mm->ksm_rmap_items);
3210+
seq_printf(m, "ksm_zero_pages %lu\n", mm->ksm_zero_pages);
32103211
seq_printf(m, "ksm_merging_pages %lu\n", mm->ksm_merging_pages);
32113212
seq_printf(m, "ksm_process_profit %ld\n", ksm_process_profit(mm));
32123213
mmput(mm);

include/linux/ksm.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ void __ksm_exit(struct mm_struct *mm);
3535

3636
extern unsigned long ksm_zero_pages;
3737

38-
static inline void ksm_might_unmap_zero_page(pte_t pte)
38+
static inline void ksm_might_unmap_zero_page(struct mm_struct *mm, pte_t pte)
3939
{
40-
if (is_ksm_zero_pte(pte))
40+
if (is_ksm_zero_pte(pte)) {
4141
ksm_zero_pages--;
42+
mm->ksm_zero_pages--;
43+
}
4244
}
4345

4446
static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
@@ -109,7 +111,7 @@ static inline void ksm_exit(struct mm_struct *mm)
109111
{
110112
}
111113

112-
static inline void ksm_might_unmap_zero_page(pte_t pte)
114+
static inline void ksm_might_unmap_zero_page(struct mm_struct *mm, pte_t pte)
113115
{
114116
}
115117

include/linux/mm_types.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,15 +812,20 @@ struct mm_struct {
812812
#ifdef CONFIG_KSM
813813
/*
814814
* Represent how many pages of this process are involved in KSM
815-
* merging.
815+
* merging (not including ksm_zero_pages).
816816
*/
817817
unsigned long ksm_merging_pages;
818818
/*
819819
* Represent how many pages are checked for ksm merging
820820
* including merged and not merged.
821821
*/
822822
unsigned long ksm_rmap_items;
823-
#endif
823+
/*
824+
* Represent how many empty pages are merged with kernel zero
825+
* pages when enabling KSM use_zero_pages.
826+
*/
827+
unsigned long ksm_zero_pages;
828+
#endif /* CONFIG_KSM */
824829
#ifdef CONFIG_LRU_GEN
825830
struct {
826831
/* this mm_struct is on lru_gen_mm_list */

mm/khugepaged.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ static void __collapse_huge_page_copy_succeeded(pte_t *pte,
710710
spin_lock(ptl);
711711
ptep_clear(vma->vm_mm, address, _pte);
712712
spin_unlock(ptl);
713-
ksm_might_unmap_zero_page(pteval);
713+
ksm_might_unmap_zero_page(vma->vm_mm, pteval);
714714
}
715715
} else {
716716
src_page = pte_page(pteval);

mm/ksm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
12331233
*/
12341234
newpte = pte_mkdirty(pte_mkspecial(pfn_pte(page_to_pfn(kpage), vma->vm_page_prot)));
12351235
ksm_zero_pages++;
1236+
mm->ksm_zero_pages++;
12361237
/*
12371238
* We're replacing an anonymous page with a zero page, which is
12381239
* not anonymous. We need to do proper accounting otherwise we

mm/memory.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
14341434
zap_install_uffd_wp_if_needed(vma, addr, pte, details,
14351435
ptent);
14361436
if (unlikely(!page)) {
1437-
ksm_might_unmap_zero_page(ptent);
1437+
ksm_might_unmap_zero_page(mm, ptent);
14381438
continue;
14391439
}
14401440

@@ -3130,7 +3130,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
31303130
inc_mm_counter(mm, MM_ANONPAGES);
31313131
}
31323132
} else {
3133-
ksm_might_unmap_zero_page(vmf->orig_pte);
3133+
ksm_might_unmap_zero_page(mm, vmf->orig_pte);
31343134
inc_mm_counter(mm, MM_ANONPAGES);
31353135
}
31363136
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));

0 commit comments

Comments
 (0)