2023-05-02 11:26:36

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 0/9] tracing: introducing eventfs

Events Tracing infrastructure contains lot of files, directories
(internally in terms of inodes, dentries). And ends up by consuming
memory in MBs. We can have multiple events of Events Tracing, which
further requires more memory.

Instead of creating inodes/dentries, eventfs could keep meta-data and
skip the creation of inodes/dentries. As and when require, eventfs will
create the inodes/dentries only for required files/directories.
Also eventfs would delete the inodes/dentries once no more requires
but preserve the meta data.

Tracing events took ~9MB, with this approach it took ~4.5MB
for ~10K files/dir.

Diff from v1:
Patch 1: add header file
Patch 2: resolved kernel test robot issues
protecting eventfs lists using nested eventfs_rwsem
Patch 3: protecting eventfs lists using nested eventfs_rwsem
Patch 4: improve events cleanup code to fix crashes
Patch 5: resolved kernel test robot issues
removed d_instantiate_anon() calls
Patch 6: resolved kernel test robot issues
fix kprobe test in eventfs_root_lookup()
protecting eventfs lists using nested eventfs_rwsem
Patch 7: remove header file
Patch 8: pass eventfs_rwsem as argument to eventfs functions
called eventfs_remove_events_dir() instead of tracefs_remove()
from event_trace_del_tracer()
Patch 9: new patch to fix kprobe test case

fs/tracefs/Makefile | 1 +
fs/tracefs/event_inode.c | 761 ++++++++++++++++++
fs/tracefs/inode.c | 124 ++-
fs/tracefs/internal.h | 25 +
include/linux/trace_events.h | 1 +
include/linux/tracefs.h | 49 ++
kernel/trace/trace.h | 3 +-
kernel/trace/trace_events.c | 66 +-
.../ftrace/test.d/kprobe/kprobe_args_char.tc | 4 +-
.../test.d/kprobe/kprobe_args_string.tc | 4 +-
10 files changed, 992 insertions(+), 46 deletions(-)
create mode 100644 fs/tracefs/event_inode.c
create mode 100644 fs/tracefs/internal.h

--
2.39.0


2023-05-02 11:26:39

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 1/9] eventfs: introducing struct tracefs_inode

Introducing tracefs_inode structure, this will help eventfs
to keep track of inode, flags and pointer to private date.

Renaming, removing static property from some function name.

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/inode.c | 21 +++++++++++----------
fs/tracefs/internal.h | 25 +++++++++++++++++++++++++
2 files changed, 36 insertions(+), 10 deletions(-)
create mode 100644 fs/tracefs/internal.h

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 57ac8aa4a..7df1752e8 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -21,6 +21,7 @@
#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/slab.h>
+#include "internal.h"

#define TRACEFS_DEFAULT_MODE 0700

@@ -127,7 +128,7 @@ static const struct inode_operations tracefs_dir_inode_operations = {
.rmdir = tracefs_syscall_rmdir,
};

-static struct inode *tracefs_get_inode(struct super_block *sb)
+struct inode *tracefs_get_inode(struct super_block *sb)
{
struct inode *inode = new_inode(sb);
if (inode) {
@@ -399,7 +400,7 @@ static struct file_system_type trace_fs_type = {
};
MODULE_ALIAS_FS("tracefs");

-static struct dentry *start_creating(const char *name, struct dentry *parent)
+struct dentry *tracefs_start_creating(const char *name, struct dentry *parent)
{
struct dentry *dentry;
int error;
@@ -437,7 +438,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
return dentry;
}

-static struct dentry *failed_creating(struct dentry *dentry)
+struct dentry *tracefs_failed_creating(struct dentry *dentry)
{
inode_unlock(d_inode(dentry->d_parent));
dput(dentry);
@@ -445,7 +446,7 @@ static struct dentry *failed_creating(struct dentry *dentry)
return NULL;
}

-static struct dentry *end_creating(struct dentry *dentry)
+struct dentry *tracefs_end_creating(struct dentry *dentry)
{
inode_unlock(d_inode(dentry->d_parent));
return dentry;
@@ -490,14 +491,14 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
if (!(mode & S_IFMT))
mode |= S_IFREG;
BUG_ON(!S_ISREG(mode));
- dentry = start_creating(name, parent);
+ dentry = tracefs_start_creating(name, parent);

if (IS_ERR(dentry))
return NULL;

inode = tracefs_get_inode(dentry->d_sb);
if (unlikely(!inode))
- return failed_creating(dentry);
+ return tracefs_failed_creating(dentry);

inode->i_mode = mode;
inode->i_fop = fops ? fops : &tracefs_file_operations;
@@ -506,13 +507,13 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
inode->i_gid = d_inode(dentry->d_parent)->i_gid;
d_instantiate(dentry, inode);
fsnotify_create(d_inode(dentry->d_parent), dentry);
- return end_creating(dentry);
+ return tracefs_end_creating(dentry);
}

static struct dentry *__create_dir(const char *name, struct dentry *parent,
const struct inode_operations *ops)
{
- struct dentry *dentry = start_creating(name, parent);
+ struct dentry *dentry = tracefs_start_creating(name, parent);
struct inode *inode;

if (IS_ERR(dentry))
@@ -520,7 +521,7 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent,

inode = tracefs_get_inode(dentry->d_sb);
if (unlikely(!inode))
- return failed_creating(dentry);
+ return tracefs_failed_creating(dentry);

/* Do not set bits for OTH */
inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP;
@@ -534,7 +535,7 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent,
d_instantiate(dentry, inode);
inc_nlink(d_inode(dentry->d_parent));
fsnotify_mkdir(d_inode(dentry->d_parent), dentry);
- return end_creating(dentry);
+ return tracefs_end_creating(dentry);
}

/**
diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
new file mode 100644
index 000000000..6776b4693
--- /dev/null
+++ b/fs/tracefs/internal.h
@@ -0,0 +1,25 @@
+#ifndef _TRACEFS_INTERNAL_H
+#define _TRACEFS_INTERNAL_H
+
+enum {
+ TRACEFS_EVENT_INODE = BIT(1),
+};
+
+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);
+}
+
+struct dentry *tracefs_start_creating(const char *name, struct dentry *parent);
+struct dentry *tracefs_end_creating(struct dentry *dentry);
+struct dentry *tracefs_failed_creating(struct dentry *dentry);
+struct inode *tracefs_get_inode(struct super_block *sb);
+
+#endif /* _TRACEFS_INTERNAL_H */
+
--
2.39.0

2023-05-02 11:26:40

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 2/9] eventfs: adding eventfs dir add functions

Adding eventfs_file structure which will hold properties of file or dir.

Adding following functions to add dir in eventfs:

eventfs_create_events_dir() will directly create events dir with-in
tracing folder.

eventfs_add_subsystem_dir() will adds the info of subsystem_dir to
eventfs and dynamically create subsystem_dir as and when requires.

eventfs_add_dir() will add the info of dir (which is with-in
subsystem_dir) to eventfs and dynamically create these dir as
and when requires.

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/Makefile | 1 +
fs/tracefs/event_inode.c | 252 +++++++++++++++++++++++++++++++++++++++
include/linux/tracefs.h | 29 +++++
kernel/trace/trace.h | 1 +
4 files changed, 283 insertions(+)
create mode 100644 fs/tracefs/event_inode.c

diff --git a/fs/tracefs/Makefile b/fs/tracefs/Makefile
index 7c35a282b..73c56da8e 100644
--- a/fs/tracefs/Makefile
+++ b/fs/tracefs/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
tracefs-objs := inode.o
+tracefs-objs += event_inode.o

obj-$(CONFIG_TRACING) += tracefs.o

diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
new file mode 100644
index 000000000..82caba7e9
--- /dev/null
+++ b/fs/tracefs/event_inode.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * event_inode.c - part of tracefs, a pseudo file system for activating tracing
+ *
+ * Copyright (C) 2020-22 VMware Inc, author: Steven Rostedt (VMware) <[email protected]>
+ * Copyright (C) 2020-22 VMware Inc, author: Ajay Kaher <[email protected]>
+ *
+ * eventfs is used to show trace events with one set of dentries
+ *
+ * eventfs stores meta-data of files/dirs and skip to create object of
+ * inodes/dentries. As and when requires, eventfs will create the
+ * inodes/dentries for only required files/directories. Also eventfs
+ * would delete the inodes/dentries once no more requires but preserve
+ * the meta data.
+ */
+#include <linux/fsnotify.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include <linux/tracefs.h>
+#include <linux/kref.h>
+#include <linux/delay.h>
+#include "internal.h"
+
+/**
+ * eventfs_dentry_to_rwsem - Return corresponding eventfs_rwsem
+ * @dentry: a pointer to dentry
+ *
+ * helper function to return crossponding eventfs_rwsem for given dentry
+ */
+static struct rw_semaphore *eventfs_dentry_to_rwsem(struct dentry *dentry)
+{
+ if (S_ISDIR(dentry->d_inode->i_mode))
+ return (struct rw_semaphore *)dentry->d_inode->i_private;
+ else
+ return (struct rw_semaphore *)dentry->d_parent->d_inode->i_private;
+}
+
+/**
+ * eventfs_down_read - acquire read lock function
+ * @eventfs_rwsem: a pointer to rw_semaphore
+ *
+ * helper function to perform read lock, skip locking if caller task already
+ * own the lock. read lock requires for lookup(), release() and these also
+ * called with-in open(), remove() which already hold the read/write lock.
+ */
+static void eventfs_down_read(struct rw_semaphore *eventfs_rwsem)
+{
+ down_read_nested(eventfs_rwsem, SINGLE_DEPTH_NESTING);
+}
+
+/**
+ * eventfs_up_read - release read lock function
+ * @eventfs_rwsem: a pointer to rw_semaphore
+ *
+ * helper function to release eventfs_rwsem lock if locked
+ */
+static void eventfs_up_read(struct rw_semaphore *eventfs_rwsem)
+{
+ up_read(eventfs_rwsem);
+}
+
+/**
+ * eventfs_down_write - acquire write lock function
+ * @eventfs_rwsem: a pointer to rw_semaphore
+ *
+ * helper function to perform write lock on eventfs_rwsem
+ */
+static void eventfs_down_write(struct rw_semaphore *eventfs_rwsem)
+{
+ while (!down_write_trylock(eventfs_rwsem))
+ msleep(10);
+}
+
+/**
+ * eventfs_up_write - release write lock function
+ * @eventfs_rwsem: a pointer to rw_semaphore
+ *
+ * helper function to perform write lock on eventfs_rwsem
+ */
+static void eventfs_up_write(struct rw_semaphore *eventfs_rwsem)
+{
+ up_write(eventfs_rwsem);
+}
+
+static const struct file_operations eventfs_file_operations = {
+};
+
+static const struct inode_operations eventfs_root_dir_inode_operations = {
+};
+
+/**
+ * eventfs_create_events_dir - create the trace event structure
+ * @name: a pointer to a string containing the name of the directory to
+ * create.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is NULL, then the
+ * directory will be created in the root of the tracefs filesystem.
+ * @eventfs_rwsem: a pointer to rw_semaphore
+ *
+ * This function creates the top of the trace event directory.
+ */
+struct dentry *eventfs_create_events_dir(const char *name,
+ struct dentry *parent,
+ struct rw_semaphore *eventfs_rwsem)
+{
+ struct dentry *dentry = tracefs_start_creating(name, parent);
+ struct eventfs_inode *ei;
+ struct tracefs_inode *ti;
+ struct inode *inode;
+
+ if (IS_ERR(dentry))
+ return dentry;
+
+ ei = kzalloc(sizeof(*ei), GFP_KERNEL);
+ if (!ei)
+ return ERR_PTR(-ENOMEM);
+ inode = tracefs_get_inode(dentry->d_sb);
+ if (unlikely(!inode)) {
+ kfree(ei);
+ tracefs_failed_creating(dentry);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init_rwsem(eventfs_rwsem);
+ INIT_LIST_HEAD(&ei->e_top_files);
+
+ ti = get_tracefs(inode);
+ ti->flags |= TRACEFS_EVENT_INODE;
+ ti->private = ei;
+
+ inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+ inode->i_op = &eventfs_root_dir_inode_operations;
+ inode->i_fop = &eventfs_file_operations;
+ inode->i_private = eventfs_rwsem;
+
+ /* directory inodes start off with i_nlink == 2 (for "." entry) */
+ inc_nlink(inode);
+ d_instantiate(dentry, inode);
+ inc_nlink(dentry->d_parent->d_inode);
+ fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
+ return tracefs_end_creating(dentry);
+}
+
+/**
+ * eventfs_add_subsystem_dir - add eventfs subsystem_dir to list to create later
+ * @name: a pointer to a string containing the name of the file to create.
+ * @parent: a pointer to the parent dentry for this dir.
+ * @eventfs_rwsem: a pointer to rw_semaphore
+ *
+ * This function adds eventfs subsystem dir to list.
+ * And all these dirs are created on the fly when they are looked up,
+ * and the dentry and inodes will be removed when they are done.
+ */
+struct eventfs_file *eventfs_add_subsystem_dir(const char *name,
+ struct dentry *parent,
+ struct rw_semaphore *eventfs_rwsem)
+{
+ struct tracefs_inode *ti_parent;
+ struct eventfs_inode *ei_parent;
+ struct eventfs_file *ef;
+
+ if (!parent)
+ return ERR_PTR(-EINVAL);
+
+ ti_parent = get_tracefs(parent->d_inode);
+ ei_parent = ti_parent->private;
+
+ ef = kzalloc(sizeof(*ef), GFP_KERNEL);
+ if (!ef)
+ return ERR_PTR(-ENOMEM);
+
+ ef->ei = kzalloc(sizeof(*ef->ei), GFP_KERNEL);
+ if (!ef->ei) {
+ kfree(ef);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ INIT_LIST_HEAD(&ef->ei->e_top_files);
+
+ ef->name = kstrdup(name, GFP_KERNEL);
+ if (!ef->name) {
+ kfree(ef->ei);
+ kfree(ef);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ef->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+ ef->iop = &eventfs_root_dir_inode_operations;
+ ef->fop = &eventfs_file_operations;
+ ef->dentry = NULL;
+ ef->created = false;
+ ef->d_parent = parent;
+ ef->data = eventfs_rwsem;
+
+ eventfs_down_write(eventfs_rwsem);
+ list_add_tail(&ef->list, &ei_parent->e_top_files);
+ eventfs_up_write(eventfs_rwsem);
+ return ef;
+}
+
+/**
+ * eventfs_add_dir - add eventfs dir to list to create later
+ * @name: a pointer to a string containing the name of the file to create.
+ * @ef_parent: a pointer to the parent eventfs_file for this dir.
+ * @eventfs_rwsem: a pointer to rw_semaphore
+ *
+ * This function adds eventfs dir to list.
+ * And all these dirs are created on the fly when they are looked up,
+ * and the dentry and inodes will be removed when they are done.
+ */
+struct eventfs_file *eventfs_add_dir(const char *name,
+ struct eventfs_file *ef_parent,
+ struct rw_semaphore *eventfs_rwsem)
+{
+ struct eventfs_file *ef;
+
+ if (!ef_parent)
+ return ERR_PTR(-EINVAL);
+
+ ef = kzalloc(sizeof(*ef), GFP_KERNEL);
+ if (!ef)
+ return ERR_PTR(-ENOMEM);
+
+ ef->ei = kzalloc(sizeof(*ef->ei), GFP_KERNEL);
+ if (!ef->ei) {
+ kfree(ef);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ INIT_LIST_HEAD(&ef->ei->e_top_files);
+
+ ef->name = kstrdup(name, GFP_KERNEL);
+ if (!ef->name) {
+ kfree(ef->ei);
+ kfree(ef);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ef->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+ ef->iop = &eventfs_root_dir_inode_operations;
+ ef->fop = &eventfs_file_operations;
+ ef->created = false;
+ ef->dentry = NULL;
+ ef->d_parent = NULL;
+ ef->data = eventfs_rwsem;
+
+ eventfs_down_write(eventfs_rwsem);
+ list_add_tail(&ef->list, &ef_parent->ei->e_top_files);
+ eventfs_up_write(eventfs_rwsem);
+ return ef;
+}
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 999124459..aeca6761f 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -21,6 +21,35 @@ struct file_operations;

#ifdef CONFIG_TRACING

+struct eventfs_inode {
+ struct list_head e_top_files;
+};
+
+struct eventfs_file {
+ const char *name;
+ struct dentry *d_parent;
+ struct dentry *dentry;
+ struct list_head list;
+ struct eventfs_inode *ei;
+ const struct file_operations *fop;
+ const struct inode_operations *iop;
+ void *data;
+ umode_t mode;
+ bool created;
+};
+
+struct dentry *eventfs_create_events_dir(const char *name,
+ struct dentry *parent,
+ struct rw_semaphore *eventfs_rwsem);
+
+struct eventfs_file *eventfs_add_subsystem_dir(const char *name,
+ struct dentry *parent,
+ struct rw_semaphore *eventfs_rwsem);
+
+struct eventfs_file *eventfs_add_dir(const char *name,
+ struct eventfs_file *ef_parent,
+ struct rw_semaphore *eventfs_rwsem);
+
struct dentry *tracefs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 616e1aa1c..3726725c8 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -359,6 +359,7 @@ struct trace_array {
struct dentry *options;
struct dentry *percpu_dir;
struct dentry *event_dir;
+ struct rw_semaphore eventfs_rwsem;
struct trace_options *topts;
struct list_head systems;
struct list_head events;
--
2.39.0

2023-05-02 11:26:45

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 5/9] eventfs: adding functions to create eventfs files and directories

Adding eventfs_create_file(), eventfs_create_dir()
to create file, dir at runtime as and when requires.

These function will be called either from lookup
of inode_operations or open of file_operations.

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/event_inode.c | 125 +++++++++++++++++++++++++++++++++++++++
fs/tracefs/inode.c | 47 +++++++++++++++
include/linux/tracefs.h | 6 ++
3 files changed, 178 insertions(+)

diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 9ab675edf..0ee27f7c8 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -83,6 +83,131 @@ static void eventfs_up_write(struct rw_semaphore *eventfs_rwsem)
up_write(eventfs_rwsem);
}

+/**
+ * eventfs_create_file - create a file in the tracefs filesystem
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is NULL, then the
+ * file will be created in the root of the tracefs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.i_private pointer will point to this value on
+ * the open() call.
+ * @fop: a pointer to a struct file_operations that should be used for
+ * this file.
+ *
+ * This is the basic "create a file" function for tracefs. It allows for a
+ * wide range of flexibility in creating a file.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the tracefs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, %NULL will be returned.
+ *
+ * If tracefs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+static struct dentry *eventfs_create_file(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fop)
+{
+ struct tracefs_inode *ti;
+ struct dentry *dentry;
+ struct inode *inode;
+
+ if (security_locked_down(LOCKDOWN_TRACEFS))
+ return NULL;
+
+ if (!(mode & S_IFMT))
+ mode |= S_IFREG;
+
+ if (WARN_ON_ONCE(!S_ISREG(mode)))
+ return NULL;
+
+ dentry = eventfs_start_creating(name, parent);
+
+ if (IS_ERR(dentry))
+ return dentry;
+
+ inode = tracefs_get_inode(dentry->d_sb);
+ if (unlikely(!inode))
+ return eventfs_failed_creating(dentry);
+
+ inode->i_mode = mode;
+ inode->i_fop = fop;
+ inode->i_private = data;
+
+ ti = get_tracefs(inode);
+ ti->flags |= TRACEFS_EVENT_INODE;
+ d_instantiate(dentry, inode);
+ fsnotify_create(dentry->d_parent->d_inode, dentry);
+ return eventfs_end_creating(dentry);
+}
+
+/**
+ * eventfs_create_dir - create a dir in the tracefs filesystem
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is NULL, then the
+ * file will be created in the root of the tracefs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.i_private pointer will point to this value on
+ * the open() call.
+ * @fop: a pointer to a struct file_operations that should be used for
+ * this dir.
+ * @iop: a pointer to a struct inode_operations that should be used for
+ * this dir.
+ *
+ * This is the basic "create a dir" function for eventfs. It allows for a
+ * wide range of flexibility in creating a dir.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the tracefs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, %NULL will be returned.
+ *
+ * If tracefs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+static struct dentry *eventfs_create_dir(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fop,
+ const struct inode_operations *iop)
+{
+ struct tracefs_inode *ti;
+ struct dentry *dentry;
+ struct inode *inode;
+
+ if (security_locked_down(LOCKDOWN_TRACEFS))
+ return NULL;
+
+ WARN_ON(!S_ISDIR(mode));
+
+ dentry = eventfs_start_creating(name, parent);
+
+ if (IS_ERR(dentry))
+ return dentry;
+
+ inode = tracefs_get_inode(dentry->d_sb);
+ if (unlikely(!inode))
+ return eventfs_failed_creating(dentry);
+
+ inode->i_mode = mode;
+ inode->i_op = iop;
+ inode->i_fop = fop;
+ inode->i_private = data;
+
+ ti = get_tracefs(inode);
+ ti->flags |= TRACEFS_EVENT_INODE;
+
+ inc_nlink(inode);
+ d_instantiate(dentry, inode);
+ inc_nlink(dentry->d_parent->d_inode);
+ fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
+ return eventfs_end_creating(dentry);
+}
+
static const struct file_operations eventfs_file_operations = {
};

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 7df1752e8..66c4df734 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -452,6 +452,53 @@ struct dentry *tracefs_end_creating(struct dentry *dentry)
return dentry;
}

+struct dentry *eventfs_start_creating(const char *name, struct dentry *parent)
+{
+ struct dentry *dentry;
+ int error;
+
+ error = simple_pin_fs(&trace_fs_type, &tracefs_mount,
+ &tracefs_mount_count);
+ if (error)
+ return ERR_PTR(error);
+
+ /*
+ * If the parent is not specified, we create it in the root.
+ * We need the root dentry to do this, which is in the super
+ * block. A pointer to that is in the struct vfsmount that we
+ * have around.
+ */
+ if (!parent)
+ parent = tracefs_mount->mnt_root;
+
+ if (unlikely(IS_DEADDIR(parent->d_inode)))
+ dentry = ERR_PTR(-ENOENT);
+ else
+ dentry = lookup_one_len(name, parent, strlen(name));
+
+ if (!IS_ERR(dentry) && dentry->d_inode) {
+ dput(dentry);
+ dentry = ERR_PTR(-EEXIST);
+ }
+
+ if (IS_ERR(dentry))
+ simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+
+ return dentry;
+}
+
+struct dentry *eventfs_failed_creating(struct dentry *dentry)
+{
+ dput(dentry);
+ simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+ return NULL;
+}
+
+struct dentry *eventfs_end_creating(struct dentry *dentry)
+{
+ return dentry;
+}
+
/**
* tracefs_create_file - create a file in the tracefs filesystem
* @name: a pointer to a string containing the name of the file to create.
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index ea10ccc87..57bfd1322 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -38,6 +38,12 @@ struct eventfs_file {
bool created;
};

+struct dentry *eventfs_start_creating(const char *name, struct dentry *parent);
+
+struct dentry *eventfs_failed_creating(struct dentry *dentry);
+
+struct dentry *eventfs_end_creating(struct dentry *dentry);
+
struct dentry *eventfs_create_events_dir(const char *name,
struct dentry *parent,
struct rw_semaphore *eventfs_rwsem);
--
2.39.0

2023-05-02 11:26:45

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 3/9] eventfs: adding eventfs file add functions

Adding following function to eventfs to add files:

eventfs_add_top_file() will add the info of top file
to eventfs and dynamically create these files as and
when required.

eventfs_add_file() will add the info of nested files
to eventfs and dynamically create these dir as and
when required.

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/event_inode.c | 118 +++++++++++++++++++++++++++++++++++++++
include/linux/tracefs.h | 8 +++
2 files changed, 126 insertions(+)

diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 82caba7e9..93134ae40 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -250,3 +250,121 @@ struct eventfs_file *eventfs_add_dir(const char *name,
eventfs_up_write(eventfs_rwsem);
return ef;
}
+
+/**
+ * eventfs_add_top_file - add event top file to list to create later
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is NULL, then the
+ * file will be created in the root of the tracefs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.i_private pointer will point to this value on
+ * the open() call.
+ * @fop: a pointer to a struct file_operations that should be used for
+ * this file.
+ *
+ * This function adds top files of event dir to list.
+ * And all these files are created on the fly when they are looked up,
+ * and the dentry and inodes will be removed when they are done.
+ */
+int eventfs_add_top_file(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fop)
+{
+ struct tracefs_inode *ti;
+ struct eventfs_inode *ei;
+ struct eventfs_file *ef;
+ struct rw_semaphore *eventfs_rwsem;
+
+ if (!parent)
+ return -EINVAL;
+
+ if (!(mode & S_IFMT))
+ mode |= S_IFREG;
+
+ if (!parent->d_inode)
+ return -EINVAL;
+
+ ti = get_tracefs(parent->d_inode);
+ if (!(ti->flags & TRACEFS_EVENT_INODE))
+ return -EINVAL;
+
+ ei = ti->private;
+ ef = kzalloc(sizeof(*ef), GFP_KERNEL);
+ if (!ef)
+ return -ENOMEM;
+
+ ef->name = kstrdup(name, GFP_KERNEL);
+ if (!ef->name) {
+ kfree(ef);
+ return -ENOMEM;
+ }
+
+ ef->mode = mode;
+ ef->data = data;
+ ef->fop = fop;
+ ef->dentry = NULL;
+ ef->ei = NULL;
+ ef->created = false;
+ ef->d_parent = parent;
+
+ eventfs_rwsem = (struct rw_semaphore *) parent->d_inode->i_private;
+ eventfs_down_write(eventfs_rwsem);
+ list_add_tail(&ef->list, &ei->e_top_files);
+ eventfs_up_write(eventfs_rwsem);
+ return 0;
+}
+
+/**
+ * eventfs_add_file - add eventfs file to list to create later
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have.
+ * @ef_parent: a pointer to the parent eventfs_file for this file.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.i_private pointer will point to this value on
+ * the open() call.
+ * @fop: a pointer to a struct file_operations that should be used for
+ * this file.
+ *
+ * This function adds top files of event dir to list.
+ * And all these files are created on the fly when they are looked up,
+ * and the dentry and inodes will be removed when they are done.
+ */
+int eventfs_add_file(const char *name, umode_t mode,
+ struct eventfs_file *ef_parent,
+ void *data,
+ const struct file_operations *fop)
+{
+ struct eventfs_file *ef;
+ struct rw_semaphore *eventfs_rwsem;
+
+ if (!ef_parent)
+ return -EINVAL;
+
+ if (!(mode & S_IFMT))
+ mode |= S_IFREG;
+
+ ef = kzalloc(sizeof(*ef), GFP_KERNEL);
+ if (!ef)
+ return -ENOMEM;
+
+ ef->name = kstrdup(name, GFP_KERNEL);
+ if (!ef->name) {
+ kfree(ef);
+ return -ENOMEM;
+ }
+
+ ef->mode = mode;
+ ef->data = data;
+ ef->fop = fop;
+ ef->dentry = NULL;
+ ef->ei = NULL;
+ ef->created = false;
+
+ eventfs_rwsem = (struct rw_semaphore *) ef_parent->data;
+ eventfs_down_write(eventfs_rwsem);
+ list_add_tail(&ef->list, &ef_parent->ei->e_top_files);
+ eventfs_up_write(eventfs_rwsem);
+ return 0;
+}
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index aeca6761f..1e1780a61 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -50,6 +50,14 @@ struct eventfs_file *eventfs_add_dir(const char *name,
struct eventfs_file *ef_parent,
struct rw_semaphore *eventfs_rwsem);

+int eventfs_add_file(const char *name, umode_t mode,
+ struct eventfs_file *ef_parent, void *data,
+ const struct file_operations *fops);
+
+int eventfs_add_top_file(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops);
+
struct dentry *tracefs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
--
2.39.0

2023-05-02 11:27:02

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 9/9] test: ftrace: fix kprobe test for eventfs

kprobe_args_char.tc, kprobe_args_string.tc has validation check
for tracefs_create_dir, for eventfs it should be eventfs_create_dir.

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
.../selftests/ftrace/test.d/kprobe/kprobe_args_char.tc | 4 ++--
.../selftests/ftrace/test.d/kprobe/kprobe_args_string.tc | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc
index 285b4770e..523cfb645 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc
@@ -34,14 +34,14 @@ mips*)
esac

: "Test get argument (1)"
-echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):char" > kprobe_events
+echo "p:testprobe eventfs_add_dir arg1=+0(${ARG1}):char" > kprobe_events
echo 1 > events/kprobes/testprobe/enable
echo "p:test $FUNCTION_FORK" >> kprobe_events
grep -qe "testprobe.* arg1='t'" trace

echo 0 > events/kprobes/testprobe/enable
: "Test get argument (2)"
-echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):char arg2=+0(${ARG1}):char[4]" > kprobe_events
+echo "p:testprobe eventfs_add_dir arg1=+0(${ARG1}):char arg2=+0(${ARG1}):char[4]" > kprobe_events
echo 1 > events/kprobes/testprobe/enable
echo "p:test $FUNCTION_FORK" >> kprobe_events
grep -qe "testprobe.* arg1='t' arg2={'t','e','s','t'}" trace
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
index a4f8e7c53..b9f8c3f8b 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
@@ -37,14 +37,14 @@ loongarch*)
esac

: "Test get argument (1)"
-echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):string" > kprobe_events
+echo "p:testprobe eventfs_add_dir arg1=+0(${ARG1}):string" > kprobe_events
echo 1 > events/kprobes/testprobe/enable
echo "p:test $FUNCTION_FORK" >> kprobe_events
grep -qe "testprobe.* arg1=\"test\"" trace

echo 0 > events/kprobes/testprobe/enable
: "Test get argument (2)"
-echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):string arg2=+0(${ARG1}):string" > kprobe_events
+echo "p:testprobe eventfs_add_dir arg1=+0(${ARG1}):string arg2=+0(${ARG1}):string" > kprobe_events
echo 1 > events/kprobes/testprobe/enable
echo "p:test $FUNCTION_FORK" >> kprobe_events
grep -qe "testprobe.* arg1=\"test\" arg2=\"test\"" trace
--
2.39.0

2023-05-02 11:27:20

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 6/9] eventfs: adding eventfs lookup, read, open functions

Adding following functions to eventfs:
eventfs_set_ef_status_free()
eventfs_post_create_dir()
eventfs_root_lookup()
eventfs_release()
dcache_dir_open_wrapper()

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/event_inode.c | 188 +++++++++++++++++++++++++++++++++++++++
include/linux/tracefs.h | 2 +
2 files changed, 190 insertions(+)

diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 0ee27f7c8..f047e45ed 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -208,10 +208,198 @@ static struct dentry *eventfs_create_dir(const char *name, umode_t mode,
return eventfs_end_creating(dentry);
}

+/**
+ * eventfs_set_ef_status_free - set the ef->status to free
+ * @dentry: dentry who's status to be freed
+ *
+ * eventfs_set_ef_status_free will be called if no more
+ * reference remains
+ */
+void eventfs_set_ef_status_free(struct dentry *dentry)
+{
+ struct tracefs_inode *ti_parent;
+ struct eventfs_file *ef;
+
+ ti_parent = get_tracefs(dentry->d_parent->d_inode);
+ if (!ti_parent || !(ti_parent->flags & TRACEFS_EVENT_INODE))
+ return;
+
+ ef = dentry->d_fsdata;
+ if (!ef)
+ return;
+ ef->created = false;
+ ef->dentry = NULL;
+}
+
+/**
+ * eventfs_post_create_dir - post create dir routine
+ * @ef: eventfs_file of recently created dir
+ *
+ * Files with-in eventfs dir should know dentry of parent dir
+ */
+static void eventfs_post_create_dir(struct eventfs_file *ef)
+{
+ struct eventfs_file *ef_child;
+ struct tracefs_inode *ti;
+
+ eventfs_down_read((struct rw_semaphore *) ef->data);
+ /* fill parent-child relation */
+ list_for_each_entry(ef_child, &ef->ei->e_top_files, list) {
+ ef_child->d_parent = ef->dentry;
+ }
+ eventfs_up_read((struct rw_semaphore *) ef->data);
+
+ ti = get_tracefs(ef->dentry->d_inode);
+ ti->private = ef->ei;
+}
+
+/**
+ * eventfs_root_lookup - lookup routine to create file/dir
+ * @dir: directory in which lookup to be done
+ * @dentry: file/dir dentry
+ * @flags:
+ *
+ * Used to create dynamic file/dir with-in @dir, search with-in ei
+ * list, if @dentry found go ahead and create the file/dir
+ */
+
+static struct dentry *eventfs_root_lookup(struct inode *dir,
+ struct dentry *dentry,
+ unsigned int flags)
+{
+ struct tracefs_inode *ti;
+ struct eventfs_inode *ei;
+ struct eventfs_file *ef;
+ struct dentry *ret = NULL;
+ struct rw_semaphore *eventfs_rwsem;
+
+ ti = get_tracefs(dir);
+ if (!(ti->flags & TRACEFS_EVENT_INODE))
+ return NULL;
+
+ ei = ti->private;
+ eventfs_rwsem = (struct rw_semaphore *) dir->i_private;
+ eventfs_down_read(eventfs_rwsem);
+ list_for_each_entry(ef, &ei->e_top_files, list) {
+ if (strcmp(ef->name, dentry->d_name.name))
+ continue;
+ ret = simple_lookup(dir, dentry, flags);
+ if (ef->created)
+ continue;
+ ef->created = true;
+ if (ef->ei)
+ ef->dentry = eventfs_create_dir(ef->name, ef->mode, ef->d_parent,
+ ef->data, ef->fop, ef->iop);
+ else
+ ef->dentry = eventfs_create_file(ef->name, ef->mode, ef->d_parent,
+ ef->data, ef->fop);
+
+ if (IS_ERR_OR_NULL(ef->dentry)) {
+ ef->created = false;
+ } else {
+ if (ef->ei)
+ eventfs_post_create_dir(ef);
+ ef->dentry->d_fsdata = ef;
+ dput(ef->dentry);
+ }
+ break;
+ }
+ eventfs_up_read(eventfs_rwsem);
+ return ret;
+}
+
+/**
+ * eventfs_release - called to release eventfs file/dir
+ * @inode: inode to be released
+ * @file: file to be released (not used)
+ */
+static int eventfs_release(struct inode *inode, struct file *file)
+{
+ struct tracefs_inode *ti;
+ struct eventfs_inode *ei;
+ struct eventfs_file *ef;
+ struct dentry *dentry = file_dentry(file);
+ struct rw_semaphore *eventfs_rwsem;
+
+ ti = get_tracefs(inode);
+ if (!(ti->flags & TRACEFS_EVENT_INODE))
+ return -EINVAL;
+
+ ei = ti->private;
+ eventfs_rwsem = eventfs_dentry_to_rwsem(dentry);
+ eventfs_down_read(eventfs_rwsem);
+ list_for_each_entry(ef, &ei->e_top_files, list) {
+ if (ef->created)
+ dput(ef->dentry);
+ }
+ eventfs_up_read(eventfs_rwsem);
+ return dcache_dir_close(inode, file);
+}
+
+/**
+ * dcache_dir_open_wrapper - eventfs open wrapper
+ * @inode: not used
+ * @file: dir to be opened (to create it's child)
+ *
+ * Used to dynamic create file/dir with-in @file, all the
+ * file/dir will be created. If already created then reference
+ * will be increased
+ */
+static int dcache_dir_open_wrapper(struct inode *inode, struct file *file)
+{
+ struct tracefs_inode *ti;
+ struct eventfs_inode *ei;
+ struct eventfs_file *ef;
+ struct inode *f_inode = file_inode(file);
+ struct dentry *dentry = file_dentry(file);
+ struct rw_semaphore *eventfs_rwsem;
+
+ ti = get_tracefs(f_inode);
+ if (!(ti->flags & TRACEFS_EVENT_INODE))
+ return -EINVAL;
+
+ ei = ti->private;
+ eventfs_rwsem = eventfs_dentry_to_rwsem(dentry);
+ eventfs_down_read(eventfs_rwsem);
+ list_for_each_entry(ef, &ei->e_top_files, list) {
+ if (ef->created) {
+ dget(ef->dentry);
+ continue;
+ }
+
+ ef->created = true;
+
+ inode_lock(dentry->d_inode);
+ if (ef->ei)
+ ef->dentry = eventfs_create_dir(ef->name, ef->mode, dentry,
+ ef->data, ef->fop, ef->iop);
+ else
+ ef->dentry = eventfs_create_file(ef->name, ef->mode, dentry,
+ ef->data, ef->fop);
+ inode_unlock(dentry->d_inode);
+
+ if (IS_ERR_OR_NULL(ef->dentry)) {
+ ef->created = false;
+ } else {
+ if (ef->ei)
+ eventfs_post_create_dir(ef);
+ ef->dentry->d_fsdata = ef;
+ }
+ }
+ eventfs_up_read(eventfs_rwsem);
+ return dcache_dir_open(inode, file);
+}
+
static const struct file_operations eventfs_file_operations = {
+ .open = dcache_dir_open_wrapper,
+ .read = generic_read_dir,
+ .iterate_shared = dcache_readdir,
+ .llseek = generic_file_llseek,
+ .release = eventfs_release,
};

static const struct inode_operations eventfs_root_dir_inode_operations = {
+ .lookup = eventfs_root_lookup,
};

/**
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 57bfd1322..268450d60 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -68,6 +68,8 @@ void eventfs_remove(struct eventfs_file *ef);

void eventfs_remove_events_dir(struct dentry *dentry);

+void eventfs_set_ef_status_free(struct dentry *dentry);
+
struct dentry *tracefs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
--
2.39.0

2023-05-02 11:27:43

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 4/9] eventfs: adding eventfs file, directory remove function

Adding eventfs_remove(), this function will recursively remove
dir or file info from eventfs.

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/event_inode.c | 78 ++++++++++++++++++++++++++++++++++++++++
include/linux/tracefs.h | 4 +++
2 files changed, 82 insertions(+)

diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 93134ae40..9ab675edf 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -368,3 +368,81 @@ int eventfs_add_file(const char *name, umode_t mode,
eventfs_up_write(eventfs_rwsem);
return 0;
}
+
+/**
+ * eventfs_remove_rec - remove eventfs dir or file from list
+ * @ef: a pointer to eventfs_file to be removed.
+ *
+ * This function recursively remove eventfs_file which
+ * contains info of file or dir.
+ */
+void eventfs_remove_rec(struct eventfs_file *ef)
+{
+ struct eventfs_file *ef_child, *n;
+
+ if (!ef)
+ return;
+
+ if (ef->ei) {
+ /* search for nested folders or files */
+ list_for_each_entry_safe(ef_child, n, &ef->ei->e_top_files, list) {
+ eventfs_remove_rec(ef_child);
+ }
+ kfree(ef->ei);
+ }
+
+ if (ef->created && ef->dentry) {
+ d_invalidate(ef->dentry);
+ dput(ef->dentry);
+ }
+ list_del(&ef->list);
+ kfree(ef->name);
+ kfree(ef);
+}
+
+/**
+ * eventfs_remove - remove eventfs dir or file from list
+ * @ef: a pointer to eventfs_file to be removed.
+ *
+ * This function acquire the eventfs_rwsem lock and call eventfs_remove_rec()
+ */
+void eventfs_remove(struct eventfs_file *ef)
+{
+ struct rw_semaphore *eventfs_rwsem;
+
+ if (!ef)
+ return;
+
+ if (ef->ei)
+ eventfs_rwsem = (struct rw_semaphore *) ef->data;
+ else
+ eventfs_rwsem = (struct rw_semaphore *) ef->d_parent->d_inode->i_private;
+
+ eventfs_down_write(eventfs_rwsem);
+ eventfs_remove_rec(ef);
+ eventfs_up_write(eventfs_rwsem);
+}
+
+/**
+ * eventfs_remove_events_dir - remove eventfs dir or file from list
+ * @dentry: a pointer to events's dentry to be removed.
+ *
+ * This function remove events main directory
+ */
+void eventfs_remove_events_dir(struct dentry *dentry)
+{
+ struct tracefs_inode *ti;
+ struct eventfs_inode *ei;
+
+ if (!dentry || !dentry->d_inode)
+ return;
+
+ ti = get_tracefs(dentry->d_inode);
+ if (!ti || !(ti->flags & TRACEFS_EVENT_INODE))
+ return;
+
+ ei = ti->private;
+ d_invalidate(dentry);
+ dput(dentry);
+ kfree(ei);
+}
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 1e1780a61..ea10ccc87 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -58,6 +58,10 @@ int eventfs_add_top_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);

+void eventfs_remove(struct eventfs_file *ef);
+
+void eventfs_remove_events_dir(struct dentry *dentry);
+
struct dentry *tracefs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
--
2.39.0

2023-05-02 11:27:56

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 7/9] eventfs: creating tracefs_inode_cache

Creating tracefs_inode_cache which is a cache of tracefs_inode.
Adding helping functions:
tracefs_alloc_inode()
tracefs_free_inode()

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/inode.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 66c4df734..76820d3e9 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -24,11 +24,30 @@
#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)
{
@@ -347,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,
@@ -676,10 +698,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;
--
2.39.0

2023-05-02 11:28:12

by Ajay Kaher

[permalink] [raw]
Subject: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

Till now /sys/kernel/debug/tracing/events is a part of tracefs,
with-in this patch creating 'events' and it's sub-dir as eventfs.
Basically replacing tracefs calls with eventfs calls for 'events'.

Signed-off-by: Ajay Kaher <[email protected]>
Co-developed-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Tested-by: Ching-lin Yu <[email protected]>
---
fs/tracefs/inode.c | 18 ++++++++++
include/linux/trace_events.h | 1 +
kernel/trace/trace.h | 2 +-
kernel/trace/trace_events.c | 66 +++++++++++++++++++-----------------
4 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index 76820d3e9..a098d7153 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -374,6 +374,23 @@ static const struct super_operations tracefs_super_operations = {
.show_options = tracefs_show_options,
};

+static void tracefs_dentry_iput(struct dentry *dentry, struct inode *inode)
+{
+ struct tracefs_inode *ti;
+
+ if (!dentry || !inode)
+ return;
+
+ ti = get_tracefs(inode);
+ if (ti && ti->flags & TRACEFS_EVENT_INODE)
+ eventfs_set_ef_status_free(dentry);
+ iput(inode);
+}
+
+static const struct dentry_operations tracefs_dentry_operations = {
+ .d_iput = tracefs_dentry_iput,
+};
+
static int trace_fill_super(struct super_block *sb, void *data, int silent)
{
static const struct tree_descr trace_files[] = {{""}};
@@ -396,6 +413,7 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent)
goto fail;

sb->s_op = &tracefs_super_operations;
+ sb->s_d_op = &tracefs_dentry_operations;

tracefs_apply_options(sb, false);

diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 0e373222a..696843d46 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -635,6 +635,7 @@ struct trace_event_file {
struct list_head list;
struct trace_event_call *event_call;
struct event_filter __rcu *filter;
+ struct eventfs_file *ef;
struct dentry *dir;
struct trace_array *tr;
struct trace_subsystem_dir *system;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 3726725c8..ee9002852 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1308,7 +1308,7 @@ struct trace_subsystem_dir {
struct list_head list;
struct event_subsystem *subsystem;
struct trace_array *tr;
- struct dentry *entry;
+ struct eventfs_file *ef;
int ref_count;
int nr_events;
};
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 654ffa404..01bd3dda6 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -988,7 +988,8 @@ static void remove_subsystem(struct trace_subsystem_dir *dir)
return;

if (!--dir->nr_events) {
- tracefs_remove(dir->entry);
+ if (dir->ef)
+ eventfs_remove(dir->ef);
list_del(&dir->list);
__put_system_dir(dir);
}
@@ -1009,7 +1010,8 @@ static void remove_event_file_dir(struct trace_event_file *file)

tracefs_remove(dir);
}
-
+ if (file->ef)
+ eventfs_remove(file->ef);
list_del(&file->list);
remove_subsystem(file->system);
free_event_filter(file->filter);
@@ -2295,13 +2297,13 @@ create_new_subsystem(const char *name)
return NULL;
}

-static struct dentry *
+static struct eventfs_file *
event_subsystem_dir(struct trace_array *tr, const char *name,
struct trace_event_file *file, struct dentry *parent)
{
struct event_subsystem *system, *iter;
struct trace_subsystem_dir *dir;
- struct dentry *entry;
+ int res;

/* First see if we did not already create this dir */
list_for_each_entry(dir, &tr->systems, list) {
@@ -2309,7 +2311,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
if (strcmp(system->name, name) == 0) {
dir->nr_events++;
file->system = dir;
- return dir->entry;
+ return dir->ef;
}
}

@@ -2333,8 +2335,8 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
} else
__get_system(system);

- dir->entry = tracefs_create_dir(name, parent);
- if (!dir->entry) {
+ dir->ef = eventfs_add_subsystem_dir(name, parent, &tr->eventfs_rwsem);
+ if (IS_ERR(dir->ef)) {
pr_warn("Failed to create system directory %s\n", name);
__put_system(system);
goto out_free;
@@ -2349,22 +2351,22 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
/* the ftrace system is special, do not create enable or filter files */
if (strcmp(name, "ftrace") != 0) {

- entry = tracefs_create_file("filter", TRACE_MODE_WRITE,
- dir->entry, dir,
+ res = eventfs_add_file("filter", TRACE_MODE_WRITE,
+ dir->ef, dir,
&ftrace_subsystem_filter_fops);
- if (!entry) {
+ if (res) {
kfree(system->filter);
system->filter = NULL;
pr_warn("Could not create tracefs '%s/filter' entry\n", name);
}

- trace_create_file("enable", TRACE_MODE_WRITE, dir->entry, dir,
+ eventfs_add_file("enable", TRACE_MODE_WRITE, dir->ef, dir,
&ftrace_system_enable_fops);
}

list_add(&dir->list, &tr->systems);

- return dir->entry;
+ return dir->ef;

out_free:
kfree(dir);
@@ -2418,6 +2420,7 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
{
struct trace_event_call *call = file->event_call;
struct trace_array *tr = file->tr;
+ struct eventfs_file *ef_subsystem = NULL;
struct dentry *d_events;
const char *name;
int ret;
@@ -2427,26 +2430,26 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
* then the system would be called "TRACE_SYSTEM".
*/
if (strcmp(call->class->system, TRACE_SYSTEM) != 0) {
- d_events = event_subsystem_dir(tr, call->class->system, file, parent);
- if (!d_events)
+ ef_subsystem = event_subsystem_dir(tr, call->class->system, file, parent);
+ if (!ef_subsystem)
return -ENOMEM;
} else
d_events = parent;

name = trace_event_name(call);
- file->dir = tracefs_create_dir(name, d_events);
- if (!file->dir) {
+ file->ef = eventfs_add_dir(name, ef_subsystem, &tr->eventfs_rwsem);
+ if (IS_ERR(file->ef)) {
pr_warn("Could not create tracefs '%s' directory\n", name);
return -1;
}

if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
- trace_create_file("enable", TRACE_MODE_WRITE, file->dir, file,
+ eventfs_add_file("enable", TRACE_MODE_WRITE, file->ef, file,
&ftrace_enable_fops);

#ifdef CONFIG_PERF_EVENTS
if (call->event.type && call->class->reg)
- trace_create_file("id", TRACE_MODE_READ, file->dir,
+ eventfs_add_file("id", TRACE_MODE_READ, file->ef,
(void *)(long)call->event.type,
&ftrace_event_id_fops);
#endif
@@ -2462,27 +2465,27 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
* triggers or filters.
*/
if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) {
- trace_create_file("filter", TRACE_MODE_WRITE, file->dir,
+ eventfs_add_file("filter", TRACE_MODE_WRITE, file->ef,
file, &ftrace_event_filter_fops);

- trace_create_file("trigger", TRACE_MODE_WRITE, file->dir,
+ eventfs_add_file("trigger", TRACE_MODE_WRITE, file->ef,
file, &event_trigger_fops);
}

#ifdef CONFIG_HIST_TRIGGERS
- trace_create_file("hist", TRACE_MODE_READ, file->dir, file,
+ eventfs_add_file("hist", TRACE_MODE_READ, file->ef, file,
&event_hist_fops);
#endif
#ifdef CONFIG_HIST_TRIGGERS_DEBUG
- trace_create_file("hist_debug", TRACE_MODE_READ, file->dir, file,
+ eventfs_add_file("hist_debug", TRACE_MODE_READ, file->ef, file,
&event_hist_debug_fops);
#endif
- trace_create_file("format", TRACE_MODE_READ, file->dir, call,
+ eventfs_add_file("format", TRACE_MODE_READ, file->ef, call,
&ftrace_event_format_fops);

#ifdef CONFIG_TRACE_EVENT_INJECT
if (call->event.type && call->class->reg)
- trace_create_file("inject", 0200, file->dir, file,
+ eventfs_add_file("inject", 0200, file->ef, file,
&event_inject_fops);
#endif

@@ -3635,21 +3638,22 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
{
struct dentry *d_events;
struct dentry *entry;
+ int error = 0;

entry = trace_create_file("set_event", TRACE_MODE_WRITE, parent,
tr, &ftrace_set_event_fops);
if (!entry)
return -ENOMEM;

- d_events = tracefs_create_dir("events", parent);
- if (!d_events) {
+ d_events = eventfs_create_events_dir("events", parent, &tr->eventfs_rwsem);
+ if (IS_ERR(d_events)) {
pr_warn("Could not create tracefs 'events' directory\n");
return -ENOMEM;
}

- entry = trace_create_file("enable", TRACE_MODE_WRITE, d_events,
+ error = eventfs_add_top_file("enable", TRACE_MODE_WRITE, d_events,
tr, &ftrace_tr_enable_fops);
- if (!entry)
+ if (error)
return -ENOMEM;

/* There are not as crucial, just warn if they are not created */
@@ -3662,11 +3666,11 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
&ftrace_set_event_notrace_pid_fops);

/* ring buffer internal formats */
- trace_create_file("header_page", TRACE_MODE_READ, d_events,
+ eventfs_add_top_file("header_page", TRACE_MODE_READ, d_events,
ring_buffer_print_page_header,
&ftrace_show_header_fops);

- trace_create_file("header_event", TRACE_MODE_READ, d_events,
+ eventfs_add_top_file("header_event", TRACE_MODE_READ, d_events,
ring_buffer_print_entry_header,
&ftrace_show_header_fops);

@@ -3754,7 +3758,7 @@ int event_trace_del_tracer(struct trace_array *tr)

down_write(&trace_event_sem);
__trace_remove_event_dirs(tr);
- tracefs_remove(tr->event_dir);
+ eventfs_remove_events_dir(tr->event_dir);
up_write(&trace_event_sem);

tr->event_dir = NULL;
--
2.39.0

2023-05-02 13:53:44

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

Hi Ajay,

kernel test robot noticed the following build warnings:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on shuah-kselftest/fixes linus/master]
[cannot apply to rostedt-trace/for-next-urgent]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
base: https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
patch link: https://lore.kernel.org/r/1683026600-13485-9-git-send-email-akaher%40vmware.com
patch subject: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs
config: mips-allyesconfig (https://download.01.org/0day-ci/archive/20230502/[email protected]/config)
compiler: mips-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/2fe2002efb23a715f5eb7a58891ff85f4e37b084
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
git checkout 2fe2002efb23a715f5eb7a58891ff85f4e37b084
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=mips olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash kernel/trace/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

kernel/trace/trace_events.c: In function 'event_create_dir':
>> kernel/trace/trace_events.c:2424:24: warning: variable 'd_events' set but not used [-Wunused-but-set-variable]
2424 | struct dentry *d_events;
| ^~~~~~~~


vim +/d_events +2424 kernel/trace/trace_events.c

ac343da7bc9048 Masami Hiramatsu 2020-09-10 2417
1473e4417c79f1 Steven Rostedt 2009-02-24 2418 static int
7f1d2f8210195c Steven Rostedt (Red Hat 2015-05-05 2419) event_create_dir(struct dentry *parent, struct trace_event_file *file)
1473e4417c79f1 Steven Rostedt 2009-02-24 2420 {
2425bcb9240f8c Steven Rostedt (Red Hat 2015-05-05 2421) struct trace_event_call *call = file->event_call;
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2422 struct trace_array *tr = file->tr;
2fe2002efb23a7 Ajay Kaher 2023-05-02 2423 struct eventfs_file *ef_subsystem = NULL;
ae63b31e4d0e2e Steven Rostedt 2012-05-03 @2424 struct dentry *d_events;
de7b2973903c6c Mathieu Desnoyers 2014-04-08 2425 const char *name;
fd99498989f3b3 Steven Rostedt 2009-02-28 2426 int ret;
1473e4417c79f1 Steven Rostedt 2009-02-24 2427
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2428 /*
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2429 * If the trace point header did not define TRACE_SYSTEM
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2430 * then the system would be called "TRACE_SYSTEM".
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2431 */
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2432 if (strcmp(call->class->system, TRACE_SYSTEM) != 0) {
2fe2002efb23a7 Ajay Kaher 2023-05-02 2433 ef_subsystem = event_subsystem_dir(tr, call->class->system, file, parent);
2fe2002efb23a7 Ajay Kaher 2023-05-02 2434 if (!ef_subsystem)
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2435 return -ENOMEM;
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2436 } else
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2437 d_events = parent;
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2438
687fcc4aee4567 Steven Rostedt (Red Hat 2015-05-13 2439) name = trace_event_name(call);
2fe2002efb23a7 Ajay Kaher 2023-05-02 2440 file->ef = eventfs_add_dir(name, ef_subsystem, &tr->eventfs_rwsem);
2fe2002efb23a7 Ajay Kaher 2023-05-02 2441 if (IS_ERR(file->ef)) {
8434dc9340cd2e Steven Rostedt (Red Hat 2015-01-20 2442) pr_warn("Could not create tracefs '%s' directory\n", name);
1473e4417c79f1 Steven Rostedt 2009-02-24 2443 return -1;
1473e4417c79f1 Steven Rostedt 2009-02-24 2444 }
1473e4417c79f1 Steven Rostedt 2009-02-24 2445
9b63776fa3ca96 Steven Rostedt 2012-05-10 2446 if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
2fe2002efb23a7 Ajay Kaher 2023-05-02 2447 eventfs_add_file("enable", TRACE_MODE_WRITE, file->ef, file,
620a30e97febc8 Oleg Nesterov 2013-07-31 2448 &ftrace_enable_fops);
1473e4417c79f1 Steven Rostedt 2009-02-24 2449

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-05-02 14:28:50

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 4/9] eventfs: adding eventfs file, directory remove function

Hi Ajay,

kernel test robot noticed the following build warnings:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on shuah-kselftest/fixes linus/master rostedt-trace/for-next v6.3 next-20230428]
[cannot apply to rostedt-trace/for-next-urgent]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
base: https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
patch link: https://lore.kernel.org/r/1683026600-13485-5-git-send-email-akaher%40vmware.com
patch subject: [PATCH v2 4/9] eventfs: adding eventfs file, directory remove function
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20230502/[email protected]/config)
compiler: arceb-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/9a36b39da0c3fbfe15a3c3a0ed71b52013bac292
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
git checkout 9a36b39da0c3fbfe15a3c3a0ed71b52013bac292
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash fs/tracefs/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> fs/tracefs/event_inode.c:379:6: warning: no previous prototype for 'eventfs_remove_rec' [-Wmissing-prototypes]
379 | void eventfs_remove_rec(struct eventfs_file *ef)
| ^~~~~~~~~~~~~~~~~~
fs/tracefs/event_inode.c:58:13: warning: 'eventfs_up_read' defined but not used [-Wunused-function]
58 | static void eventfs_up_read(struct rw_semaphore *eventfs_rwsem)
| ^~~~~~~~~~~~~~~
fs/tracefs/event_inode.c:47:13: warning: 'eventfs_down_read' defined but not used [-Wunused-function]
47 | static void eventfs_down_read(struct rw_semaphore *eventfs_rwsem)
| ^~~~~~~~~~~~~~~~~
fs/tracefs/event_inode.c:31:29: warning: 'eventfs_dentry_to_rwsem' defined but not used [-Wunused-function]
31 | static struct rw_semaphore *eventfs_dentry_to_rwsem(struct dentry *dentry)
| ^~~~~~~~~~~~~~~~~~~~~~~


vim +/eventfs_remove_rec +379 fs/tracefs/event_inode.c

371
372 /**
373 * eventfs_remove_rec - remove eventfs dir or file from list
374 * @ef: a pointer to eventfs_file to be removed.
375 *
376 * This function recursively remove eventfs_file which
377 * contains info of file or dir.
378 */
> 379 void eventfs_remove_rec(struct eventfs_file *ef)
380 {
381 struct eventfs_file *ef_child, *n;
382
383 if (!ef)
384 return;
385
386 if (ef->ei) {
387 /* search for nested folders or files */
388 list_for_each_entry_safe(ef_child, n, &ef->ei->e_top_files, list) {
389 eventfs_remove_rec(ef_child);
390 }
391 kfree(ef->ei);
392 }
393
394 if (ef->created && ef->dentry) {
395 d_invalidate(ef->dentry);
396 dput(ef->dentry);
397 }
398 list_del(&ef->list);
399 kfree(ef->name);
400 kfree(ef);
401 }
402

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-05-02 16:19:15

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 4/9] eventfs: adding eventfs file, directory remove function

Hi Ajay,

kernel test robot noticed the following build warnings:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on shuah-kselftest/fixes linus/master v6.3 next-20230428]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
base: https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
patch link: https://lore.kernel.org/r/1683026600-13485-5-git-send-email-akaher%40vmware.com
patch subject: [PATCH v2 4/9] eventfs: adding eventfs file, directory remove function
config: i386-randconfig-a011-20230501 (https://download.01.org/0day-ci/archive/20230502/[email protected]/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/9a36b39da0c3fbfe15a3c3a0ed71b52013bac292
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
git checkout 9a36b39da0c3fbfe15a3c3a0ed71b52013bac292
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash fs/tracefs/ kernel/trace/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> fs/tracefs/event_inode.c:379:6: warning: no previous prototype for function 'eventfs_remove_rec' [-Wmissing-prototypes]
void eventfs_remove_rec(struct eventfs_file *ef)
^
fs/tracefs/event_inode.c:379:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void eventfs_remove_rec(struct eventfs_file *ef)
^
static
fs/tracefs/event_inode.c:31:29: warning: unused function 'eventfs_dentry_to_rwsem' [-Wunused-function]
static struct rw_semaphore *eventfs_dentry_to_rwsem(struct dentry *dentry)
^
fs/tracefs/event_inode.c:47:13: warning: unused function 'eventfs_down_read' [-Wunused-function]
static void eventfs_down_read(struct rw_semaphore *eventfs_rwsem)
^
fs/tracefs/event_inode.c:58:13: warning: unused function 'eventfs_up_read' [-Wunused-function]
static void eventfs_up_read(struct rw_semaphore *eventfs_rwsem)
^
4 warnings generated.


vim +/eventfs_remove_rec +379 fs/tracefs/event_inode.c

371
372 /**
373 * eventfs_remove_rec - remove eventfs dir or file from list
374 * @ef: a pointer to eventfs_file to be removed.
375 *
376 * This function recursively remove eventfs_file which
377 * contains info of file or dir.
378 */
> 379 void eventfs_remove_rec(struct eventfs_file *ef)
380 {
381 struct eventfs_file *ef_child, *n;
382
383 if (!ef)
384 return;
385
386 if (ef->ei) {
387 /* search for nested folders or files */
388 list_for_each_entry_safe(ef_child, n, &ef->ei->e_top_files, list) {
389 eventfs_remove_rec(ef_child);
390 }
391 kfree(ef->ei);
392 }
393
394 if (ef->created && ef->dentry) {
395 d_invalidate(ef->dentry);
396 dput(ef->dentry);
397 }
398 list_del(&ef->list);
399 kfree(ef->name);
400 kfree(ef);
401 }
402

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-05-02 18:17:52

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

Hi Ajay,

kernel test robot noticed the following build warnings:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on shuah-kselftest/fixes linus/master v6.3 next-20230428]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
base: https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
patch link: https://lore.kernel.org/r/1683026600-13485-9-git-send-email-akaher%40vmware.com
patch subject: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs
config: i386-randconfig-a011-20230501 (https://download.01.org/0day-ci/archive/20230503/[email protected]/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/2fe2002efb23a715f5eb7a58891ff85f4e37b084
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
git checkout 2fe2002efb23a715f5eb7a58891ff85f4e37b084
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash kernel/trace/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> kernel/trace/trace_events.c:2424:17: warning: variable 'd_events' set but not used [-Wunused-but-set-variable]
struct dentry *d_events;
^
1 warning generated.


vim +/d_events +2424 kernel/trace/trace_events.c

ac343da7bc9048 Masami Hiramatsu 2020-09-10 2417
1473e4417c79f1 Steven Rostedt 2009-02-24 2418 static int
7f1d2f8210195c Steven Rostedt (Red Hat 2015-05-05 2419) event_create_dir(struct dentry *parent, struct trace_event_file *file)
1473e4417c79f1 Steven Rostedt 2009-02-24 2420 {
2425bcb9240f8c Steven Rostedt (Red Hat 2015-05-05 2421) struct trace_event_call *call = file->event_call;
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2422 struct trace_array *tr = file->tr;
2fe2002efb23a7 Ajay Kaher 2023-05-02 2423 struct eventfs_file *ef_subsystem = NULL;
ae63b31e4d0e2e Steven Rostedt 2012-05-03 @2424 struct dentry *d_events;
de7b2973903c6c Mathieu Desnoyers 2014-04-08 2425 const char *name;
fd99498989f3b3 Steven Rostedt 2009-02-28 2426 int ret;
1473e4417c79f1 Steven Rostedt 2009-02-24 2427
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2428 /*
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2429 * If the trace point header did not define TRACE_SYSTEM
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2430 * then the system would be called "TRACE_SYSTEM".
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2431 */
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2432 if (strcmp(call->class->system, TRACE_SYSTEM) != 0) {
2fe2002efb23a7 Ajay Kaher 2023-05-02 2433 ef_subsystem = event_subsystem_dir(tr, call->class->system, file, parent);
2fe2002efb23a7 Ajay Kaher 2023-05-02 2434 if (!ef_subsystem)
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2435 return -ENOMEM;
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2436 } else
ae63b31e4d0e2e Steven Rostedt 2012-05-03 2437 d_events = parent;
6ecc2d1ca39177 Steven Rostedt 2009-02-27 2438
687fcc4aee4567 Steven Rostedt (Red Hat 2015-05-13 2439) name = trace_event_name(call);
2fe2002efb23a7 Ajay Kaher 2023-05-02 2440 file->ef = eventfs_add_dir(name, ef_subsystem, &tr->eventfs_rwsem);
2fe2002efb23a7 Ajay Kaher 2023-05-02 2441 if (IS_ERR(file->ef)) {
8434dc9340cd2e Steven Rostedt (Red Hat 2015-01-20 2442) pr_warn("Could not create tracefs '%s' directory\n", name);
1473e4417c79f1 Steven Rostedt 2009-02-24 2443 return -1;
1473e4417c79f1 Steven Rostedt 2009-02-24 2444 }
1473e4417c79f1 Steven Rostedt 2009-02-24 2445
9b63776fa3ca96 Steven Rostedt 2012-05-10 2446 if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
2fe2002efb23a7 Ajay Kaher 2023-05-02 2447 eventfs_add_file("enable", TRACE_MODE_WRITE, file->ef, file,
620a30e97febc8 Oleg Nesterov 2013-07-31 2448 &ftrace_enable_fops);
1473e4417c79f1 Steven Rostedt 2009-02-24 2449

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-05-02 22:26:33

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 4/9] eventfs: adding eventfs file, directory remove function

Hi Ajay,

kernel test robot noticed the following build warnings:

[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on shuah-kselftest/fixes linus/master rostedt-trace/for-next v6.3 next-20230428]
[cannot apply to rostedt-trace/for-next-urgent]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
base: https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
patch link: https://lore.kernel.org/r/1683026600-13485-5-git-send-email-akaher%40vmware.com
patch subject: [PATCH v2 4/9] eventfs: adding eventfs file, directory remove function
config: i386-randconfig-s002 (https://download.01.org/0day-ci/archive/20230503/[email protected]/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/9a36b39da0c3fbfe15a3c3a0ed71b52013bac292
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
git checkout 9a36b39da0c3fbfe15a3c3a0ed71b52013bac292
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=i386 olddefconfig
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=i386 SHELL=/bin/bash fs/tracefs/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/

sparse warnings: (new ones prefixed by >>)
>> fs/tracefs/event_inode.c:379:6: sparse: sparse: symbol 'eventfs_remove_rec' was not declared. Should it be static?

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-05-05 10:06:54

by Yujie Liu

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

Hello,

kernel test robot noticed "WARNING:at_fs/namei.c:#lookup_one_len" on:

commit: 2fe2002efb23a715f5eb7a58891ff85f4e37b084 ("[PATCH v2 8/9] eventfs: moving tracing/events to eventfs")
url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
base: https://git.kernel.org/cgit/linux/kernel/git/shuah/linux-kselftest.git next
patch link: https://lore.kernel.org/all/[email protected]/
patch subject: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

in testcase: stress-ng
version: stress-ng-x86_64-0.15.04-1_20230503
with following parameters:

nr_threads: 100%
testtime: 60s
class: cpu
test: uprobe
cpufreq_governor: performance

compiler: gcc-11
test machine: 128 threads 2 sockets Intel(R) Xeon(R) Platinum 8358 CPU @ 2.60GHz (Ice Lake) with 128G memory

(please refer to attached dmesg/kmsg for entire log/backtrace)


If you fix the issue, kindly add following tag
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-lkp/[email protected]


[ 49.551466][ T5878] ------------[ cut here ]------------
[ 49.557236][ T5878] WARNING: CPU: 68 PID: 5878 at fs/namei.c:2705 lookup_one_len (fs/namei.c:2705 (discriminator 1))
[ 49.565959][ T5878] Modules linked in: intel_rapl_msr intel_rapl_common x86_pkg_temp_thermal intel_powerclamp coretemp btrfs blake2b_generic xor raid6_pq libcrc32c sd_mod t10_pi kvm_intel crc64_rocksoft_generic crc64_rocksoft kvm crc64 irqbypass sg crct10dif_pclmul crc32_pclmul crc32c_intel ipmi_ssif ghash_clmulni_intel sha512_ssse3 rapl ahci acpi_ipmi intel_cstate libahci ast mei_me drm_shmem_helper ipmi_si drm_kms_helper ipmi_devintf ioatdma syscopyarea sysfillrect intel_uncore libata sysimgblt mei joydev dca wmi ipmi_msghandler acpi_pad acpi_power_meter drm fuse ip_tables
[ 49.618899][ T5878] CPU: 68 PID: 5878 Comm: stress-ng-uprob Not tainted 6.3.0-rc1-00033-g2fe2002efb23 #1
[ 49.628810][ T5878] RIP: 0010:lookup_one_len (fs/namei.c:2705 (discriminator 1))
[ 49.634395][ T5878] Code: 83 c4 18 5d c3 cc cc cc cc 31 d2 48 89 ee 48 89 e7 e8 8a da ff ff 48 85 c0 75 d4 31 d2 48 89 ee 48 89 e7 e8 b8 db ff ff eb c5 <0f> 0b eb a6 e8 ad 85 ac 00 66 66 2e 0f 1f 84 00 00 00 00 00 66 66
All code
========
0: 83 c4 18 add $0x18,%esp
3: 5d pop %rbp
4: c3 ret
5: cc int3
6: cc int3
7: cc int3
8: cc int3
9: 31 d2 xor %edx,%edx
b: 48 89 ee mov %rbp,%rsi
e: 48 89 e7 mov %rsp,%rdi
11: e8 8a da ff ff call 0xffffffffffffdaa0
16: 48 85 c0 test %rax,%rax
19: 75 d4 jne 0xffffffffffffffef
1b: 31 d2 xor %edx,%edx
1d: 48 89 ee mov %rbp,%rsi
20: 48 89 e7 mov %rsp,%rdi
23: e8 b8 db ff ff call 0xffffffffffffdbe0
28: eb c5 jmp 0xffffffffffffffef
2a:* 0f 0b ud2 <-- trapping instruction
2c: eb a6 jmp 0xffffffffffffffd4
2e: e8 ad 85 ac 00 call 0xac85e0
33: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)
3a: 00 00 00 00
3e: 66 data16
3f: 66 data16

Code starting with the faulting instruction
===========================================
0: 0f 0b ud2
2: eb a6 jmp 0xffffffffffffffaa
4: e8 ad 85 ac 00 call 0xac85b6
9: 66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)
10: 00 00 00 00
14: 66 data16
15: 66 data16
[ 49.654574][ T5878] RSP: 0018:ffa000002b207bb0 EFLAGS: 00010246
[ 49.660865][ T5878] RAX: 0000000000000000 RBX: 00000000000041ed RCX: 0000000000000012
[ 49.669066][ T5878] RDX: 0000000000000012 RSI: ff110010866cfec0 RDI: ff11000104c631c0
[ 49.677271][ T5878] RBP: ff110010866cfec0 R08: ffffffff82268900 R09: ff11000104c631c0
[ 49.685392][ T5878] R10: ff110020610bfc80 R11: 00000012d7445f9b R12: ff11000104c631c0
[ 49.693516][ T5878] R13: ffffffff82268900 R14: ffffffff82268840 R15: 0000000000000000
[ 49.701640][ T5878] FS: 00007fcddb229740(0000) GS:ff1100103fb00000(0000) knlGS:0000000000000000
[ 49.710712][ T5878] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 49.717444][ T5878] CR2: 00007fcddb3704e0 CR3: 00000020628e0001 CR4: 0000000000771ee0
[ 49.725566][ T5878] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 49.733686][ T5878] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 49.741807][ T5878] PKRU: 55555554
[ 49.745507][ T5878] Call Trace:
[ 49.748961][ T5878] <TASK>
[ 49.752082][ T5878] eventfs_start_creating (fs/tracefs/inode.c:519)
[ 49.757416][ T5878] eventfs_create_dir (fs/tracefs/event_inode.c:187 (discriminator 3))
[ 49.762488][ T5878] eventfs_root_lookup (fs/tracefs/event_inode.c:291)
[ 49.767637][ T5878] __lookup_slow (fs/namei.c:1686)
[ 49.772268][ T5878] walk_component (include/linux/fs.h:773 fs/namei.c:1704 fs/namei.c:1994)
[ 49.777016][ T5878] link_path_walk+0x24e/0x3b0
[ 49.783462][ T5878] ? path_init (fs/namei.c:2387)
[ 49.788021][ T5878] path_openat (fs/namei.c:3711)
[ 49.792463][ T5878] do_filp_open (fs/namei.c:3742)
[ 49.797021][ T5878] ? __check_object_size (mm/memremap.c:107 mm/memremap.c:144)
[ 49.803055][ T5878] do_sys_openat2 (fs/open.c:1348)
[ 49.807740][ T5878] __x64_sys_openat (fs/open.c:1375)
[ 49.812512][ T5878] do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80)
[ 49.817068][ T5878] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)
[ 49.823092][ T5878] RIP: 0033:0x7fcddb3b84e7
[ 49.827584][ T5878] Code: 25 00 00 41 00 3d 00 00 41 00 74 47 64 8b 04 25 18 00 00 00 85 c0 75 6b 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 95 00 00 00 48 8b 4c 24 28 64 48 2b 0c 25
All code
========
0: 25 00 00 41 00 and $0x410000,%eax
5: 3d 00 00 41 00 cmp $0x410000,%eax
a: 74 47 je 0x53
c: 64 8b 04 25 18 00 00 mov %fs:0x18,%eax
13: 00
14: 85 c0 test %eax,%eax
16: 75 6b jne 0x83
18: 44 89 e2 mov %r12d,%edx
1b: 48 89 ee mov %rbp,%rsi
1e: bf 9c ff ff ff mov $0xffffff9c,%edi
23: b8 01 01 00 00 mov $0x101,%eax
28: 0f 05 syscall
2a:* 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax <-- trapping instruction
30: 0f 87 95 00 00 00 ja 0xcb
36: 48 8b 4c 24 28 mov 0x28(%rsp),%rcx
3b: 64 fs
3c: 48 rex.W
3d: 2b .byte 0x2b
3e: 0c 25 or $0x25,%al

Code starting with the faulting instruction
===========================================
0: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
6: 0f 87 95 00 00 00 ja 0xa1
c: 48 8b 4c 24 28 mov 0x28(%rsp),%rcx
11: 64 fs
12: 48 rex.W
13: 2b .byte 0x2b
14: 0c 25 or $0x25,%al
[ 49.847467][ T5878] RSP: 002b:00007ffd43974260 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
[ 49.855986][ T5878] RAX: ffffffffffffffda RBX: 00007ffd439743f0 RCX: 00007fcddb3b84e7
[ 49.864089][ T5878] RDX: 0000000000000241 RSI: 00007ffd43976470 RDI: 00000000ffffff9c
[ 49.872145][ T5878] RBP: 00007ffd43976470 R08: 00000000ffffffff R09: 00007ffd43974190
[ 49.880191][ T5878] R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000241
[ 49.888227][ T5878] R13: 00007ffd43974360 R14: 00007ffd43977630 R15: 00007ffd43976470
[ 49.896273][ T5878] </TASK>
[ 49.899371][ T5878] ---[ end trace 0000000000000000 ]---


To reproduce:

git clone https://github.com/intel/lkp-tests.git
cd lkp-tests
sudo bin/lkp install job.yaml # job file is attached in this email
bin/lkp split-job --compatible job.yaml # generate the yaml file for lkp run
sudo bin/lkp run generated-yaml-file

# if come across any failure that blocks the test,
# please remove ~/.lkp and /lkp dir to run from a clean state.


--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests


Attachments:
(No filename) (8.40 kB)
config-6.3.0-rc1-00033-g2fe2002efb23 (159.41 kB)
job-script (7.93 kB)
dmesg.xz (50.24 kB)
stress-ng (26.64 kB)
job.yaml (5.62 kB)
reproduce (350.00 B)
Download all attachments

2023-05-09 12:40:28

by Ajay Kaher

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs


> On 02/05/23, 11:42 PM, "kernel test robot" <[email protected]> wrote:
> >> kernel/trace/trace_events.c:2424:17: warning: variable 'd_events' set but not used [-Wunused-but-set-variable]
> struct dentry *d_events;
> ^
> 1 warning generated.
>

Steve, with-in event_create_dir(), do we have any scenario when file->event_call->class->system
doesn't have TRACE_SYSTEM? And need to execute following:

ae63b31e4d0e2e Steven Rostedt 2012-05-03 2437 d_events = parent;

looking for your input if we could remove d_events from event_create_dir().

- Ajay

> vim +/d_events +2424 kernel/trace/trace_events.c
>
> ac343da7bc9048 Masami Hiramatsu 2020-09-10 2417
> 1473e4417c79f1 Steven Rostedt 2009-02-24 2418 static int
> 7f1d2f8210195c Steven Rostedt (Red Hat 2015-05-05 2419) event_create_dir(struct dentry *parent, struct trace_event_file *file)
> 1473e4417c79f1 Steven Rostedt 2009-02-24 2420 {
> 2425bcb9240f8c Steven Rostedt (Red Hat 2015-05-05 2421) struct trace_event_call *call = file->event_call;
> ae63b31e4d0e2e Steven Rostedt 2012-05-03 2422 struct trace_array *tr = file->tr;
> 2fe2002efb23a7 Ajay Kaher 2023-05-02 2423 struct eventfs_file *ef_subsystem = NULL;
> ae63b31e4d0e2e Steven Rostedt 2012-05-03 @2424 struct dentry *d_events;
> de7b2973903c6c Mathieu Desnoyers 2014-04-08 2425 const char *name;
> fd99498989f3b3 Steven Rostedt 2009-02-28 2426 int ret;
> 1473e4417c79f1 Steven Rostedt 2009-02-24 2427
> 6ecc2d1ca39177 Steven Rostedt 2009-02-27 2428 /*
> 6ecc2d1ca39177 Steven Rostedt 2009-02-27 2429 * If the trace point header did not define TRACE_SYSTEM
> 6ecc2d1ca39177 Steven Rostedt 2009-02-27 2430 * then the system would be called "TRACE_SYSTEM".
> 6ecc2d1ca39177 Steven Rostedt 2009-02-27 2431 */
> ae63b31e4d0e2e Steven Rostedt 2012-05-03 2432 if (strcmp(call->class->system, TRACE_SYSTEM) != 0) {
> 2fe2002efb23a7 Ajay Kaher 2023-05-02 2433 ef_subsystem = event_subsystem_dir(tr, call->class->system, file, parent);
> 2fe2002efb23a7 Ajay Kaher 2023-05-02 2434 if (!ef_subsystem)
> ae63b31e4d0e2e Steven Rostedt 2012-05-03 2435 return -ENOMEM;
> ae63b31e4d0e2e Steven Rostedt 2012-05-03 2436 } else
> ae63b31e4d0e2e Steven Rostedt 2012-05-03 2437 d_events = parent;
> 6ecc2d1ca39177 Steven Rostedt 2009-02-27 2438
> 687fcc4aee4567 Steven Rostedt (Red Hat 2015-05-13 2439) name = trace_event_name(call);
> 2fe2002efb23a7 Ajay Kaher 2023-05-02 2440 file->ef = eventfs_add_dir(name, ef_subsystem, &tr->eventfs_rwsem);
> 2fe2002efb23a7 Ajay Kaher 2023-05-02 2441 if (IS_ERR(file->ef)) {
> 8434dc9340cd2e Steven Rostedt (Red Hat 2015-01-20 2442) pr_warn("Could not create tracefs '%s' directory\n", name);
> 1473e4417c79f1 Steven Rostedt 2009-02-24 2443 return -1;
> 1473e4417c79f1 Steven Rostedt 2009-02-24 2444 }
> 1473e4417c79f1 Steven Rostedt 2009-02-24 2445
> 9b63776fa3ca96 Steven Rostedt 2012-05-10 2446 if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
> 2fe2002efb23a7 Ajay Kaher 2023-05-02 2447 eventfs_add_file("enable", TRACE_MODE_WRITE, file->ef, file,
> 620a30e97febc8 Oleg Nesterov 2013-07-31 2448 &ftrace_enable_fops);
> 1473e4417c79f1 Steven Rostedt 2009-02-24 2449


2023-05-09 16:58:06

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

On Tue, 9 May 2023 12:29:23 +0000
Ajay Kaher <[email protected]> wrote:

> > On 02/05/23, 11:42 PM, "kernel test robot" <[email protected]> wrote:
> > >> kernel/trace/trace_events.c:2424:17: warning: variable 'd_events' set but not used [-Wunused-but-set-variable]
> > struct dentry *d_events;
> > ^
> > 1 warning generated.
> >
>
> Steve, with-in event_create_dir(), do we have any scenario when file->event_call->class->system
> doesn't have TRACE_SYSTEM? And need to execute following:
>
> ae63b31e4d0e2e Steven Rostedt 2012-05-03 2437 d_events = parent;
>
> looking for your input if we could remove d_events from event_create_dir().
>

I have hit this in the beginning, but I don't think it's an issue
anymore. Perhaps just have it be:

if (WARN_ON_ONCE(strcmp(call->class->system, TRACE_SYSTEM) == 0))
return -ENODEV;

ef_subsystem = event_subsystem_dir(tr, call->class->system, file, parent);

Hmm, how about just add this patch before your patch set:

-- Steve

From: "Steven Rostedt (Google)" <[email protected]>
Subject: [PATCH] tracing: Require all trace events to have a TRACE_SYSTEM

The creation of the trace event directory requires that a TRACE_SYSTEM is
defined that the trace event directory is added within the system it was
defined in.

The code handled the case where a TRACE_SYSTEM was not added, and would
then add the event at the events directory. But nothing should be doing
this. This code also prevents the implementation of creating dynamic
dentrys for the eventfs system.

As this path has never been hit on correct code, remove it. If it does get
hit, issues a WARN_ON_ONCE() and return ENODEV.

Signed-off-by: Steven Rostedt (Google) <[email protected]>
---

(lightly tested)

kernel/trace/trace_events.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 654ffa40457a..16bc5ba45507 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2424,14 +2424,15 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)

/*
* If the trace point header did not define TRACE_SYSTEM
- * then the system would be called "TRACE_SYSTEM".
+ * then the system would be called "TRACE_SYSTEM". This should
+ * never happen.
*/
- if (strcmp(call->class->system, TRACE_SYSTEM) != 0) {
- d_events = event_subsystem_dir(tr, call->class->system, file, parent);
- if (!d_events)
- return -ENOMEM;
- } else
- d_events = parent;
+ if (WARN_ON_ONCE(strcmp(call->class->system, TRACE_SYSTEM) == 0))
+ return -ENODEV;
+
+ d_events = event_subsystem_dir(tr, call->class->system, file, parent);
+ if (!d_events)
+ return -ENOMEM;

name = trace_event_name(call);
file->dir = tracefs_create_dir(name, d_events);
--
2.39.2

2023-05-10 11:22:18

by Ajay Kaher

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs



> On 09-May-2023, at 10:15 PM, Steven Rostedt <[email protected]> wrote:
>
> !! External Email
>
> On Tue, 9 May 2023 12:29:23 +0000
> Ajay Kaher <[email protected]> wrote:
>
>> > On 02/05/23, 11:42 PM, "kernel test robot" <[email protected]> wrote:
>>>>> kernel/trace/trace_events.c:2424:17: warning: variable 'd_events' set but not used [-Wunused-but-set-variable]
>>> struct dentry *d_events;
>>> ^
>>> 1 warning generated.
>>>
>>
>> Steve, with-in event_create_dir(), do we have any scenario when file->event_call->class->system
>> doesn't have TRACE_SYSTEM? And need to execute following:
>>
>> ae63b31e4d0e2e Steven Rostedt 2012-05-03 2437 d_events = parent;
>>
>> looking for your input if we could remove d_events from event_create_dir().
>>
>
> I have hit this in the beginning, but I don't think it's an issue
> anymore. Perhaps just have it be:
>
> if (WARN_ON_ONCE(strcmp(call->class->system, TRACE_SYSTEM) == 0))
> return -ENODEV;
>
> ef_subsystem = event_subsystem_dir(tr, call->class->system, file, parent);
>
> Hmm, how about just add this patch before your patch set:
>

Sounds good. Thanks Steve :)
Once you will merge below patch, I will rebase this patch in v3.

- Ajay

>
> From: "Steven Rostedt (Google)" <[email protected]>
> Subject: [PATCH] tracing: Require all trace events to have a TRACE_SYSTEM
>
> The creation of the trace event directory requires that a TRACE_SYSTEM is
> defined that the trace event directory is added within the system it was
> defined in.
>
> The code handled the case where a TRACE_SYSTEM was not added, and would
> then add the event at the events directory. But nothing should be doing
> this. This code also prevents the implementation of creating dynamic
> dentrys for the eventfs system.
>
> As this path has never been hit on correct code, remove it. If it does get
> hit, issues a WARN_ON_ONCE() and return ENODEV.
>
> Signed-off-by: Steven Rostedt (Google) <[email protected]>
> ---
>
> (lightly tested)
>
> kernel/trace/trace_events.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
> index 654ffa40457a..16bc5ba45507 100644
> --- a/kernel/trace/trace_events.c
> +++ b/kernel/trace/trace_events.c
> @@ -2424,14 +2424,15 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
>
> /*
> * If the trace point header did not define TRACE_SYSTEM
> - * then the system would be called "TRACE_SYSTEM".
> + * then the system would be called "TRACE_SYSTEM". This should
> + * never happen.
> */
> - if (strcmp(call->class->system, TRACE_SYSTEM) != 0) {
> - d_events = event_subsystem_dir(tr, call->class->system, file, parent);
> - if (!d_events)
> - return -ENOMEM;
> - } else
> - d_events = parent;
> + if (WARN_ON_ONCE(strcmp(call->class->system, TRACE_SYSTEM) == 0))
> + return -ENODEV;
> +
> + d_events = event_subsystem_dir(tr, call->class->system, file, parent);
> + if (!d_events)
> + return -ENOMEM;
>
> name = trace_event_name(call);
> file->dir = tracefs_create_dir(name, d_events);
> --
> 2.39.2
>
>
> !! External Email: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender.


2023-05-10 11:44:35

by Ajay Kaher

[permalink] [raw]
Subject: Re: [PATCH v2 2/9] eventfs: adding eventfs dir add functions



> On 08-May-2023, at 3:02 PM, Zheng Yejian <[email protected]> wrote:
>
> On 2023/5/2 19:23, Ajay Kaher wrote:
>> Adding eventfs_file structure which will hold properties of file or dir.
>>
>> Adding following functions to add dir in eventfs:
>>
>> eventfs_create_events_dir() will directly create events dir with-in
>> tracing folder.
>>
>> eventfs_add_subsystem_dir() will adds the info of subsystem_dir to
>> eventfs and dynamically create subsystem_dir as and when requires.
>>
>> eventfs_add_dir() will add the info of dir (which is with-in
>> subsystem_dir) to eventfs and dynamically create these dir as
>> and when requires.
>>
>> Signed-off-by: Ajay Kaher <[email protected]>
>> Co-developed-by: Steven Rostedt (VMware) <[email protected]>
>> Signed-off-by: Steven Rostedt (VMware) <[email protected]>
>> Tested-by: Ching-lin Yu <[email protected]>
>> ---
>> fs/tracefs/Makefile | 1 +
>> fs/tracefs/event_inode.c | 252 +++++++++++++++++++++++++++++++++++++++
>> include/linux/tracefs.h | 29 +++++
>> kernel/trace/trace.h | 1 +
>> 4 files changed, 283 insertions(+)
>> create mode 100644 fs/tracefs/event_inode.c
>>
>> diff --git a/fs/tracefs/Makefile b/fs/tracefs/Makefile
>> index 7c35a282b..73c56da8e 100644
>> --- a/fs/tracefs/Makefile
>> +++ b/fs/tracefs/Makefile
>> @@ -1,5 +1,6 @@
>> # SPDX-License-Identifier: GPL-2.0-only
>> tracefs-objs := inode.o
>> +tracefs-objs += event_inode.o
>>
>> obj-$(CONFIG_TRACING) += tracefs.o
>>
>> diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
>> new file mode 100644
>> index 000000000..82caba7e9
>> --- /dev/null
>> +++ b/fs/tracefs/event_inode.c
>> @@ -0,0 +1,252 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * event_inode.c - part of tracefs, a pseudo file system for activating tracing
>> + *
>> + * Copyright (C) 2020-22 VMware Inc, author: Steven Rostedt (VMware) <[email protected]>
>> + * Copyright (C) 2020-22 VMware Inc, author: Ajay Kaher <[email protected]>
>> + *
>> + * eventfs is used to show trace events with one set of dentries
>> + *
>> + * eventfs stores meta-data of files/dirs and skip to create object of
>> + * inodes/dentries. As and when requires, eventfs will create the
>> + * inodes/dentries for only required files/directories. Also eventfs
>> + * would delete the inodes/dentries once no more requires but preserve
>> + * the meta data.
>> + */
>> +#include <linux/fsnotify.h>
>> +#include <linux/fs.h>
>> +#include <linux/namei.h>
>> +#include <linux/security.h>
>> +#include <linux/tracefs.h>
>> +#include <linux/kref.h>
>> +#include <linux/delay.h>
>> +#include "internal.h"
>> +
>> +/**
>> + * eventfs_dentry_to_rwsem - Return corresponding eventfs_rwsem
>> + * @dentry: a pointer to dentry
>> + *
>> + * helper function to return crossponding eventfs_rwsem for given dentry
>> + */
>> +static struct rw_semaphore *eventfs_dentry_to_rwsem(struct dentry *dentry)
>> +{
>> + if (S_ISDIR(dentry->d_inode->i_mode))
>> + return (struct rw_semaphore *)dentry->d_inode->i_private;
>> + else
>> + return (struct rw_semaphore *)dentry->d_parent->d_inode->i_private;
>> +}
>> +
>> +/**
>> + * eventfs_down_read - acquire read lock function
>> + * @eventfs_rwsem: a pointer to rw_semaphore
>> + *
>> + * helper function to perform read lock, skip locking if caller task already
>> + * own the lock. read lock requires for lookup(), release() and these also
>> + * called with-in open(), remove() which already hold the read/write lock.
>> + */
>> +static void eventfs_down_read(struct rw_semaphore *eventfs_rwsem)
>> +{
>> + down_read_nested(eventfs_rwsem, SINGLE_DEPTH_NESTING);
>> +}
>> +
>> +/**
>> + * eventfs_up_read - release read lock function
>> + * @eventfs_rwsem: a pointer to rw_semaphore
>> + *
>> + * helper function to release eventfs_rwsem lock if locked
>> + */
>> +static void eventfs_up_read(struct rw_semaphore *eventfs_rwsem)
>> +{
>> + up_read(eventfs_rwsem);
>> +}
>> +
>> +/**
>> + * eventfs_down_write - acquire write lock function
>> + * @eventfs_rwsem: a pointer to rw_semaphore
>> + *
>> + * helper function to perform write lock on eventfs_rwsem
>> + */
>> +static void eventfs_down_write(struct rw_semaphore *eventfs_rwsem)
>> +{
>> + while (!down_write_trylock(eventfs_rwsem))
>> + msleep(10);
>> +}
>> +
>> +/**
>> + * eventfs_up_write - release write lock function
>> + * @eventfs_rwsem: a pointer to rw_semaphore
>> + *
>> + * helper function to perform write lock on eventfs_rwsem
>> + */
>> +static void eventfs_up_write(struct rw_semaphore *eventfs_rwsem)
>> +{
>> + up_write(eventfs_rwsem);
>> +}
>> +
>> +static const struct file_operations eventfs_file_operations = {
>> +};
>> +
>> +static const struct inode_operations eventfs_root_dir_inode_operations = {
>> +};
>> +
>> +/**
>> + * eventfs_create_events_dir - create the trace event structure
>> + * @name: a pointer to a string containing the name of the directory to
>> + * create.
>> + * @parent: a pointer to the parent dentry for this file. This should be a
>> + * directory dentry if set. If this parameter is NULL, then the
>> + * directory will be created in the root of the tracefs filesystem.
>> + * @eventfs_rwsem: a pointer to rw_semaphore
>> + *
>> + * This function creates the top of the trace event directory.
>> + */
>> +struct dentry *eventfs_create_events_dir(const char *name,
>> + struct dentry *parent,
>> + struct rw_semaphore *eventfs_rwsem)
>> +{
>> + struct dentry *dentry = tracefs_start_creating(name, parent);
>> + struct eventfs_inode *ei;
>> + struct tracefs_inode *ti;
>> + struct inode *inode;
>> +
>> + if (IS_ERR(dentry))
>> + return dentry;
>> +
>> + ei = kzalloc(sizeof(*ei), GFP_KERNEL);
>> + if (!ei)
>> + return ERR_PTR(-ENOMEM);
>> + inode = tracefs_get_inode(dentry->d_sb);
>> + if (unlikely(!inode)) {
>> + kfree(ei);
>> + tracefs_failed_creating(dentry);
>> + return ERR_PTR(-ENOMEM);
>> + }
>> +
>> + init_rwsem(eventfs_rwsem);
>> + INIT_LIST_HEAD(&ei->e_top_files);
>> +
>> + ti = get_tracefs(inode);
>> + ti->flags |= TRACEFS_EVENT_INODE;
>> + ti->private = ei;
>> +
>> + inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
>> + inode->i_op = &eventfs_root_dir_inode_operations;
>> + inode->i_fop = &eventfs_file_operations;
>> + inode->i_private = eventfs_rwsem;
>> +
>> + /* directory inodes start off with i_nlink == 2 (for "." entry) */
>> + inc_nlink(inode);
>> + d_instantiate(dentry, inode);
>> + inc_nlink(dentry->d_parent->d_inode);
>> + fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
>> + return tracefs_end_creating(dentry);
>> +}
>> +
>> +/**
>> + * eventfs_add_subsystem_dir - add eventfs subsystem_dir to list to create later
>> + * @name: a pointer to a string containing the name of the file to create.
>> + * @parent: a pointer to the parent dentry for this dir.
>> + * @eventfs_rwsem: a pointer to rw_semaphore
>> + *
>> + * This function adds eventfs subsystem dir to list.
>> + * And all these dirs are created on the fly when they are looked up,
>> + * and the dentry and inodes will be removed when they are done.
>> + */
>> +struct eventfs_file *eventfs_add_subsystem_dir(const char *name,
>> + struct dentry *parent,
>> + struct rw_semaphore *eventfs_rwsem)
>> +{
>> + struct tracefs_inode *ti_parent;
>> + struct eventfs_inode *ei_parent;
>> + struct eventfs_file *ef;
>> +
>> + if (!parent)
>> + return ERR_PTR(-EINVAL);
>> +
>> + ti_parent = get_tracefs(parent->d_inode);
>> + ei_parent = ti_parent->private;
>> +
>> + ef = kzalloc(sizeof(*ef), GFP_KERNEL);
>> + if (!ef)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + ef->ei = kzalloc(sizeof(*ef->ei), GFP_KERNEL);
>> + if (!ef->ei) {
>> + kfree(ef);
>> + return ERR_PTR(-ENOMEM);
>> + }
>> +
>> + INIT_LIST_HEAD(&ef->ei->e_top_files);
>> +
>> + ef->name = kstrdup(name, GFP_KERNEL);
>> + if (!ef->name) {
>> + kfree(ef->ei);
>> + kfree(ef);
>> + return ERR_PTR(-ENOMEM);
>> + }
>> +
>> + ef->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
>> + ef->iop = &eventfs_root_dir_inode_operations;
>> + ef->fop = &eventfs_file_operations;
>> + ef->dentry = NULL;
>> + ef->created = false;
>> + ef->d_parent = parent;
>> + ef->data = eventfs_rwsem;
>> +
>> + eventfs_down_write(eventfs_rwsem);
>> + list_add_tail(&ef->list, &ei_parent->e_top_files);
>> + eventfs_up_write(eventfs_rwsem);
>> + return ef;
>> +}
>> +
>> +/**
>> + * eventfs_add_dir - add eventfs dir to list to create later
>> + * @name: a pointer to a string containing the name of the file to create.
>> + * @ef_parent: a pointer to the parent eventfs_file for this dir.
>> + * @eventfs_rwsem: a pointer to rw_semaphore
>> + *
>> + * This function adds eventfs dir to list.
>> + * And all these dirs are created on the fly when they are looked up,
>> + * and the dentry and inodes will be removed when they are done.
>> + */
>> +struct eventfs_file *eventfs_add_dir(const char *name,
>> + struct eventfs_file *ef_parent,
>> + struct rw_semaphore *eventfs_rwsem)
>> +{
>> + struct eventfs_file *ef;
>> +
>> + if (!ef_parent)
>> + return ERR_PTR(-EINVAL);
>> +
>> + ef = kzalloc(sizeof(*ef), GFP_KERNEL);
>> + if (!ef)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + ef->ei = kzalloc(sizeof(*ef->ei), GFP_KERNEL);
>> + if (!ef->ei) {
>> + kfree(ef);
>> + return ERR_PTR(-ENOMEM);
>> + }
>> +
>> + INIT_LIST_HEAD(&ef->ei->e_top_files);
>> +
>> + ef->name = kstrdup(name, GFP_KERNEL);
>> + if (!ef->name) {
>> + kfree(ef->ei);
>> + kfree(ef);
>> + return ERR_PTR(-ENOMEM);
>> + }
>> +
>> + ef->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
>> + ef->iop = &eventfs_root_dir_inode_operations;
>> + ef->fop = &eventfs_file_operations;
>> + ef->created = false;
>> + ef->dentry = NULL;
>> + ef->d_parent = NULL;
>> + ef->data = eventfs_rwsem;
>> +
>> + eventfs_down_write(eventfs_rwsem);
>> + list_add_tail(&ef->list, &ef_parent->ei->e_top_files);
>> + eventfs_up_write(eventfs_rwsem);
>> + return ef;
>> +}
>
> Hi,
> eventfs_add_subsystem_dir() and eventfs_add_dir() are almost the same,
> how about extract a common help function to simplify them, like:
>
> +static struct eventfs_file *__eventfs_add_dir(const char *name,
> + struct dentry *d_parent,
> + struct eventfs_inode
> *ei_parent,
> + struct rw_semaphore
> *eventfs_rwsem)
> +{
> + struct eventfs_file *ef;
> +
> + ef = kzalloc(sizeof(*ef), GFP_KERNEL);
> + if (!ef)
> + return ERR_PTR(-ENOMEM);
> +
> + ef->ei = kzalloc(sizeof(*ef->ei), GFP_KERNEL);
> + if (!ef->ei) {
> + kfree(ef);
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + INIT_LIST_HEAD(&ef->ei->e_top_files);
> +
> + ef->name = kstrdup(name, GFP_KERNEL);
> + if (!ef->name) {
> + kfree(ef->ei);
> + kfree(ef);
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + ef->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
> + ef->iop = &eventfs_root_dir_inode_operations;
> + ef->fop = &eventfs_file_operations;
> + ef->dentry = NULL;
> + ef->created = false;
> + ef->d_parent = d_parent;
> + ef->data = eventfs_rwsem;
> +
> + eventfs_down_write(eventfs_rwsem);
> + list_add_tail(&ef->list, &ei_parent->e_top_files);
> + eventfs_up_write(eventfs_rwsem);
> + return ef;
> +}
> +
> +struct eventfs_file *eventfs_add_subsystem_dir(const char *name,
> + struct dentry *parent,
> + struct rw_semaphore
> *eventfs_rwsem)
> +{
> + struct tracefs_inode *ti_parent;
> + struct eventfs_inode *ei_parent;
> +
> + if (!parent)
> + return ERR_PTR(-EINVAL);
> + ti_parent = get_tracefs(parent->d_inode);
> + ei_parent = ti_parent->private;
> + return __eventfs_add_dir(name, parent, ei_parent, eventfs_rwsem);
> +}
> +
> +struct eventfs_file *eventfs_add_dir(const char *name,
> + struct eventfs_file *ef_parent,
> + struct rw_semaphore *eventfs_rwsem)
> +{
> + if (!ef_parent)
> + return ERR_PTR(-EINVAL);
> + return __eventfs_add_dir(name, NULL, ef_parent->ei, eventfs_rwsem);
> +}

Sounds good. Thanks for sharing code snippet. I will consider in v3.

- Ajay

>> diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
>> index 999124459..aeca6761f 100644
>> --- a/include/linux/tracefs.h
>> +++ b/include/linux/tracefs.h
>> @@ -21,6 +21,35 @@ struct file_operations;
>>
>> #ifdef CONFIG_TRACING
>>
>> +struct eventfs_inode {
>> + struct list_head e_top_files;
>> +};
>> +
>> +struct eventfs_file {
>> + const char *name;
>> + struct dentry *d_parent;
>> + struct dentry *dentry;
>> + struct list_head list;
>> + struct eventfs_inode *ei;
>> + const struct file_operations *fop;
>> + const struct inode_operations *iop;
>> + void *data;
>> + umode_t mode;
>> + bool created;
>> +};
>> +
>> +struct dentry *eventfs_create_events_dir(const char *name,
>> + struct dentry *parent,
>> + struct rw_semaphore *eventfs_rwsem);
>> +
>> +struct eventfs_file *eventfs_add_subsystem_dir(const char *name,
>> + struct dentry *parent,
>> + struct rw_semaphore *eventfs_rwsem);
>> +
>> +struct eventfs_file *eventfs_add_dir(const char *name,
>> + struct eventfs_file *ef_parent,
>> + struct rw_semaphore *eventfs_rwsem);
>> +
>> struct dentry *tracefs_create_file(const char *name, umode_t mode,
>> struct dentry *parent, void *data,
>> const struct file_operations *fops);
>> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
>> index 616e1aa1c..3726725c8 100644
>> --- a/kernel/trace/trace.h
>> +++ b/kernel/trace/trace.h
>> @@ -359,6 +359,7 @@ struct trace_array {
>> struct dentry *options;
>> struct dentry *percpu_dir;
>> struct dentry *event_dir;
>> + struct rw_semaphore eventfs_rwsem;
>> struct trace_options *topts;
>> struct list_head systems;
>> struct list_head events;



2023-05-12 23:01:23

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

On Wed, 10 May 2023 11:11:15 +0000
Ajay Kaher <[email protected]> wrote:

> Sounds good. Thanks Steve :)
> Once you will merge below patch, I will rebase this patch in v3.

Feel free to just add it at the start of your queue. You just need to
keep the "From" line and it will be added as my patch.

-- Steve

2023-05-15 11:54:45

by Ajay Kaher

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs



> On 13-May-2023, at 4:29 AM, Steven Rostedt <[email protected]> wrote:
>
> !! External Email
>
> On Wed, 10 May 2023 11:11:15 +0000
> Ajay Kaher <[email protected]> wrote:
>
>> Sounds good. Thanks Steve :)
>> Once you will merge below patch, I will rebase this patch in v3.
>
> Feel free to just add it at the start of your queue. You just need to
> keep the "From" line and it will be added as my patch.

Ok, I will include in v3.

-Ajay

2023-05-17 12:47:02

by Ajay Kaher

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

> kernel test robot noticed "WARNING:at_fs/namei.c:#lookup_one_len" on:
>
> commit: 2fe2002efb23a715f5eb7a58891ff85f4e37b084 ("[PATCH v2 8/9] eventfs: moving tracing/events to eventfs")
> url: https://github.com/intel-lab-lkp/linux/commits/Ajay-Kaher/eventfs-introducing-struct-tracefs_inode/20230502-192949
> base: https://git.kernel.org/cgit/linux/kernel/git/shuah/linux-kselftest.git next
> patch link: https://lore.kernel.org/all/[email protected]/
> patch subject: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs
.
.
.
> 49.752082][ T5878] eventfs_start_creating (fs/tracefs/inode.c:519)
> [ 49.757416][ T5878] eventfs_create_dir (fs/tracefs/event_inode.c:187 (discriminator 3))
> [ 49.762488][ T5878] eventfs_root_lookup (fs/tracefs/event_inode.c:291)
> [ 49.767637][ T5878] __lookup_slow (fs/namei.c:1686)
> [ 49.772268][ T5878] walk_component (include/linux/fs.h:773 fs/namei.c:1704 fs/namei.c:1994)
> [ 49.777016][ T5878] link_path_walk+0x24e/0x3b0
> [ 49.783462][ T5878] ? path_init (fs/namei.c:2387)
> [ 49.788021][ T5878] path_openat (fs/namei.c:3711)
> [ 49.792463][ T5878] do_filp_open (fs/namei.c:3742)
> [ 49.797021][ T5878] ? __check_object_size (mm/memremap.c:107 mm/memremap.c:144)
> [ 49.803055][ T5878] do_sys_openat2 (fs/open.c:1348)
> [ 49.807740][ T5878] __x64_sys_openat (fs/open.c:1375)
> [ 49.812512][ T5878] do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80)
> [ 49.817068][ T5878] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)
> [ 49.823092][ T5878] RIP: 0033:0x7fcddb3b84e7

Steve, locally I have reproduced this issue using:
lkp run job-cpu-100%-uprobe-60s.yaml

And also fixed, I will include this fix as well in v3.

Thanks to lkp, kernel test robot <[email protected]>.

-Ajay


2023-05-17 14:17:29

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH v2 8/9] eventfs: moving tracing/events to eventfs

On Wed, 17 May 2023 18:10:07 +0530
Ajay Kaher <[email protected]> wrote:

> Steve, locally I have reproduced this issue using:
> lkp run job-cpu-100%-uprobe-60s.yaml
>
> And also fixed, I will include this fix as well in v3.

Great. Thanks Ajay!

-- Steve

2023-06-19 05:39:54

by Ajay Kaher

[permalink] [raw]
Subject: Re: [PATCH v2 2/9] eventfs: adding eventfs dir add functions



> On 10-May-2023, at 4:55 PM, Ajay Kaher <[email protected]> wrote:
>>
>> Hi,
>> eventfs_add_subsystem_dir() and eventfs_add_dir() are almost the same,
>> how about extract a common help function to simplify them, like:
>>
>> +static struct eventfs_file *__eventfs_add_dir(const char *name,
>> + struct dentry *d_parent,
>> + struct eventfs_inode
>> *ei_parent,
>> + struct rw_semaphore
>> *eventfs_rwsem)
>> +{
>> + struct eventfs_file *ef;
>> +
>> + ef = kzalloc(sizeof(*ef), GFP_KERNEL);
>> + if (!ef)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + ef->ei = kzalloc(sizeof(*ef->ei), GFP_KERNEL);
>> + if (!ef->ei) {
>> + kfree(ef);
>> + return ERR_PTR(-ENOMEM);
>> + }
>> +
>> + INIT_LIST_HEAD(&ef->ei->e_top_files);
>> +
>> + ef->name = kstrdup(name, GFP_KERNEL);
>> + if (!ef->name) {
>> + kfree(ef->ei);
>> + kfree(ef);
>> + return ERR_PTR(-ENOMEM);
>> + }
>> +
>> + ef->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
>> + ef->iop = &eventfs_root_dir_inode_operations;
>> + ef->fop = &eventfs_file_operations;
>> + ef->dentry = NULL;
>> + ef->created = false;
>> + ef->d_parent = d_parent;
>> + ef->data = eventfs_rwsem;
>> +
>> + eventfs_down_write(eventfs_rwsem);
>> + list_add_tail(&ef->list, &ei_parent->e_top_files);
>> + eventfs_up_write(eventfs_rwsem);
>> + return ef;
>> +}
>> +
>> +struct eventfs_file *eventfs_add_subsystem_dir(const char *name,
>> + struct dentry *parent,
>> + struct rw_semaphore
>> *eventfs_rwsem)
>> +{
>> + struct tracefs_inode *ti_parent;
>> + struct eventfs_inode *ei_parent;
>> +
>> + if (!parent)
>> + return ERR_PTR(-EINVAL);
>> + ti_parent = get_tracefs(parent->d_inode);
>> + ei_parent = ti_parent->private;
>> + return __eventfs_add_dir(name, parent, ei_parent, eventfs_rwsem);
>> +}
>> +
>> +struct eventfs_file *eventfs_add_dir(const char *name,
>> + struct eventfs_file *ef_parent,
>> + struct rw_semaphore *eventfs_rwsem)
>> +{
>> + if (!ef_parent)
>> + return ERR_PTR(-EINVAL);
>> + return __eventfs_add_dir(name, NULL, ef_parent->ei, eventfs_rwsem);
>> +}
>
> Sounds good. Thanks for sharing code snippet. I will consider in v3.
>

Hi Zheng, I have moved common code to eventfs_prepare_ef() in v3 3/10, 4/10:
https://lore.kernel.org/all/[email protected]/

-Ajay