Commit 4005f28d authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

nvme: avoid an Identify Controller command for each namespace scan

The namespace lists are 0-terminated, so we don't really need the NN value
execept for the legacy sequential scan.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKeith Busch <kbusch@kernel.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 4450ba3b
...@@ -3740,12 +3740,11 @@ static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl, ...@@ -3740,12 +3740,11 @@ static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
} }
static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn) static int nvme_scan_ns_list(struct nvme_ctrl *ctrl)
{ {
__le32 *ns_list; __le32 *ns_list;
unsigned i, j, nsid, prev = 0; u32 prev = 0;
unsigned num_lists = DIV_ROUND_UP_ULL((u64)nn, 1024); int ret = 0, i;
int ret = 0;
if (nvme_ctrl_limited_cns(ctrl)) if (nvme_ctrl_limited_cns(ctrl))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -3754,22 +3753,20 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn) ...@@ -3754,22 +3753,20 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
if (!ns_list) if (!ns_list)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < num_lists; i++) { for (;;) {
ret = nvme_identify_ns_list(ctrl, prev, ns_list); ret = nvme_identify_ns_list(ctrl, prev, ns_list);
if (ret) if (ret)
goto free; goto free;
for (j = 0; j < min(nn, 1024U); j++) { for (i = 0; i < 1024; i++) {
nsid = le32_to_cpu(ns_list[j]); u32 nsid = le32_to_cpu(ns_list[i]);
if (!nsid)
goto out;
if (!nsid) /* end of the list? */
goto out;
nvme_validate_ns(ctrl, nsid); nvme_validate_ns(ctrl, nsid);
while (++prev < nsid) while (++prev < nsid)
nvme_ns_remove_by_nsid(ctrl, prev); nvme_ns_remove_by_nsid(ctrl, prev);
} }
nn -= j;
} }
out: out:
nvme_remove_invalid_namespaces(ctrl, prev); nvme_remove_invalid_namespaces(ctrl, prev);
...@@ -3778,9 +3775,15 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn) ...@@ -3778,9 +3775,15 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
return ret; return ret;
} }
static void nvme_scan_ns_sequential(struct nvme_ctrl *ctrl, unsigned nn) static void nvme_scan_ns_sequential(struct nvme_ctrl *ctrl)
{ {
unsigned i; struct nvme_id_ctrl *id;
u32 nn, i;
if (nvme_identify_ctrl(ctrl, &id))
return;
nn = le32_to_cpu(id->nn);
kfree(id);
for (i = 1; i <= nn; i++) for (i = 1; i <= nn; i++)
nvme_validate_ns(ctrl, i); nvme_validate_ns(ctrl, i);
...@@ -3817,8 +3820,6 @@ static void nvme_scan_work(struct work_struct *work) ...@@ -3817,8 +3820,6 @@ static void nvme_scan_work(struct work_struct *work)
{ {
struct nvme_ctrl *ctrl = struct nvme_ctrl *ctrl =
container_of(work, struct nvme_ctrl, scan_work); container_of(work, struct nvme_ctrl, scan_work);
struct nvme_id_ctrl *id;
unsigned nn;
/* No tagset on a live ctrl means IO queues could not created */ /* No tagset on a live ctrl means IO queues could not created */
if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset) if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset)
...@@ -3829,14 +3830,9 @@ static void nvme_scan_work(struct work_struct *work) ...@@ -3829,14 +3830,9 @@ static void nvme_scan_work(struct work_struct *work)
nvme_clear_changed_ns_log(ctrl); nvme_clear_changed_ns_log(ctrl);
} }
if (nvme_identify_ctrl(ctrl, &id))
return;
nn = le32_to_cpu(id->nn);
kfree(id);
mutex_lock(&ctrl->scan_lock); mutex_lock(&ctrl->scan_lock);
if (nvme_scan_ns_list(ctrl, nn) != 0) if (nvme_scan_ns_list(ctrl) != 0)
nvme_scan_ns_sequential(ctrl, nn); nvme_scan_ns_sequential(ctrl);
mutex_unlock(&ctrl->scan_lock); mutex_unlock(&ctrl->scan_lock);
down_write(&ctrl->namespaces_rwsem); down_write(&ctrl->namespaces_rwsem);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment