mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Hildenbrand <david@redhat.com>
To: Longlong Xia <xialonglong@kylinos.cn>,
	akpm@linux-foundation.org, xu.xin16@zte.com.cn
Cc: chengming.zhou@linux.dev, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, Stefan Roesch <shr@devkernel.io>
Subject: Re: [PATCH 1/1] mm/ksm: add ksm_pages_sharing for each process to calculate profit more accurately
Date: Fri, 6 Jun 2025 12:08:47 +0200	[thread overview]
Message-ID: <63145e68-76f7-44a1-b3fb-1213eaa959d0@redhat.com> (raw)
In-Reply-To: <20250606070314.3028593-1-xialonglong@kylinos.cn>

On 06.06.25 09:03, Longlong Xia wrote:

CCing Stefan.

> The general_profit_show() function only considers ksm_pages_sharing,
> while ksm_process_profit() includes both ksm_pages_sharing and
> ksm_pages_shared for each process. This leads to a mismatch between
> the total profits from ksm_process_profit() and general_profit_show().
> 
> Based on my tests, the sum of ksm_process_profit() for all processes
> can be up to 20% higher than general_profit_show(), depending on
> the size of page_shared. For individual processes, the ratio of
> ksm_pages_sharing to ksm_merging_pages is usually not equal to 1.
> 
> To resolve this, we suggest introducing ksm_pages_sharing for each
> process to accurately calculate its pages_sharing, ensuring
> ksm_process_profit() reflects shared memory benefits more accurately.
> 
> Add a new proc file named as ksm_pages_sharing both under /proc/<pid>/

It's an entry in the file, not a new file.

> and /proc/self/ksm_stat/ to indicate the saved pages of this process.
> (not including ksm_zero_pages)

Curious, why is updating ksm_process_profit() insufficient and we also 
have to expose ksm_pages_sharing?

> 
> Suggested-by: Xu Xin <xu.xin16@zte.com.cn>
> Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
> ---
>   Documentation/admin-guide/mm/ksm.rst |  5 +++--
>   Documentation/filesystems/proc.rst   |  8 ++++++++
>   fs/proc/base.c                       | 18 ++++++++++++++++++
>   include/linux/mm_types.h             |  5 +++++
>   mm/ksm.c                             | 12 ++++++++----
>   5 files changed, 42 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/admin-guide/mm/ksm.rst b/Documentation/admin-guide/mm/ksm.rst
> index ad8e7a41f3b5..0b33ef98930f 100644
> --- a/Documentation/admin-guide/mm/ksm.rst
> +++ b/Documentation/admin-guide/mm/ksm.rst
> @@ -256,9 +256,10 @@ several times, which are unprofitable memory consumed.
>   	process_profit =~ ksm_saved_pages * sizeof(page) -
>   			  ksm_rmap_items * sizeof(rmap_item).
>   
> -   where ksm_saved_pages equals to the sum of ``ksm_merging_pages`` and
> +   where ksm_saved_pages equals to the sum of ``ksm_pages_sharing`` and
>      ``ksm_zero_pages``, both of which are shown under the directory
> -   ``/proc/<pid>/ksm_stat``, and ksm_rmap_items is also shown in
> +   ``/proc/<pid>/ksm_stat``, ksm_merging_pages and ksm_rmap_items are
> +   also shown in
>      ``/proc/<pid>/ksm_stat``. The process profit is also shown in
>      ``/proc/<pid>/ksm_stat`` as ksm_process_profit.
>   
> diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst
> index 2a17865dfe39..e14ea8389500 100644
> --- a/Documentation/filesystems/proc.rst
> +++ b/Documentation/filesystems/proc.rst
> @@ -2290,6 +2290,7 @@ Example
>       / # cat /proc/self/ksm_stat
>       ksm_rmap_items 0
>       ksm_zero_pages 0
> +    ksm_pages_sharing 0
>       ksm_merging_pages 0
>       ksm_process_profit 0
>       ksm_merge_any: no
> @@ -2312,6 +2313,13 @@ ksm_zero_pages
>   When /sys/kernel/mm/ksm/use_zero_pages is enabled, it represent how many
>   empty pages are merged with kernel zero pages by KSM.
>   
> +ksm_pages_sharing
> +^^^^^^^^^^^^^^^^^
> +
> +It represents how many pages saved of this process.
> +(not including ksm_zero_pages). It is the same with what
> +/proc/<pid>/ksm_pages_sharing shows.
 > +>   ksm_merging_pages
>   ^^^^^^^^^^^^^^^^^
>   
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index c667702dc69b..327bf82acf54 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -3262,6 +3262,21 @@ static int proc_pid_ksm_merging_pages(struct seq_file *m, struct pid_namespace *
>   
>   	return 0;
>   }
> +
> +static int proc_pid_ksm_pages_sharing(struct seq_file *m, struct pid_namespace *ns,
> +				struct pid *pid, struct task_struct *task)
> +{
> +	struct mm_struct *mm;
> +
> +	mm = get_task_mm(task);
> +	if (mm) {
> +		seq_printf(m, "%lu\n", mm->ksm_pages_sharing);
> +		mmput(mm);
> +	}
> +
> +	return 0;
> +}
> +
>   static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns,
>   				struct pid *pid, struct task_struct *task)
>   {
> @@ -3272,6 +3287,7 @@ static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns,
>   	if (mm) {
>   		seq_printf(m, "ksm_rmap_items %lu\n", mm->ksm_rmap_items);
>   		seq_printf(m, "ksm_zero_pages %ld\n", mm_ksm_zero_pages(mm));
> +		seq_printf(m, "ksm_pages_sharing %lu\n", mm->ksm_pages_sharing);
>   		seq_printf(m, "ksm_merging_pages %lu\n", mm->ksm_merging_pages);
>   		seq_printf(m, "ksm_process_profit %ld\n", ksm_process_profit(mm));
>   		seq_printf(m, "ksm_merge_any: %s\n",
> @@ -3421,6 +3437,7 @@ static const struct pid_entry tgid_base_stuff[] = {
>   	ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache),
>   #endif
>   #ifdef CONFIG_KSM
> +	ONE("ksm_pages_sharing",  S_IRUSR, proc_pid_ksm_pages_sharing),
>   	ONE("ksm_merging_pages",  S_IRUSR, proc_pid_ksm_merging_pages),
>   	ONE("ksm_stat",  S_IRUSR, proc_pid_ksm_stat),
>   #endif
> @@ -3758,6 +3775,7 @@ static const struct pid_entry tid_base_stuff[] = {
>   	ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache),
>   #endif
>   #ifdef CONFIG_KSM
> +	ONE("ksm_pages_sharing",  S_IRUSR, proc_pid_ksm_pages_sharing),
>   	ONE("ksm_merging_pages",  S_IRUSR, proc_pid_ksm_merging_pages),
>   	ONE("ksm_stat",  S_IRUSR, proc_pid_ksm_stat),
>   #endif
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index d6b91e8a66d6..d260cb09c10a 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -1176,6 +1176,11 @@ struct mm_struct {
>   		 * merging (not including ksm_zero_pages).
>   		 */
>   		unsigned long ksm_merging_pages;
> +		/*
> +		 * Represents how many pages saved of this process.
> +		 * (not including ksm_zero_pages).
> +		 */
> +		unsigned long ksm_pages_sharing;
>   		/*
>   		 * Represent how many pages are checked for ksm merging
>   		 * including merged and not merged.
> diff --git a/mm/ksm.c b/mm/ksm.c
> index 8583fb91ef13..c2d85ea07b1c 100644
> --- a/mm/ksm.c
> +++ b/mm/ksm.c
> @@ -824,6 +824,7 @@ static void remove_node_from_stable_tree(struct ksm_stable_node *stable_node)
>   	hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) {
>   		if (rmap_item->hlist.next) {
>   			ksm_pages_sharing--;
> +			rmap_item->mm->ksm_pages_sharing--;
>   			trace_ksm_remove_rmap_item(stable_node->kpfn, rmap_item, rmap_item->mm);
>   		} else {
>   			ksm_pages_shared--;
> @@ -976,8 +977,10 @@ static void remove_rmap_item_from_tree(struct ksm_rmap_item *rmap_item)
>   		folio_unlock(folio);
>   		folio_put(folio);
>   
> -		if (!hlist_empty(&stable_node->hlist))
> +		if (!hlist_empty(&stable_node->hlist)) {
>   			ksm_pages_sharing--;
> +			rmap_item->mm->ksm_pages_sharing--;
> +		}


Hm, I am wondering if that works. Stable nodes are not per MM, so can't 
we create an accounting imbalance for one MM somehow?

(did not look into all the details, just something that came to mind)

-- 
Cheers,

David / dhildenb


  reply	other threads:[~2025-06-06 10:08 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-06  7:03 Longlong Xia
2025-06-06 10:08 ` David Hildenbrand [this message]
2025-06-18  7:13   ` Longlong Xia
2025-06-18  9:14     ` xu.xin16
2025-06-24  8:35       ` Longlong Xia
2025-06-24  9:47         ` 答复: " xu.xin16

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=63145e68-76f7-44a1-b3fb-1213eaa959d0@redhat.com \
    --to=david@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=chengming.zhou@linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=shr@devkernel.io \
    --cc=xialonglong@kylinos.cn \
    --cc=xu.xin16@zte.com.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®