On Fri, 10 Feb 2023 09:18:52 +0800 (CST) <yang.yang29@xxxxxxxxxx> wrote: > From: xu xin <xu.xin16@xxxxxxxxxx> > > As pages_sharing and pages_shared don't include the number of zero pages > merged by KSM, we cannot know how many pages are zero pages placed by KSM > when enabling use_zero_pages, which leads to KSM not being transparent with > all actual merged pages by KSM. In the early days of use_zero_pages, > zero-pages was unable to get unshared by the ways like MADV_UNMERGEABLE so > it's hard to count how many times one of those zeropages was then unmerged. > > But now, unsharing KSM-placed zero page accurately has been achieved, so we > can easily count both how many times a page full of zeroes was merged with > zero-page and how many times one of those pages was then unmerged. and so, > it helps to estimate memory demands when each and every shared page could > get unshared. > > So we add zero_pages_sharing under /sys/kernel/mm/ksm/ to show the number > of all zero pages placed by KSM. > > Signed-off-by: xu xin <xu.xin16@xxxxxxxxxx> > Cc: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx> > Cc: David Hildenbrand <david@xxxxxxxxxx> > Cc: Xuexin Jiang <jiang.xuexin@xxxxxxxxxx> > Reviewed-by: Xiaokai Ran <ran.xiaokai@xxxxxxxxxx> > Reviewed-by: Yang Yang <yang.yang29@xxxxxxxxxx> Reviewed-by: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx> > > v4->v5: > fix warning mm/ksm.c:3238:9: warning: no previous prototype for > 'zero_pages_sharing_show' [-Wmissing-prototypes]. > --- > mm/ksm.c | 19 +++++++++++++++++-- > 1 file changed, 17 insertions(+), 2 deletions(-) > > diff --git a/mm/ksm.c b/mm/ksm.c > index ab04b44679c8..1fa668e1fe82 100644 > --- a/mm/ksm.c > +++ b/mm/ksm.c > @@ -276,6 +276,9 @@ static unsigned int zero_checksum __read_mostly; > /* Whether to merge empty (zeroed) pages with actual zero pages */ > static bool ksm_use_zero_pages __read_mostly; > > +/* The number of zero pages placed by KSM use_zero_pages */ > +static unsigned long ksm_zero_pages_sharing; > + > #ifdef CONFIG_NUMA > /* Zeroed when merging across nodes is not allowed */ > static unsigned int ksm_merge_across_nodes = 1; > @@ -789,8 +792,10 @@ static struct page *get_ksm_page(struct ksm_stable_node *stable_node, > */ > static inline void clean_rmap_item_zero_flag(struct ksm_rmap_item *rmap_item) > { > - if (rmap_item->address & ZERO_PAGE_FLAG) > + if (rmap_item->address & ZERO_PAGE_FLAG) { > + ksm_zero_pages_sharing--; > rmap_item->address &= PAGE_MASK; > + } > } > > /* Only called when rmap_item is going to be freed */ > @@ -2109,8 +2114,10 @@ static int try_to_merge_with_kernel_zero_page(struct ksm_rmap_item *rmap_item, > if (vma) { > err = try_to_merge_one_page(vma, page, > ZERO_PAGE(rmap_item->address)); > - if (!err) > + if (!err) { > rmap_item->address |= ZERO_PAGE_FLAG; > + ksm_zero_pages_sharing++; > + } > } else { > /* If the vma is out of date, we do not need to continue. */ > err = 0; > @@ -3230,6 +3237,13 @@ static ssize_t pages_volatile_show(struct kobject *kobj, > } > KSM_ATTR_RO(pages_volatile); > > +static ssize_t zero_pages_sharing_show(struct kobject *kobj, > + struct kobj_attribute *attr, char *buf) > +{ > + return sysfs_emit(buf, "%ld\n", ksm_zero_pages_sharing); > +} > +KSM_ATTR_RO(zero_pages_sharing); > + > static ssize_t stable_node_dups_show(struct kobject *kobj, > struct kobj_attribute *attr, char *buf) > { > @@ -3285,6 +3299,7 @@ static struct attribute *ksm_attrs[] = { > &pages_sharing_attr.attr, > &pages_unshared_attr.attr, > &pages_volatile_attr.attr, > + &zero_pages_sharing_attr.attr, > &full_scans_attr.attr, > #ifdef CONFIG_NUMA > &merge_across_nodes_attr.attr,