[PATCH] landlock: Use kmem for object, rule, and hierarchy structures

Ayush Tiwari ayushtiw0110 at gmail.com
Mon Apr 1 20:15:33 UTC 2024


Use kmem_cache to replace kzalloc() calls with kmem_cache_zalloc() for
structs landlock_object, landlock_rule and landlock_hierarchy and
update the related dependencies to improve memory allocation and
deallocation performance. This patch does not change kfree() and
kfree_rcu() calls because according to kernel commit
ae65a5211d90("mm/slab: document kfree() as allowed for
kmem_cache_alloc() objects"), starting from kernel 6.4, kfree() is
safe to use for such objects. Use clang-format to format the code
to the kernel style. /proc/slabinfo shows decrease in
'ext4_inode_cache' and 'dentry' usage suggesting a significant
reduction in file system related object and memory allocations and
increase in kmem_cache and kmalloc usage also indicates more cache
allocation for objects for efficient memory handling.

Signed-off-by: Ayush Tiwari <ayushtiw0110 at gmail.com>
---
 security/landlock/object.c  | 12 +++++++++++-
 security/landlock/object.h  |  2 ++
 security/landlock/ruleset.c | 18 +++++++++++++++---
 security/landlock/ruleset.h |  2 ++
 security/landlock/setup.c   |  4 ++++
 5 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/security/landlock/object.c b/security/landlock/object.c
index 1f50612f0185..cfc367725624 100644
--- a/security/landlock/object.c
+++ b/security/landlock/object.c
@@ -17,6 +17,15 @@
 
 #include "object.h"
 
+static struct kmem_cache *landlock_object_cache;
+
+void __init landlock_object_cache_init(void)
+{
+	landlock_object_cache = kmem_cache_create(
+		"landlock_object_cache", sizeof(struct landlock_object), 0,
+		SLAB_PANIC, NULL);
+}
+
 struct landlock_object *
 landlock_create_object(const struct landlock_object_underops *const underops,
 		       void *const underobj)
@@ -25,7 +34,8 @@ landlock_create_object(const struct landlock_object_underops *const underops,
 
 	if (WARN_ON_ONCE(!underops || !underobj))
 		return ERR_PTR(-ENOENT);
-	new_object = kzalloc(sizeof(*new_object), GFP_KERNEL_ACCOUNT);
+	new_object =
+		kmem_cache_zalloc(landlock_object_cache, GFP_KERNEL_ACCOUNT);
 	if (!new_object)
 		return ERR_PTR(-ENOMEM);
 	refcount_set(&new_object->usage, 1);
diff --git a/security/landlock/object.h b/security/landlock/object.h
index 5f28c35e8aa8..d9967ef16ec1 100644
--- a/security/landlock/object.h
+++ b/security/landlock/object.h
@@ -15,6 +15,8 @@
 
 struct landlock_object;
 
+void __init landlock_object_cache_init(void);
+
 /**
  * struct landlock_object_underops - Operations on an underlying object
  */
diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c
index e0a5fbf9201a..0f8a9994f5fa 100644
--- a/security/landlock/ruleset.c
+++ b/security/landlock/ruleset.c
@@ -24,6 +24,19 @@
 #include "object.h"
 #include "ruleset.h"
 
+static struct kmem_cache *landlock_hierarchy_cache;
+static struct kmem_cache *landlock_rule_cache;
+
+void __init landlock_ruleset_cache_init(void)
+{
+	landlock_hierarchy_cache = kmem_cache_create(
+		"landlock_hierarchy_cache", sizeof(struct landlock_hierarchy),
+		0, SLAB_PANIC, NULL);
+	landlock_rule_cache = kmem_cache_create("landlock_rule_cache",
+						sizeof(struct landlock_rule), 0,
+						SLAB_PANIC, NULL);
+}
+
 static struct landlock_ruleset *create_ruleset(const u32 num_layers)
 {
 	struct landlock_ruleset *new_ruleset;
@@ -112,8 +125,7 @@ create_rule(const struct landlock_id id,
 	} else {
 		new_num_layers = num_layers;
 	}
-	new_rule = kzalloc(struct_size(new_rule, layers, new_num_layers),
-			   GFP_KERNEL_ACCOUNT);
+	new_rule = kmem_cache_zalloc(landlock_rule_cache, GFP_KERNEL_ACCOUNT);
 	if (!new_rule)
 		return ERR_PTR(-ENOMEM);
 	RB_CLEAR_NODE(&new_rule->node);
@@ -559,7 +571,7 @@ landlock_merge_ruleset(struct landlock_ruleset *const parent,
 	if (IS_ERR(new_dom))
 		return new_dom;
 	new_dom->hierarchy =
-		kzalloc(sizeof(*new_dom->hierarchy), GFP_KERNEL_ACCOUNT);
+		kmem_cache_zalloc(landlock_hierarchy_cache, GFP_KERNEL_ACCOUNT);
 	if (!new_dom->hierarchy) {
 		err = -ENOMEM;
 		goto out_put_dom;
diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h
index c7f1526784fd..f738e8b0cf9b 100644
--- a/security/landlock/ruleset.h
+++ b/security/landlock/ruleset.h
@@ -30,6 +30,8 @@
 	LANDLOCK_ACCESS_FS_REFER)
 /* clang-format on */
 
+void __init landlock_ruleset_cache_init(void);
+
 typedef u16 access_mask_t;
 /* Makes sure all filesystem access rights can be stored. */
 static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS);
diff --git a/security/landlock/setup.c b/security/landlock/setup.c
index f6dd33143b7f..a4904d00cbe6 100644
--- a/security/landlock/setup.c
+++ b/security/landlock/setup.c
@@ -16,6 +16,8 @@
 #include "net.h"
 #include "ptrace.h"
 #include "setup.h"
+#include "object.h"
+#include "ruleset.h"
 
 bool landlock_initialized __ro_after_init = false;
 
@@ -33,6 +35,8 @@ const struct lsm_id landlock_lsmid = {
 
 static int __init landlock_init(void)
 {
+	landlock_object_cache_init();
+	landlock_ruleset_cache_init();
 	landlock_add_cred_hooks();
 	landlock_add_ptrace_hooks();
 	landlock_add_fs_hooks();
-- 
2.40.1




More information about the Linux-security-module-archive mailing list