Re: [PATCH 1/2] nvme: fix racy access to FDP placement ID array
Hari Mishal <[email protected]> Wed, 29 Jul 2026 13:47:47 +0200
| Newsgroups | org.infradead.lists.linux-nvme,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAMmC+=ApjmaGpnsxYBo7C-0BsROWJ=ffDc9FQSs9fn4wr7Amxg@mail.gmail.com> |
Hi Kanchan, I think your patch does solve all the problems. Should I resubmit the patch as a V2 or a new one? Cheers, Hari On Mon, Jul 27, 2026 at 4:22 PM Kanchan Joshi <[email protected]> wrote: > > Hari, > > Can you please try this patch and see if this solves what you saw? > > drivers/nvme/host/core.c | 38 +++++++++++++++++--------------------- > drivers/nvme/host/nvme.h | 1 + > 2 files changed, 18 insertions(+), 21 deletions(-) > > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c > index 453c1f0b2dd0..09cb22f6509c 100644 > --- a/drivers/nvme/host/core.c > +++ b/drivers/nvme/host/core.c > @@ -2320,14 +2320,6 @@ static int nvme_query_fdp_info(struct nvme_ns > *ns, struct nvme_ns_info *info) > size_t size; > int i, ret; > > - /* > - * The FDP configuration is static for the lifetime of the > namespace, > - * so return immediately if we've already registered this > namespace's > - * streams. > - */ > - if (head->nr_plids) > - return 0; > - > ret = nvme_get_features(ctrl, NVME_FEAT_FDP, info->endgid, NULL, 0, > &fdp); > if (ret) { > @@ -2374,6 +2366,7 @@ static int nvme_query_fdp_info(struct nvme_ns *ns, > struct nvme_ns_info *info) > > for (i = 0; i < head->nr_plids; i++) > head->plids[i] = le16_to_cpu(ruhs->ruhsd[i].pid); > + head->write_stream_granularity = min(info->runs, U32_MAX); > free: > kfree(ruhs); > return ret; > @@ -2421,12 +2414,6 @@ static int nvme_update_ns_info_block(struct > nvme_ns *ns, > goto out; > } > > - if (ns->ctrl->ctratt & NVME_CTRL_ATTR_FDPS) { > - ret = nvme_query_fdp_info(ns, info); > - if (ret < 0) > - goto out; > - } > - > if (nvme_invalid_lba_sz(le64_to_cpu(id->nsze), > id->lbaf[lbaf].ds - SECTOR_SHIFT, &capacity)) { > dev_warn_once(ns->ctrl->device, > @@ -2469,10 +2456,7 @@ static int nvme_update_ns_info_block(struct > nvme_ns *ns, > capacity = 0; > > lim.max_write_streams = ns->head->nr_plids; > - if (lim.max_write_streams) > - lim.write_stream_granularity = min(info->runs, U32_MAX); > - else > - lim.write_stream_granularity = 0; > + lim.write_stream_granularity = ns->head->write_stream_granularity; > > /* > * Only set the DEAC bit if the device guarantees that reads from > @@ -3964,9 +3948,10 @@ static void nvme_add_ns_cdev(struct nvme_ns *ns) > set_bit(NVME_NS_CDEV_LIVE, &ns->flags); > } > > -static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl, > +static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ns *ns, > struct nvme_ns_info *info) > { > + struct nvme_ctrl *ctrl = ns->ctrl; > struct nvme_ns_head *head; > size_t size = sizeof(*head); > int ret = -ENOMEM; > @@ -4002,15 +3987,26 @@ static struct nvme_ns_head > *nvme_alloc_ns_head(struct nvme_ctrl *ctrl, > } else > head->effects = ctrl->effects; > > + if (ctrl->ctratt & NVME_CTRL_ATTR_FDPS) { > + ns->head = head; > + ret = nvme_query_fdp_info(ns, info); > + if (ret < 0) > + goto out_clear_ns_head; > + } > + > ret = nvme_mpath_alloc_disk(ctrl, head); > if (ret) > - goto out_cleanup_srcu; > + goto out_cleanup_fdp; > > list_add_tail(&head->entry, &ctrl->subsys->nsheads); > > kref_get(&ctrl->subsys->ref); > > return head; > +out_cleanup_fdp: > + kfree(head->plids); > +out_clear_ns_head: > + ns->head = NULL; > out_cleanup_srcu: > cleanup_srcu_struct(&head->srcu); > out_ida_remove: > @@ -4103,7 +4099,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, > struct nvme_ns_info *info) > info->nsid); > goto out_unlock; > } > - head = nvme_alloc_ns_head(ctrl, info); > + head = nvme_alloc_ns_head(ns, info); > if (IS_ERR(head)) { > ret = PTR_ERR(head); > goto out_unlock; > diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h > index 824651cc898d..3ae73b36866d 100644 > --- a/drivers/nvme/host/nvme.h > +++ b/drivers/nvme/host/nvme.h > @@ -560,6 +560,7 @@ struct nvme_ns_head { > > u16 nr_plids; > u16 *plids; > + u32 write_stream_granularity; > #ifdef CONFIG_NVME_MULTIPATH > struct bio_list requeue_list; > spinlock_t requeue_lock; > -- > 2.25.1 >