eventfs: Implement tracefs_inode_cache
authorAjay Kaher <akaher@vmware.com>
Fri, 28 Jul 2023 18:20:44 +0000 (23:50 +0530)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Sun, 30 Jul 2023 22:13:33 +0000 (18:13 -0400)
Create a kmem cache of tracefs_inodes. To be more efficient, as there are
lots of tracefs inodes, create its own cache. This also allows to see how
many tracefs inodes have been created.

Add helper functions:
tracefs_alloc_inode()
tracefs_free_inode()
get_tracefs()

Link: https://lkml.kernel.org/r/1690568452-46553-3-git-send-email-akaher@vmware.com
Signed-off-by: Ajay Kaher <akaher@vmware.com>
Co-developed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Tested-by: Ching-lin Yu <chinglinyu@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
fs/tracefs/inode.c
fs/tracefs/internal.h [new file with mode: 0644]

index 57ac8aa..2508944 100644 (file)
 #include <linux/parser.h>
 #include <linux/magic.h>
 #include <linux/slab.h>
+#include "internal.h"
 
 #define TRACEFS_DEFAULT_MODE   0700
+static struct kmem_cache *tracefs_inode_cachep __ro_after_init;
 
 static struct vfsmount *tracefs_mount;
 static int tracefs_mount_count;
 static bool tracefs_registered;
 
+static struct inode *tracefs_alloc_inode(struct super_block *sb)
+{
+       struct tracefs_inode *ti;
+
+       ti = kmem_cache_alloc(tracefs_inode_cachep, GFP_KERNEL);
+       if (!ti)
+               return NULL;
+
+       ti->flags = 0;
+
+       return &ti->vfs_inode;
+}
+
+static void tracefs_free_inode(struct inode *inode)
+{
+       kmem_cache_free(tracefs_inode_cachep, get_tracefs(inode));
+}
+
 static ssize_t default_read_file(struct file *file, char __user *buf,
                                 size_t count, loff_t *ppos)
 {
@@ -346,6 +366,9 @@ static int tracefs_show_options(struct seq_file *m, struct dentry *root)
 }
 
 static const struct super_operations tracefs_super_operations = {
+       .alloc_inode    = tracefs_alloc_inode,
+       .free_inode     = tracefs_free_inode,
+       .drop_inode     = generic_delete_inode,
        .statfs         = simple_statfs,
        .remount_fs     = tracefs_remount,
        .show_options   = tracefs_show_options,
@@ -628,10 +651,26 @@ bool tracefs_initialized(void)
        return tracefs_registered;
 }
 
+static void init_once(void *foo)
+{
+       struct tracefs_inode *ti = (struct tracefs_inode *) foo;
+
+       inode_init_once(&ti->vfs_inode);
+}
+
 static int __init tracefs_init(void)
 {
        int retval;
 
+       tracefs_inode_cachep = kmem_cache_create("tracefs_inode_cache",
+                                                sizeof(struct tracefs_inode),
+                                                0, (SLAB_RECLAIM_ACCOUNT|
+                                                    SLAB_MEM_SPREAD|
+                                                    SLAB_ACCOUNT),
+                                                init_once);
+       if (!tracefs_inode_cachep)
+               return -ENOMEM;
+
        retval = sysfs_create_mount_point(kernel_kobj, "tracing");
        if (retval)
                return -EINVAL;
diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
new file mode 100644 (file)
index 0000000..954ea00
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _TRACEFS_INTERNAL_H
+#define _TRACEFS_INTERNAL_H
+
+struct tracefs_inode {
+       unsigned long           flags;
+       void                    *private;
+       struct inode            vfs_inode;
+};
+
+static inline struct tracefs_inode *get_tracefs(const struct inode *inode)
+{
+       return container_of(inode, struct tracefs_inode, vfs_inode);
+}
+#endif /* _TRACEFS_INTERNAL_H */