On 07.08.24 15:44, Al Viro wrote: > 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()).
Jepp, sounds much better indeed and doesn't require 'struct tracefs_inode' to have its own 'struct rcu_head' member. Thanks, Mathias