[PATCH v2 1/2] srcu: Add list_splice_init_srcu()

Paul E. McKenney paulmck at kernel.org
Wed Nov 4 17:44:08 PST 2026


On Wed, Nov 04, 2026 at 08:22:42PM -0500, Qiliang Yuan wrote:
> On Wed, Nov 04, 2026 at 09:14:12AM -0800, Paul E. McKenney wrote:
> > I am not inalterably opposed to adding a list_splice_init_srcu(),
> > especially if quite a few more users show up, but here is what I was
> > expecting people to do:
> >
> > 	static void synchronize_my_srcu(void)
> > 	{
> > 		synchronize_srcu(&my_srcu);
> > 	}
> >
> > 	...
> >
> > 	list_splice_init_rcu(l, h, synchronize_my_srcu);
> >
> > We need at least six uses of the above idiom to break even on the line
> > of code required for introducing a list_splice_init_srcu().
> 
> That works for a global srcu_struct, but nvme has one per controller,
> next to the list it protects:
> 
> 	struct nvme_ctrl {
> 		...
> 		struct list_head namespaces;
> 		struct mutex namespaces_lock;
> 		struct srcu_struct srcu;
> 		...
> 	};
> 
> nvme_init_ctrl() calls init_srcu_struct(&ctrl->srcu) for every
> controller, and readers walk the list under that controller's srcu,
> e.g. nvme_wait_freeze():
> 
> 	srcu_idx = srcu_read_lock(&ctrl->srcu);
> 	list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
> 				 srcu_read_lock_held(&ctrl->srcu))
> 		blk_mq_freeze_queue_wait(ns->queue);
> 	srcu_read_unlock(&ctrl->srcu, srcu_idx);
> 
> nvme_remove_namespaces() thus has to wait on the srcu of the controller
> being deleted, which a sync function that takes no argument can't get
> at.
> 
> So the choice here is between list_splice_init_srcu(), as Christoph
> suggested on v1, and open-coding the splice in nvme_remove_namespaces()
> as v1 did. Which would you prefer?

Sigh!  I hereby withdraw all objections to list_splice_init_srcu(),
and thank you for bearing with me.

(Yes, you could squirrel away a pointer to the srcu_struct structure
in the task_struct structure or some such, but that cure is worse than
the disease.)

							Thanx, Paul



More information about the Linux-nvme mailing list