Skip to content

Commit 9edceaf

Browse files
igawChristoph Hellwig
authored andcommitted
nvme: avoid race in shutdown namespace removal
When we remove the siblings entry, we update ns->head->list, hence we can't separate the removal and test for being empty. They have to be in the same critical section to avoid a race. To avoid breaking the refcounting imbalance again, add a list empty check to nvme_find_ns_head. Fixes: 5396fda ("nvme: fix refcounting imbalance when all paths are down") Signed-off-by: Daniel Wagner <dwagner@suse.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Tested-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent 0bd46e2 commit 9edceaf

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

drivers/nvme/host/core.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3524,7 +3524,9 @@ static struct nvme_ns_head *nvme_find_ns_head(struct nvme_subsystem *subsys,
35243524
lockdep_assert_held(&subsys->lock);
35253525

35263526
list_for_each_entry(h, &subsys->nsheads, entry) {
3527-
if (h->ns_id == nsid && nvme_tryget_ns_head(h))
3527+
if (h->ns_id != nsid)
3528+
continue;
3529+
if (!list_empty(&h->list) && nvme_tryget_ns_head(h))
35283530
return h;
35293531
}
35303532

@@ -3843,6 +3845,10 @@ static void nvme_ns_remove(struct nvme_ns *ns)
38433845

38443846
mutex_lock(&ns->ctrl->subsys->lock);
38453847
list_del_rcu(&ns->siblings);
3848+
if (list_empty(&ns->head->list)) {
3849+
list_del_init(&ns->head->entry);
3850+
last_path = true;
3851+
}
38463852
mutex_unlock(&ns->ctrl->subsys->lock);
38473853

38483854
/* guarantee not available in head->list */
@@ -3863,13 +3869,6 @@ static void nvme_ns_remove(struct nvme_ns *ns)
38633869
list_del_init(&ns->list);
38643870
up_write(&ns->ctrl->namespaces_rwsem);
38653871

3866-
/* Synchronize with nvme_init_ns_head() */
3867-
mutex_lock(&ns->head->subsys->lock);
3868-
if (list_empty(&ns->head->list)) {
3869-
list_del_init(&ns->head->entry);
3870-
last_path = true;
3871-
}
3872-
mutex_unlock(&ns->head->subsys->lock);
38733872
if (last_path)
38743873
nvme_mpath_shutdown_disk(ns->head);
38753874
nvme_put_ns(ns);

0 commit comments

Comments
 (0)