Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: add new KSM process and sysfs knobs

This adds the general_profit KSM sysfs knob and the process profit metric
knobs to ksm_stat.

1) expose general_profit metric

The documentation mentions a general profit metric, however this
metric is not calculated. In addition the formula depends on the size
of internal structures, which makes it more difficult for an
administrator to make the calculation. Adding the metric for a better
user experience.

2) document general_profit sysfs knob

3) calculate ksm process profit metric

The ksm documentation mentions the process profit metric and how to
calculate it. This adds the calculation of the metric.

4) mm: expose ksm process profit metric in ksm_stat

This exposes the ksm process profit metric in /proc/<pid>/ksm_stat.
The documentation mentions the formula for the ksm process profit
metric, however it does not calculate it. In addition the formula
depends on the size of internal structures. So it makes sense to
expose it.

5) document new procfs ksm knobs

Link: https://lkml.kernel.org/r/20230418051342.1919757-3-shr@devkernel.io
Signed-off-by: Stefan Roesch <shr@devkernel.io>
Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Rik van Riel <riel@surriel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Stefan Roesch and committed by
Andrew Morton
d21077fb d7597f59

+41 -1
+8
Documentation/ABI/testing/sysfs-kernel-mm-ksm
··· 51 51 52 52 When it is set to 0 only pages from the same node are merged, 53 53 otherwise pages from all nodes can be merged together (default). 54 + 55 + What: /sys/kernel/mm/ksm/general_profit 56 + Date: April 2023 57 + KernelVersion: 6.4 58 + Contact: Linux memory management mailing list <linux-mm@kvack.org> 59 + Description: Measure how effective KSM is. 60 + general_profit: how effective is KSM. The formula for the 61 + calculation is in Documentation/admin-guide/mm/ksm.rst.
+4 -1
Documentation/admin-guide/mm/ksm.rst
··· 157 157 158 158 The effectiveness of KSM and MADV_MERGEABLE is shown in ``/sys/kernel/mm/ksm/``: 159 159 160 + general_profit 161 + how effective is KSM. The calculation is explained below. 160 162 pages_shared 161 163 how many shared pages are being used 162 164 pages_sharing ··· 209 207 ksm_rmap_items * sizeof(rmap_item). 210 208 211 209 where ksm_merging_pages is shown under the directory ``/proc/<pid>/``, 212 - and ksm_rmap_items is shown in ``/proc/<pid>/ksm_stat``. 210 + and ksm_rmap_items is shown in ``/proc/<pid>/ksm_stat``. The process profit 211 + is also shown in ``/proc/<pid>/ksm_stat`` as ksm_process_profit. 213 212 214 213 From the perspective of application, a high ratio of ``ksm_rmap_items`` to 215 214 ``ksm_merging_pages`` means a bad madvise-applied policy, so developers or
+3
fs/proc/base.c
··· 96 96 #include <linux/time_namespace.h> 97 97 #include <linux/resctrl.h> 98 98 #include <linux/cn_proc.h> 99 + #include <linux/ksm.h> 99 100 #include <trace/events/oom.h> 100 101 #include "internal.h" 101 102 #include "fd.h" ··· 3208 3207 mm = get_task_mm(task); 3209 3208 if (mm) { 3210 3209 seq_printf(m, "ksm_rmap_items %lu\n", mm->ksm_rmap_items); 3210 + seq_printf(m, "ksm_merging_pages %lu\n", mm->ksm_merging_pages); 3211 + seq_printf(m, "ksm_process_profit %ld\n", ksm_process_profit(mm)); 3211 3212 mmput(mm); 3212 3213 } 3213 3214
+5
include/linux/ksm.h
··· 68 68 void collect_procs_ksm(struct page *page, struct list_head *to_kill, 69 69 int force_early); 70 70 #endif 71 + 72 + #ifdef CONFIG_PROC_FS 73 + long ksm_process_profit(struct mm_struct *); 74 + #endif /* CONFIG_PROC_FS */ 75 + 71 76 #else /* !CONFIG_KSM */ 72 77 73 78 static inline void ksm_add_vma(struct vm_area_struct *vma)
+21
mm/ksm.c
··· 3007 3007 } 3008 3008 #endif /* CONFIG_MEMORY_HOTREMOVE */ 3009 3009 3010 + #ifdef CONFIG_PROC_FS 3011 + long ksm_process_profit(struct mm_struct *mm) 3012 + { 3013 + return mm->ksm_merging_pages * PAGE_SIZE - 3014 + mm->ksm_rmap_items * sizeof(struct ksm_rmap_item); 3015 + } 3016 + #endif /* CONFIG_PROC_FS */ 3017 + 3010 3018 #ifdef CONFIG_SYSFS 3011 3019 /* 3012 3020 * This all compiles without CONFIG_SYSFS, but is a waste of space. ··· 3279 3271 } 3280 3272 KSM_ATTR_RO(pages_volatile); 3281 3273 3274 + static ssize_t general_profit_show(struct kobject *kobj, 3275 + struct kobj_attribute *attr, char *buf) 3276 + { 3277 + long general_profit; 3278 + 3279 + general_profit = ksm_pages_sharing * PAGE_SIZE - 3280 + ksm_rmap_items * sizeof(struct ksm_rmap_item); 3281 + 3282 + return sysfs_emit(buf, "%ld\n", general_profit); 3283 + } 3284 + KSM_ATTR_RO(general_profit); 3285 + 3282 3286 static ssize_t stable_node_dups_show(struct kobject *kobj, 3283 3287 struct kobj_attribute *attr, char *buf) 3284 3288 { ··· 3355 3335 &stable_node_dups_attr.attr, 3356 3336 &stable_node_chains_prune_millisecs_attr.attr, 3357 3337 &use_zero_pages_attr.attr, 3338 + &general_profit_attr.attr, 3358 3339 NULL, 3359 3340 }; 3360 3341