| From 86a5c1280973b82df74951e5bd6ac97678615dd4 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 14 Sep 2021 08:38:20 +0200 |
| Subject: nvme: keep ctrl->namespaces ordered |
| |
| From: Christoph Hellwig <hch@lst.de> |
| |
| [ Upstream commit 298ba0e3d4af539cc37f982d4c011a0f07fca48c ] |
| |
| Various places in the nvme code that rely on ctrl->namespace to be |
| ordered. Ensure that the namespae is inserted into the list at the |
| right position from the start instead of sorting it after the fact. |
| |
| Fixes: 540c801c65eb ("NVMe: Implement namespace list scanning") |
| Reported-by: Anton Eidelman <anton.eidelman@gmail.com> |
| Signed-off-by: Christoph Hellwig <hch@lst.de> |
| Reviewed-by: Keith Busch <kbusch@kernel.org> |
| Reviewed-by: Sagi Grimberg <sagi@grimberg.me> |
| Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> |
| Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/nvme/host/core.c | 33 +++++++++++++++++---------------- |
| 1 file changed, 17 insertions(+), 16 deletions(-) |
| |
| diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c |
| index 84e7cb9f1968..e2374319df61 100644 |
| --- a/drivers/nvme/host/core.c |
| +++ b/drivers/nvme/host/core.c |
| @@ -13,7 +13,6 @@ |
| #include <linux/kernel.h> |
| #include <linux/module.h> |
| #include <linux/backing-dev.h> |
| -#include <linux/list_sort.h> |
| #include <linux/slab.h> |
| #include <linux/types.h> |
| #include <linux/pr.h> |
| @@ -3688,15 +3687,6 @@ out_unlock: |
| return ret; |
| } |
| |
| -static int ns_cmp(void *priv, const struct list_head *a, |
| - const struct list_head *b) |
| -{ |
| - struct nvme_ns *nsa = container_of(a, struct nvme_ns, list); |
| - struct nvme_ns *nsb = container_of(b, struct nvme_ns, list); |
| - |
| - return nsa->head->ns_id - nsb->head->ns_id; |
| -} |
| - |
| struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid) |
| { |
| struct nvme_ns *ns, *ret = NULL; |
| @@ -3717,6 +3707,22 @@ struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid) |
| } |
| EXPORT_SYMBOL_NS_GPL(nvme_find_get_ns, NVME_TARGET_PASSTHRU); |
| |
| +/* |
| + * Add the namespace to the controller list while keeping the list ordered. |
| + */ |
| +static void nvme_ns_add_to_ctrl_list(struct nvme_ns *ns) |
| +{ |
| + struct nvme_ns *tmp; |
| + |
| + list_for_each_entry_reverse(tmp, &ns->ctrl->namespaces, list) { |
| + if (tmp->head->ns_id < ns->head->ns_id) { |
| + list_add(&ns->list, &tmp->list); |
| + return; |
| + } |
| + } |
| + list_add(&ns->list, &ns->ctrl->namespaces); |
| +} |
| + |
| static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid, |
| struct nvme_ns_ids *ids) |
| { |
| @@ -3778,9 +3784,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid, |
| } |
| |
| down_write(&ctrl->namespaces_rwsem); |
| - list_add_tail(&ns->list, &ctrl->namespaces); |
| + nvme_ns_add_to_ctrl_list(ns); |
| up_write(&ctrl->namespaces_rwsem); |
| - |
| nvme_get_ctrl(ctrl); |
| |
| device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups); |
| @@ -4059,10 +4064,6 @@ static void nvme_scan_work(struct work_struct *work) |
| if (nvme_scan_ns_list(ctrl) != 0) |
| nvme_scan_ns_sequential(ctrl); |
| mutex_unlock(&ctrl->scan_lock); |
| - |
| - down_write(&ctrl->namespaces_rwsem); |
| - list_sort(NULL, &ctrl->namespaces, ns_cmp); |
| - up_write(&ctrl->namespaces_rwsem); |
| } |
| |
| /* |
| -- |
| 2.33.0 |
| |