@@ -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);
@@ -15,6 +15,8 @@
struct landlock_object;
+void __init landlock_object_cache_init(void);
+
/**
* struct landlock_object_underops - Operations on an underlying object
*/
@@ -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;
@@ -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);
@@ -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();
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@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(-)