On Wed, Aug 07, 2024 at 09:35:45AM -0400, Steven Rostedt wrote: > Perhaps: > > diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h > index f704d8348357..ab6d6c3d835d 100644 > --- a/fs/tracefs/internal.h > +++ b/fs/tracefs/internal.h > @@ -10,12 +10,12 @@ enum { > }; > > struct tracefs_inode { > + struct inode vfs_inode; > + /* The below gets initialized with memset_after(ti, 0, vfs_inode) */ > union { > - struct inode vfs_inode; > + struct list_head list; > struct rcu_head rcu; > }; > - /* The below gets initialized with memset_after(ti, 0, vfs_inode) */ > - struct list_head list; > unsigned long flags; > void *private; > };
Your current variant gives you an RCU-delayed call of tracefs_free_inode(), which schedules an RCU-delayed call of tracefs_free_inode_rcu(). Do you really need that double RCU delay to start with? Because if you do not, just do that list_del_rcu() in ->destroy_inode() (which is called without an RCU delay) and have kmem_cache_free() in ->free_inode() (which is called *with* RCU delay started after the call of ->destroy_inode()).