FAILED: patch "[PATCH] eventfs: Use list_add_tail_rcu() for SRCU-protected children" failed to apply to 7.0-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 7.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.0.y
git checkout FETCH_HEAD
git cherry-pick -x f67950b2887fa10df50c4317a1fe98a65bc6875b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026051232-clapped-algebra-8969@gregkh' --subject-prefix 'PATCH 7.0.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f67950b2887fa10df50c4317a1fe98a65bc6875b Mon Sep 17 00:00:00 2001
From: David Carlier <[email protected]>
Date: Sat, 18 Apr 2026 16:22:50 +0100
Subject: [PATCH] eventfs: Use list_add_tail_rcu() for SRCU-protected children
list
Commit d2603279c7d6 ("eventfs: Use list_del_rcu() for SRCU protected list variable") converted the removal side to pair with the list_for_each_entry_srcu() walker in eventfs_iterate(). The insertion in eventfs_create_dir() was left as a plain list_add_tail(), which on weakly-ordered architectures can expose a new entry to the SRCU reader before its list pointers and fields are observable.
Use list_add_tail_rcu() so the publication pairs with the existing list_del_rcu() and list_for_each_entry_srcu().
fs/tracefs/event_inode.c +1 -1
@@ -706,7 +706,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode scoped_guard(mutex, &eventfs_mutex) {if (!parent->is_freed) -list_add_tail (&ei->list, &parent->children); +list_add_tail_rcu (&ei->list, &parent->children); }/* Was the parent freed? */ if (list_empty (&ei->list)) {
Sasha Levin
maintainerPATCH 1/2 eventfs: Simplify code using guard()s
From: Steven Rostedt <[email protected]>
[ Upstream commit 4d9b262031ffef203243e53577a90ae6e1090e67 ]
Use guard(mutex), scoped_guard(mutex) and guard(src) to simplify the code and remove a lot of the jumps to "out:" labels.
Stable-dep-of: f67950b2887f ("eventfs: Use list_add_tail_rcu() for SRCU-protected children list")
--- fs/tracefs/event_inode.c | 96 +++++++++++++++------------------------- 1 file changed, 36 insertions(+), 60 deletions(-)
fs/tracefs/event_inode.c +36 -60
@@ -180,29 +180,25 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,const char *name;int ret; -mutex_lock (&eventfs_mutex); +guard (mutex)(&eventfs_mutex); ei = dentry->d_fsdata; -if (ei->is_freed) { -/* Do not allow changes if the event is about to be removed. */ -mutex_unlock (&eventfs_mutex); +/* Do not allow changes if the event is about to be removed. */ +if (ei->is_freed)return -ENODEV ; - }/* Preallocate the children mode array if necessary */ if (!(dentry->d_inode->i_mode &S_IFDIR )) {if (!ei->entry_attrs) { ei->entry_attrs =kzalloc_objs (*ei->entry_attrs, ei->nr_entries,GFP_NOFS ); -if (!ei->entry_attrs) { - ret = -ENOMEM ; - goto out; - } +if (!ei->entry_attrs) +return -ENOMEM ; } } ret =simple_setattr (idmap, dentry, iattr);if (ret <0 ) - goto out; +return ret;/* * If this is a dir, then update the ei cache, only the file
@@ -225,8 +221,6 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry, } } } - out: -mutex_unlock (&eventfs_mutex);return ret; }
@@ -530,26 +524,24 @@ static struct dentry *eventfs_root_lookup(struct inode *dir,struct tracefs_inode *ti;struct eventfs_inode *ei;const char *name = dentry->d_name.name; -struct dentry *result =NULL ; ti =get_tracefs (dir);if (WARN_ON_ONCE (!(ti->flags &TRACEFS_EVENT_INODE )))return ERR_PTR (-EIO ); -mutex_lock (&eventfs_mutex); +guard (mutex)(&eventfs_mutex); ei = ti->private;if (!ei || ei->is_freed) - goto out; +return NULL ;list_for_each_entry (ei_child, &ei->children, list) {if (strcmp (ei_child->name, name) !=0 )continue ;/* A child is freed and removed from the list at the same time */ if (WARN_ON_ONCE (ei_child->is_freed)) - goto out; - result =lookup_dir_entry (dentry, ei, ei_child); - goto out; +return NULL ; +return lookup_dir_entry (dentry, ei, ei_child); }for (int i =0 ; i < ei->nr_entries; i++) {
@@ -563,14 +555,12 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, data = ei->data;if (entry->callback (name, &mode, &data, &fops) <=0 ) - goto out; +return NULL ; + +return lookup_file_dentry (dentry, ei, i, mode, data, fops); - result =lookup_file_dentry (dentry, ei, i, mode, data, fops); - goto out; } - out: -mutex_unlock (&eventfs_mutex); -return result; +return NULL ; }/*
@@ -586,7 +576,6 @@ static int eventfs_iterate(struct file *file, struct dir_context *ctx)struct eventfs_inode *ei;const char *name;umode_t mode; -int idx;int ret = -EINVAL ;int ino;int i, r, c;
@@ -600,16 +589,13 @@ static int eventfs_iterate(struct file *file, struct dir_context *ctx) c = ctx->pos -2 ; - idx =srcu_read_lock (&eventfs_srcu); - -mutex_lock (&eventfs_mutex); - ei =READ_ONCE (ti->private); -if (ei && ei->is_freed) - ei =NULL ; -mutex_unlock (&eventfs_mutex); +guard (srcu)(&eventfs_srcu); -if (!ei) - goto out; + scoped_guard(mutex, &eventfs_mutex) { + ei =READ_ONCE (ti->private); +if (!ei || ei->is_freed) +return -EINVAL ; + }/* * Need to create the dentries and inodes to have a consistent
@@ -624,21 +610,19 @@ static int eventfs_iterate(struct file *file, struct dir_context *ctx) entry = &ei->entries[i]; name = entry->name; -mutex_lock (&eventfs_mutex);/* If ei->is_freed then just bail here, nothing more to do */ -if (ei->is_freed) { -mutex_unlock (&eventfs_mutex); - goto out; + scoped_guard(mutex, &eventfs_mutex) { +if (ei->is_freed) +return -EINVAL ; + r = entry->callback (name, &mode, &cdata, &fops); } - r = entry->callback (name, &mode, &cdata, &fops); -mutex_unlock (&eventfs_mutex);if (r <=0 )continue ; ino =EVENTFS_FILE_INODE_INO ;if (!dir_emit (ctx, name,strlen (name), ino,DT_REG )) - goto out; +return -EINVAL ; }/* Subtract the skipped entries above */
@@ -661,19 +645,13 @@ static int eventfs_iterate(struct file *file, struct dir_context *ctx) ino =eventfs_dir_ino (ei_child); -if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) - goto out_dec; +if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) { +/* Incremented ctx->pos without adding something, reset it */ + ctx->pos--; +return -EINVAL ; + } } - ret =1 ; - out: -srcu_read_unlock (&eventfs_srcu, idx); - -return ret; - - out_dec: -/* Incremented ctx->pos without adding something, reset it */ - ctx->pos--; - goto out; +return 1 ; }/**
@@ -730,11 +708,10 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inodeINIT_LIST_HEAD (&ei->children);INIT_LIST_HEAD (&ei->list); -mutex_lock (&eventfs_mutex); -if (!parent->is_freed) -list_add_tail (&ei->list, &parent->children); -mutex_unlock (&eventfs_mutex); - + scoped_guard(mutex, &eventfs_mutex) { +if (!parent->is_freed) +list_add_tail (&ei->list, &parent->children); + }/* Was the parent freed? */ if (list_empty (&ei->list)) {cleanup_ei (ei);
@@ -880,9 +857,8 @@ void eventfs_remove_dir(struct eventfs_inode *ei)if (!ei)return ; -mutex_lock (&eventfs_mutex); +guard (mutex)(&eventfs_mutex);eventfs_remove_rec (ei,0 ); -mutex_unlock (&eventfs_mutex); }/**
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 eventfs: Use list_add_tail_rcu() for SRCU-protected children list
From: David Carlier <[email protected]>
[ Upstream commit f67950b2887fa10df50c4317a1fe98a65bc6875b ]
Commit d2603279c7d6 ("eventfs: Use list_del_rcu() for SRCU protected list variable") converted the removal side to pair with the list_for_each_entry_srcu() walker in eventfs_iterate(). The insertion in eventfs_create_dir() was left as a plain list_add_tail(), which on weakly-ordered architectures can expose a new entry to the SRCU reader before its list pointers and fields are observable.
Use list_add_tail_rcu() so the publication pairs with the existing list_del_rcu() and list_for_each_entry_srcu().
--- fs/tracefs/event_inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/tracefs/event_inode.c +1 -1
@@ -710,7 +710,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode scoped_guard(mutex, &eventfs_mutex) {if (!parent->is_freed) -list_add_tail (&ei->list, &parent->children); +list_add_tail_rcu (&ei->list, &parent->children); }/* Was the parent freed? */ if (list_empty (&ei->list)) {
Signature · 1 line
2.53.0