Skip to content

Commit e164471

Browse files
sagigrimbergChristoph Hellwig
authored andcommitted
nvme: don't protect ns mutation with ns->head->lock
Right now ns->head->lock is protecting namespace mutation which is wrong and unneeded. Move it to only protect against head mutations. While we're at it, remove unnecessary ns->head reference as we already have head pointer. The problem with this is that the head->lock spans mpath disk node I/O that may block under some conditions (if for example the controller is disconnecting or the path became inaccessible), The locking scheme does not allow any other path to enable itself, preventing blocked I/O to complete and forward-progress from there. This is a preparation patch for the fix in a subsequent patch where the disk I/O will also be done outside the head->lock. Fixes: 0d0b660 ("nvme: add ANA support") Signed-off-by: Anton Eidelman <[email protected]> Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 489dd10 commit e164471

File tree

1 file changed

+4
-8
lines changed

1 file changed

+4
-8
lines changed

drivers/nvme/host/multipath.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
409409
{
410410
struct nvme_ns_head *head = ns->head;
411411

412-
lockdep_assert_held(&ns->head->lock);
413-
414412
if (!head->disk)
415413
return;
416414

415+
mutex_lock(&head->lock);
417416
if (!(head->disk->flags & GENHD_FL_UP))
418417
device_add_disk(&head->subsys->dev, head->disk,
419418
nvme_ns_id_attr_groups);
@@ -426,9 +425,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
426425
__nvme_find_path(head, node);
427426
srcu_read_unlock(&head->srcu, srcu_idx);
428427
}
428+
mutex_unlock(&head->lock);
429429

430-
synchronize_srcu(&ns->head->srcu);
431-
kblockd_schedule_work(&ns->head->requeue_work);
430+
synchronize_srcu(&head->srcu);
431+
kblockd_schedule_work(&head->requeue_work);
432432
}
433433

434434
static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data,
@@ -483,14 +483,12 @@ static inline bool nvme_state_is_live(enum nvme_ana_state state)
483483
static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc,
484484
struct nvme_ns *ns)
485485
{
486-
mutex_lock(&ns->head->lock);
487486
ns->ana_grpid = le32_to_cpu(desc->grpid);
488487
ns->ana_state = desc->state;
489488
clear_bit(NVME_NS_ANA_PENDING, &ns->flags);
490489

491490
if (nvme_state_is_live(ns->ana_state))
492491
nvme_mpath_set_live(ns);
493-
mutex_unlock(&ns->head->lock);
494492
}
495493

496494
static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
@@ -669,10 +667,8 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id)
669667
nvme_update_ns_ana_state(&desc, ns);
670668
}
671669
} else {
672-
mutex_lock(&ns->head->lock);
673670
ns->ana_state = NVME_ANA_OPTIMIZED;
674671
nvme_mpath_set_live(ns);
675-
mutex_unlock(&ns->head->lock);
676672
}
677673

678674
if (bdi_cap_stable_pages_required(ns->queue->backing_dev_info)) {

0 commit comments

Comments
 (0)