From patchwork Fri Feb 24 04:39:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roesch X-Patchwork-Id: 13150932 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4CC42C677F1 for ; Fri, 24 Feb 2023 04:44:07 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id BDEB96B0073; Thu, 23 Feb 2023 23:44:06 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id B90596B007D; Thu, 23 Feb 2023 23:44:06 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A56706B007E; Thu, 23 Feb 2023 23:44:06 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 9380E6B0073 for ; Thu, 23 Feb 2023 23:44:06 -0500 (EST) Received: from smtpin10.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 68CB61213D2 for ; Fri, 24 Feb 2023 04:44:06 +0000 (UTC) X-FDA: 80500943292.10.0ABC6A0 Received: from 66-220-144-178.mail-mxout.facebook.com (66-220-144-178.mail-mxout.facebook.com [66.220.144.178]) by imf09.hostedemail.com (Postfix) with ESMTP id CEEF914000D for ; Fri, 24 Feb 2023 04:44:04 +0000 (UTC) Authentication-Results: imf09.hostedemail.com; dkim=none; dmarc=none; spf=neutral (imf09.hostedemail.com: 66.220.144.178 is neither permitted nor denied by domain of shr@devkernel.io) smtp.mailfrom=shr@devkernel.io ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1677213845; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dYd6PJ/+Lz4kyMK226vDPlipneM30k84+9xqFDHWhI4=; b=7EyKtuDEd8kLJ+rwlNdqWk5tLjO7o4+n/8Ux4x3tSAdrDXNu25pADRmpOwIE/FlAmuhVtv 19ZA2prMuPj+2TSUab5hpdM/qAhKJZ4FFhe9+0Ierl9McCLhu2C8d9v5wdL6FAZikHQIGI u9ER1jt2JgzLlhHNEgE4v65bU1s2q48= ARC-Authentication-Results: i=1; imf09.hostedemail.com; dkim=none; dmarc=none; spf=neutral (imf09.hostedemail.com: 66.220.144.178 is neither permitted nor denied by domain of shr@devkernel.io) smtp.mailfrom=shr@devkernel.io ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1677213845; a=rsa-sha256; cv=none; b=esRykPfi/yaPi8hD3d24gBCiSnLzhTuaUb5E1JyD04xWDINLhhcgurp2uptZaPFzqfukox veQZGYjgTHQruSolxReJhIl4DYf7VKP8uuPWEPAJfndf1OAidz5wBb04eyaLVMFOBjkOb7 +ZZHwsLbafDnffFW6Iz6oHaepx/eHiU= Received: by dev0134.prn3.facebook.com (Postfix, from userid 425415) id 0A66F7B74EDD; Thu, 23 Feb 2023 20:40:59 -0800 (PST) From: Stefan Roesch To: kernel-team@fb.com Cc: shr@devkernel.io, linux-mm@kvack.org, riel@surriel.com, mhocko@suse.com, david@redhat.com, linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org, akpm@linux-foundation.org, hannes@cmpxchg.org, Bagas Sanjaya Subject: [PATCH v3 2/3] mm: add new KSM process and sysfs knobs Date: Thu, 23 Feb 2023 20:39:59 -0800 Message-Id: <20230224044000.3084046-3-shr@devkernel.io> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230224044000.3084046-1-shr@devkernel.io> References: <20230224044000.3084046-1-shr@devkernel.io> MIME-Version: 1.0 X-Rspamd-Queue-Id: CEEF914000D X-Rspamd-Server: rspam09 X-Rspam-User: X-Stat-Signature: qk7f4sdrnfq1ucijqe5bbyn11n3j53fr X-HE-Tag: 1677213844-463708 X-HE-Meta: U2FsdGVkX197rs+9c2Fp2gl8RbcAPzgUVm0jb1l26+qohnvZmaBmlLBeRIE7kADl6H9M79shibus60ljQrYLbNvWhwe2nhp4dH9BoUWSikCzeUlzgD5HBFw+aLj+WWGJOhymroUZcXxEtaktAStSqi97LJkUcmxn3zvfz7hx9BIqEGWZb0vC+RXeAC+s9XuZLbeUeF4dEQZ0+wJBN1DNThmbgCAq/NyooHjsAYRHjuS7sSl+R86QlnNFe+tc7x8kf8x5aYv/uP5wNDV3CTk4zWw9xskcPJVo1oKq6oxCU7Z6XxfXEGyt889j8rYhHSSNSDSHew82kWIEH43XecfSl4kcH2sFpP9VspqvEoLo2/imRhGmFt+DSrbk/yEZSoYe78T++0BhVEv52k9LYZOZhD1z40mvDiAXDhEkybWjWf3a0NMxK36pxJYw4NsJMnA1Bbl8+uDZrVtal7H8OYhVDnAI2wBG9NfLEzo13rkQCt5c59r1XoF0L+e5Bs3Kmo3Ei3E033UQxl7pW/eXuO1R92dr0+WYTpnhvn0P0RPpLUwk9s9XDlG8zngGpw6azdB/8CeiSQmM3UtzOecGnPHXyonycG+lz5nQJyxzd2ALN4MrnIKnCs/q2UmOXaGNpz1Wf/4ZuPKp2vT8W/ikwUdZ6VGncg3EzcPiiKOaOLt3WHFn0osV+EhwrDLI77a4iTjO5u7qIJ5iV37GrInlF1Zl5MBIjdOnDCdrKzUEsfvqM1NeNVMAPqzZOC94mQdD3hfNI/yHuQKQ301/EYc04xoEous5CnaM4AiMwvlM05LJARccurkrfAhY7F0BsK/qOE0A339yq+Gutsw7MPwhadkDJPZvyE81YCaGenZLSe5umNIHJ/SwmXeyFljSGuXWyzjMoqxwmwSV3+VGkHNksBnhubb/+9TIzWdF2fcIhQu8srOnpLKMgB5SC+Nyq5xlmM/vfYuTJuYKlZKDMe16AVl t+ViCCrR tGBEY425dksf3jr02zf7sNTAQDeEgX3r54UTlk1f/R36qCdjqwB5Sq+VhFqesj1591hfJRr1/9fGFXZqRA7655RkMZupM/S9znUCvCYwi8XNKQfsg+ABYtJhOGU5biULyecm0eDqVSIcW15JN8tjcUuacS7DdGRp4rda5 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This adds the general_profit KSM sysfs knob and the process profit metric and process merge type knobs to ksm_stat. 1) split off pages_volatile function This splits off the pages_volatile function. The next patch will use this function. 2) 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. 3) document general_profit sysfs knob 4) 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. 5) add ksm_merge_type() function This adds the ksm_merge_type function. The function returns the merge type for the process. For madvise it returns "madvise", for prctl it returns "process" and otherwise it returns "none". 6) mm: expose ksm process profit metric and merge type in ksm_stat This exposes the ksm process profit metric in /proc//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. This exposes the ksm process type in /proc//ksm_stat. The name of the value is ksm_merge_type. 7) document new procfs ksm knobs Signed-off-by: Stefan Roesch Reviewed-by: Bagas Sanjaya --- Documentation/ABI/testing/sysfs-kernel-mm-ksm | 8 ++++ Documentation/admin-guide/mm/ksm.rst | 8 +++- fs/proc/base.c | 5 ++ include/linux/ksm.h | 5 ++ mm/ksm.c | 47 +++++++++++++++++-- 5 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-ksm b/Documentation/ABI/testing/sysfs-kernel-mm-ksm index d244674a9480..7768e90f7a8f 100644 --- a/Documentation/ABI/testing/sysfs-kernel-mm-ksm +++ b/Documentation/ABI/testing/sysfs-kernel-mm-ksm @@ -51,3 +51,11 @@ Description: Control merging pages across different NUMA nodes. When it is set to 0 only pages from the same node are merged, otherwise pages from all nodes can be merged together (default). + +What: /sys/kernel/mm/ksm/general_profit +Date: January 2023 +KernelVersion: 6.1 +Contact: Linux memory management mailing list +Description: Measure how effective KSM is. + general_profit: how effective is KSM. The formula for the + calculation is in Documentation/admin-guide/mm/ksm.rst. diff --git a/Documentation/admin-guide/mm/ksm.rst b/Documentation/admin-guide/mm/ksm.rst index f160f9487a90..34f1d0396eee 100644 --- a/Documentation/admin-guide/mm/ksm.rst +++ b/Documentation/admin-guide/mm/ksm.rst @@ -159,6 +159,8 @@ stable_node_chains_prune_millisecs The effectiveness of KSM and MADV_MERGEABLE is shown in ``/sys/kernel/mm/ksm/``: +general_profit + how effective is KSM. The calculation is explained below. pages_shared how many shared pages are being used pages_sharing @@ -216,7 +218,8 @@ several times, which are unprofitable memory consumed. ksm_rmap_items * sizeof(rmap_item). where ksm_merging_pages is shown under the directory ``/proc//``, - and ksm_rmap_items is shown in ``/proc//ksm_stat``. + and ksm_rmap_items is shown in ``/proc//ksm_stat``. The process profit + is also shown in ``/proc//ksm_stat`` as ksm_process_profit. From the perspective of application, a high ratio of ``ksm_rmap_items`` to ``ksm_merging_pages`` means a bad madvise-applied policy, so developers or @@ -227,6 +230,9 @@ so if the ``ksm_rmap_items/ksm_merging_pages`` ratio exceeds 64 on 64-bit CPU or exceeds 128 on 32-bit CPU, then the app's madvise policy should be dropped, because the ksm profit is approximately zero or negative. +The ksm_merge_type in ``/proc//ksm_stat`` shows the merge type of the +process. Valid values are ``none``, ``madvise`` and ``process``. + Monitoring KSM events ===================== diff --git a/fs/proc/base.c b/fs/proc/base.c index ac9ebe972be0..45749051e53b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -96,6 +96,7 @@ #include #include #include +#include #include #include "internal.h" #include "fd.h" @@ -3199,6 +3200,7 @@ static int proc_pid_ksm_merging_pages(struct seq_file *m, struct pid_namespace * return 0; } + static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task) { @@ -3208,6 +3210,9 @@ 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, "zero_pages_sharing %lu\n", mm->ksm_zero_pages_sharing); + seq_printf(m, "ksm_merging_pages %lu\n", mm->ksm_merging_pages); + seq_printf(m, "ksm_merge_type %s\n", ksm_merge_type(mm)); + seq_printf(m, "ksm_process_profit %ld\n", ksm_process_profit(mm)); mmput(mm); } diff --git a/include/linux/ksm.h b/include/linux/ksm.h index d38a05a36298..d5f69f18ee5a 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h @@ -55,6 +55,11 @@ struct page *ksm_might_need_to_copy(struct page *page, void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc); void folio_migrate_ksm(struct folio *newfolio, struct folio *folio); +#ifdef CONFIG_PROC_FS +long ksm_process_profit(struct mm_struct *); +const char *ksm_merge_type(struct mm_struct *mm); +#endif /* CONFIG_PROC_FS */ + #else /* !CONFIG_KSM */ static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) diff --git a/mm/ksm.c b/mm/ksm.c index 23d6944f78ad..3121bc0f48f3 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -3024,6 +3024,25 @@ static void wait_while_offlining(void) } #endif /* CONFIG_MEMORY_HOTREMOVE */ +#ifdef CONFIG_PROC_FS +long ksm_process_profit(struct mm_struct *mm) +{ + return (long)mm->ksm_merging_pages * PAGE_SIZE - + mm->ksm_rmap_items * sizeof(struct ksm_rmap_item); +} + +/* Return merge type name as string. */ +const char *ksm_merge_type(struct mm_struct *mm) +{ + if (test_bit(MMF_VM_MERGE_ANY, &mm->flags)) + return "process"; + else if (test_bit(MMF_VM_MERGEABLE, &mm->flags)) + return "madvise"; + else + return "none"; +} +#endif /* CONFIG_PROC_FS */ + #ifdef CONFIG_SYSFS /* * This all compiles without CONFIG_SYSFS, but is a waste of space. @@ -3271,8 +3290,7 @@ static ssize_t pages_unshared_show(struct kobject *kobj, } KSM_ATTR_RO(pages_unshared); -static ssize_t pages_volatile_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) +static long pages_volatile(void) { long ksm_pages_volatile; @@ -3284,7 +3302,14 @@ static ssize_t pages_volatile_show(struct kobject *kobj, */ if (ksm_pages_volatile < 0) ksm_pages_volatile = 0; - return sysfs_emit(buf, "%ld\n", ksm_pages_volatile); + + return ksm_pages_volatile; +} + +static ssize_t pages_volatile_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%ld\n", pages_volatile()); } KSM_ATTR_RO(pages_volatile); @@ -3295,6 +3320,21 @@ static ssize_t zero_pages_sharing_show(struct kobject *kobj, } KSM_ATTR_RO(zero_pages_sharing); +static ssize_t general_profit_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + long general_profit; + long all_rmap_items; + + all_rmap_items = ksm_max_page_sharing + ksm_pages_shared + + ksm_pages_unshared + pages_volatile(); + general_profit = ksm_pages_sharing * PAGE_SIZE - + all_rmap_items * sizeof(struct ksm_rmap_item); + + return sysfs_emit(buf, "%ld\n", general_profit); +} +KSM_ATTR_RO(general_profit); + static ssize_t stable_node_dups_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -3360,6 +3400,7 @@ static struct attribute *ksm_attrs[] = { &stable_node_dups_attr.attr, &stable_node_chains_prune_millisecs_attr.attr, &use_zero_pages_attr.attr, + &general_profit_attr.attr, NULL, };