提交 ff0c17f8 编写于 作者: A Anton Eidelman 提交者: Yang Yingliang

nvme: don't protect ns mutation with ns->head->lock

mainline inclusion
from mainline-v5.8-rc3
commit e164471d
category: bugfix
bugzilla: NA
CVE: NA
Link: https://gitee.com/openeuler/kernel/issues/I1WGZE

--------------------------------

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: 0d0b660f ("nvme: add ANA support")
Signed-off-by: NAnton Eidelman <anton@lightbitslabs.com>
Signed-off-by: NSagi Grimberg <sagi@grimberg.me>
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Conflicts:
  drivers/nvme/host/multipath.c
[adjust context]
Reviewed-by: NChao Leng <lengchao@huawei.com>
Reviewed-by: NJike Cheng <chengjike.cheng@huawei.com>
Signed-off-by: NLijie <lijie34@huawei.com>
Acked-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 adda4c9b
...@@ -308,11 +308,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) ...@@ -308,11 +308,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
{ {
struct nvme_ns_head *head = ns->head; struct nvme_ns_head *head = ns->head;
lockdep_assert_held(&ns->head->lock);
if (!head->disk) if (!head->disk)
return; return;
mutex_lock(&head->lock);
if (!(head->disk->flags & GENHD_FL_UP)) { if (!(head->disk->flags & GENHD_FL_UP)) {
device_add_disk(&head->subsys->dev, head->disk); device_add_disk(&head->subsys->dev, head->disk);
if (sysfs_create_group(&disk_to_dev(head->disk)->kobj, if (sysfs_create_group(&disk_to_dev(head->disk)->kobj,
...@@ -320,9 +319,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) ...@@ -320,9 +319,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
dev_warn(&head->subsys->dev, dev_warn(&head->subsys->dev,
"failed to create id group.\n"); "failed to create id group.\n");
} }
mutex_unlock(&head->lock);
synchronize_srcu(&ns->head->srcu); synchronize_srcu(&head->srcu);
kblockd_schedule_work(&ns->head->requeue_work); kblockd_schedule_work(&head->requeue_work);
} }
static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data, static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data,
...@@ -377,14 +377,12 @@ static inline bool nvme_state_is_live(enum nvme_ana_state state) ...@@ -377,14 +377,12 @@ static inline bool nvme_state_is_live(enum nvme_ana_state state)
static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc, static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc,
struct nvme_ns *ns) struct nvme_ns *ns)
{ {
mutex_lock(&ns->head->lock);
ns->ana_grpid = le32_to_cpu(desc->grpid); ns->ana_grpid = le32_to_cpu(desc->grpid);
ns->ana_state = desc->state; ns->ana_state = desc->state;
clear_bit(NVME_NS_ANA_PENDING, &ns->flags); clear_bit(NVME_NS_ANA_PENDING, &ns->flags);
if (nvme_state_is_live(ns->ana_state)) if (nvme_state_is_live(ns->ana_state))
nvme_mpath_set_live(ns); nvme_mpath_set_live(ns);
mutex_unlock(&ns->head->lock);
} }
static int nvme_update_ana_state(struct nvme_ctrl *ctrl, static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
...@@ -518,10 +516,8 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id) ...@@ -518,10 +516,8 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id)
nvme_parse_ana_log(ns->ctrl, ns, nvme_set_ns_ana_state); nvme_parse_ana_log(ns->ctrl, ns, nvme_set_ns_ana_state);
mutex_unlock(&ns->ctrl->ana_lock); mutex_unlock(&ns->ctrl->ana_lock);
} else { } else {
mutex_lock(&ns->head->lock);
ns->ana_state = NVME_ANA_OPTIMIZED; ns->ana_state = NVME_ANA_OPTIMIZED;
nvme_mpath_set_live(ns); nvme_mpath_set_live(ns);
mutex_unlock(&ns->head->lock);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册