[PATCH v2 1/2] srcu: Add list_splice_init_srcu()
Qiliang Yuan
odys.yuan at gmail.com
Wed Nov 4 17:22:42 PST 2026
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?
Thanks,
Qiliang
More information about the Linux-nvme
mailing list