[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