nvmet: only allocate a single slab for bvecs
authorChristoph Hellwig <hch@lst.de>
Mon, 7 Nov 2022 13:01:24 +0000 (14:01 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:14:09 +0000 (13:14 +0100)
[ Upstream commit fa8f9ac42350edd3ce82d0d148a60f0fa088f995 ]

There is no need to have a separate slab cache for each namespace,
and having separate ones creates duplicate debugs file names as well.

Fixes: d5eff33ee6f8 ("nvmet: add simple file backed ns support")
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: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/nvme/target/core.c
drivers/nvme/target/io-cmd-file.c
drivers/nvme/target/nvmet.h

index 87a3472..cfd0385 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "nvmet.h"
 
+struct kmem_cache *nvmet_bvec_cache;
 struct workqueue_struct *buffered_io_wq;
 struct workqueue_struct *zbd_wq;
 static const struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
@@ -1607,26 +1608,28 @@ void nvmet_subsys_put(struct nvmet_subsys *subsys)
 
 static int __init nvmet_init(void)
 {
-       int error;
+       int error = -ENOMEM;
 
        nvmet_ana_group_enabled[NVMET_DEFAULT_ANA_GRPID] = 1;
 
+       nvmet_bvec_cache = kmem_cache_create("nvmet-bvec",
+                       NVMET_MAX_MPOOL_BVEC * sizeof(struct bio_vec), 0,
+                       SLAB_HWCACHE_ALIGN, NULL);
+       if (!nvmet_bvec_cache)
+               return -ENOMEM;
+
        zbd_wq = alloc_workqueue("nvmet-zbd-wq", WQ_MEM_RECLAIM, 0);
        if (!zbd_wq)
-               return -ENOMEM;
+               goto out_destroy_bvec_cache;
 
        buffered_io_wq = alloc_workqueue("nvmet-buffered-io-wq",
                        WQ_MEM_RECLAIM, 0);
-       if (!buffered_io_wq) {
-               error = -ENOMEM;
+       if (!buffered_io_wq)
                goto out_free_zbd_work_queue;
-       }
 
        nvmet_wq = alloc_workqueue("nvmet-wq", WQ_MEM_RECLAIM, 0);
-       if (!nvmet_wq) {
-               error = -ENOMEM;
+       if (!nvmet_wq)
                goto out_free_buffered_work_queue;
-       }
 
        error = nvmet_init_discovery();
        if (error)
@@ -1645,6 +1648,8 @@ out_free_buffered_work_queue:
        destroy_workqueue(buffered_io_wq);
 out_free_zbd_work_queue:
        destroy_workqueue(zbd_wq);
+out_destroy_bvec_cache:
+       kmem_cache_destroy(nvmet_bvec_cache);
        return error;
 }
 
@@ -1656,6 +1661,7 @@ static void __exit nvmet_exit(void)
        destroy_workqueue(nvmet_wq);
        destroy_workqueue(buffered_io_wq);
        destroy_workqueue(zbd_wq);
+       kmem_cache_destroy(nvmet_bvec_cache);
 
        BUILD_BUG_ON(sizeof(struct nvmf_disc_rsp_page_entry) != 1024);
        BUILD_BUG_ON(sizeof(struct nvmf_disc_rsp_page_hdr) != 1024);
index 228871d..eadba13 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/fs.h>
 #include "nvmet.h"
 
-#define NVMET_MAX_MPOOL_BVEC           16
 #define NVMET_MIN_MPOOL_OBJ            16
 
 int nvmet_file_ns_revalidate(struct nvmet_ns *ns)
@@ -33,8 +32,6 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns)
                        flush_workqueue(buffered_io_wq);
                mempool_destroy(ns->bvec_pool);
                ns->bvec_pool = NULL;
-               kmem_cache_destroy(ns->bvec_cache);
-               ns->bvec_cache = NULL;
                fput(ns->file);
                ns->file = NULL;
        }
@@ -68,16 +65,8 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
        ns->blksize_shift = min_t(u8,
                        file_inode(ns->file)->i_blkbits, 12);
 
-       ns->bvec_cache = kmem_cache_create("nvmet-bvec",
-                       NVMET_MAX_MPOOL_BVEC * sizeof(struct bio_vec),
-                       0, SLAB_HWCACHE_ALIGN, NULL);
-       if (!ns->bvec_cache) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
        ns->bvec_pool = mempool_create(NVMET_MIN_MPOOL_OBJ, mempool_alloc_slab,
-                       mempool_free_slab, ns->bvec_cache);
+                       mempool_free_slab, nvmet_bvec_cache);
 
        if (!ns->bvec_pool) {
                ret = -ENOMEM;
@@ -86,9 +75,10 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
 
        return ret;
 err:
+       fput(ns->file);
+       ns->file = NULL;
        ns->size = 0;
        ns->blksize_shift = 0;
-       nvmet_file_ns_disable(ns);
        return ret;
 }
 
index dbeb0b8..fdb06a9 100644 (file)
@@ -77,7 +77,6 @@ struct nvmet_ns {
 
        struct completion       disable_done;
        mempool_t               *bvec_pool;
-       struct kmem_cache       *bvec_cache;
 
        int                     use_p2pmem;
        struct pci_dev          *p2p_dev;
@@ -363,6 +362,8 @@ struct nvmet_req {
        u64                     error_slba;
 };
 
+#define NVMET_MAX_MPOOL_BVEC           16
+extern struct kmem_cache *nvmet_bvec_cache;
 extern struct workqueue_struct *buffered_io_wq;
 extern struct workqueue_struct *zbd_wq;
 extern struct workqueue_struct *nvmet_wq;