[PATCH] nvme: fix SRCU protection of nvme_ns_head list

Caleb Sander csander at purestorage.com
Mon Nov 21 09:48:31 PST 2022


On Sun, Nov 20, 2022 at 11:40 PM Christoph Hellwig <hch at lst.de> wrote:
>
> On Sun, Nov 20, 2022 at 01:24:51PM +0200, Sagi Grimberg wrote:
> >>      sector_t capacity = get_capacity(head->disk);
> >>      int node;
> >> +    int srcu_idx;
> >>   +  srcu_idx = srcu_read_lock(&head->srcu);
> >>      list_for_each_entry_rcu(ns, &head->list, siblings) {
> >>              if (capacity != get_capacity(ns->disk))
> >>                      clear_bit(NVME_NS_READY, &ns->flags);
> >>      }
> >> +    srcu_read_unlock(&head->srcu, srcu_idx);
> >
> > I don't think you need srcu here, rcu_read_lock/unlock is sufficient.
>
> So the code obviously does not sleep.  But I wonder if anything speaks
> against mixing SRCU and RCU protection for the same list?

As I understand, synchronize_rcu() only synchronizes with RCU critical sections,
and likewise synchronize_srcu() only synchronizes with SRCU critical sections.
Currently nvme_ns_head_submit_bio() is using srcu_read_lock()
but nvme_ns_remove() is using synchronize_rcu(),
so there is no synchronization at all.
Since nvme_ns_head_submit_bio() sleeps during the critical section,
we definitely need to keep using SRCU there,
and therefore nvme_ns_remove() needs to use synchronize_srcu().
I agree RCU would work in nvme_mpath_revalidate_paths(), but as Paul points out,
nvme_ns_remove() would then need to synchronize with both SRCU and RCU.
This seems like it would complicate nvme_ns_remove()
and require waiting on readers of unrelated RCU-protected structures.
Is there some cost to using SRCU over RCU that I am missing?

Thanks,
Caleb



More information about the Linux-nvme mailing list