lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250321173729.3175898-4-souravpanda@google.com>
Date: Fri, 21 Mar 2025 17:37:26 +0000
From: Sourav Panda <souravpanda@...gle.com>
To: mathieu.desnoyers@...icios.com, willy@...radead.org, david@...hat.com, 
	pasha.tatashin@...een.com, rientjes@...gle.com, akpm@...ux-foundation.org, 
	linux-mm@...ck.org, linux-kernel@...r.kernel.org, weixugc@...gle.com, 
	gthelen@...gle.com, souravpanda@...gle.com, surenb@...gle.com
Subject: [RFC PATCH 3/6] mm: make Selective KSM partitioned

Create a sysfs interface to partition the KSM merge space. We add a
new sysfs file, namely add_partition. Which is used to specify the
name of the new partition. Once a partition is created, we would get the
traditional files typcally available in KSM under each partition.

This sysfs interface changes are in preparation of the following patch
that shall actually partition the merge space (e.g., prevent
page-comparison and merging across partitions).

KSM_SYSFS=/sys/kernel/mm/ksm

echo "part_1" >  ${KSM_SYSFS}/ksm/control/add_partition

ls ${KSM_SYSFS}/part_1/
	pages_scanned       pages_to_scan   sleep_millisecs  ...

echo "pid start_addr end_addr" > ${KSM_SYSFS}/part_1/trigger_merge

Signed-off-by: Sourav Panda <souravpanda@...gle.com>
---
 mm/ksm.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 95 insertions(+), 6 deletions(-)

diff --git a/mm/ksm.c b/mm/ksm.c
index b2f184557ed9..927e257c48b5 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -3832,7 +3832,17 @@ static ssize_t full_scans_show(struct kobject *kobj,
 }
 KSM_ATTR_RO(full_scans);
 
-#ifndef CONFIG_SELECTIVE_KSM
+#ifdef CONFIG_SELECTIVE_KSM
+static struct kobject *ksm_base_kobj;
+
+struct partition_kobj {
+	struct kobject *kobj;
+	struct list_head list;
+};
+
+static LIST_HEAD(partition_list);
+
+#else /* CONFIG_SELECTIVE_KSM */
 static ssize_t smart_scan_show(struct kobject *kobj,
 			       struct kobj_attribute *attr, char *buf)
 {
@@ -4015,15 +4025,22 @@ static struct attribute *ksm_attrs[] = {
 
 static const struct attribute_group ksm_attr_group = {
 	.attrs = ksm_attrs,
+#ifndef CONFIG_SELECTIVE_KSM
 	.name = "ksm",
+#endif
 };
 
-static int __init ksm_sysfs_init(void)
+static int __init ksm_sysfs_init(struct kobject *kobj,
+				 const struct attribute_group *grp)
 {
-	return sysfs_create_group(mm_kobj, &ksm_attr_group);
+	int err;
+
+	err = sysfs_create_group(kobj, grp);
+	return err;
 }
 #else /* CONFIG_SYSFS */
-static int __init ksm_sysfs_init(void)
+static int __init ksm_sysfs_init(struct kobject *kobj,
+				 const struct attribute_group *grp)
 {
 	ksm_run = KSM_RUN_MERGE;	/* no way for user to start it */
 	return 0;
@@ -4031,9 +4048,81 @@ static int __init ksm_sysfs_init(void)
 #endif /* CONFIG_SYSFS */
 
 #ifdef CONFIG_SELECTIVE_KSM
+static ssize_t add_partition_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t count)
+{
+	struct partition_kobj *new_partition_kobj;
+	char partition_name[50];
+	int err;
+
+	mutex_lock(&ksm_thread_mutex);
+
+	if (count >= sizeof(partition_name)) {
+		err = -EINVAL;  /* Prevent buffer overflow */
+		goto unlock;
+	}
+
+	snprintf(partition_name, sizeof(partition_name),
+		 "%.*s", (int)(count - 1), buf); /* Remove newline */
+
+	/* Allocate memory for new dynamic kobject entry */
+	new_partition_kobj = kmalloc(sizeof(*new_partition_kobj), GFP_KERNEL);
+	if (!new_partition_kobj) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	new_partition_kobj->kobj = kobject_create_and_add(partition_name,
+							  ksm_base_kobj);
+	if (!new_partition_kobj) {
+		kfree(new_partition_kobj);
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	err = sysfs_create_group(new_partition_kobj->kobj, &ksm_attr_group);
+	if (err) {
+		pr_err("ksm: register sysfs failed\n");
+		kfree(new_partition_kobj);
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	list_add(&new_partition_kobj->list, &partition_list);
+
+unlock:
+	mutex_unlock(&ksm_thread_mutex);
+	return err ? err : count;
+}
+
+static struct kobj_attribute add_kobj_attr = __ATTR(add_partition, 0220, NULL,
+						    add_partition_store);
+
+/* Array of attributes for base kobject */
+static struct attribute *ksm_base_attrs[] = {
+	&add_kobj_attr.attr,
+	NULL,  /* NULL-terminated */
+};
+
+/* Attribute group for base kobject */
+static struct attribute_group ksm_base_attr_group = {
+	.name = "control",
+	.attrs = ksm_base_attrs,
+};
+
 static int __init ksm_thread_sysfs_init(void)
 {
-	return ksm_sysfs_init();
+	int err;
+
+	ksm_base_kobj = kobject_create_and_add("ksm", mm_kobj);
+	if (!ksm_base_kobj) {
+		err = -ENOMEM;
+		return err;
+	}
+
+	err = ksm_sysfs_init(ksm_base_kobj, &ksm_base_attr_group);
+	return err;
 }
 #else /* CONFIG_SELECTIVE_KSM */
 static int __init ksm_thread_sysfs_init(void)
@@ -4048,7 +4137,7 @@ static int __init ksm_thread_sysfs_init(void)
 		return err;
 	}
 
-	err = ksm_sysfs_init();
+	err = ksm_sysfs_init(mm_kobj, &ksm_attr_group);
 	if (err) {
 		pr_err("ksm: register sysfs failed\n");
 		kthread_stop(ksm_thread);
-- 
2.49.0.395.g12beb8f557-goog


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ