[PATCH] nvme: Use first ctrl->instance id as subsystem id

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Since after the introduction of NVMe multipath, we have a struct to
track subsystems, and more important, we have now the nvme block device
name bound to the subsystem id instead of ctrl->instance as before.
This is not a big problem, users can even fallback to the old behavior
using the module parameter "nvme_core.multipath=N" in case they don't
have multipath and wish to have a consistent mapping between the char
device nvmeX and the block device nvmeXnY.

That said, we noticed the nvme subsystem id is generated by its own ID
allocator, and ctrl->instance value has itself an ID allocator too.
The controller instance is generated during the probe, in the function
nvme_init_ctrl(), which always executes before nvme_init_subsystem().
That said, and since according to the spec we have a relation 1:N
between subsystem and controllers (i.e., one subsystem may have more
controllers but not the reciprocal), why not use the ctrl->instance id
as the subsystem id?

This patch does exactly this: removes the ID allocator for subsystems
and use the unique controller instance id as subsystem id. The patch
was tested in multiple scenarios, like:

* multiple controllers (each one tied to its own subsystem);
* 2 controllers in a single subsystem (using emulated nvme controllers
from qemu). In this case, subsystem gets the id of its 1st controller;
* NVMEoF/TCP with this patch in both target and host kernels.

All test cases worked as expected. With this patch, the "coincidence"
of the char device number matches the block device number is forced for
single-controllers subsystems (the most usual scenario), even without
disabling multipath. It's useful for scenarios with some multipath'ed
controllers and some solo controllers.

Signed-off-by: Guilherme G. Piccoli <gpiccoli@xxxxxxxxxxxxx>
---
 drivers/nvme/host/core.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index cca270836892..60631e856b41 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -81,7 +81,6 @@ EXPORT_SYMBOL_GPL(nvme_reset_wq);
 struct workqueue_struct *nvme_delete_wq;
 EXPORT_SYMBOL_GPL(nvme_delete_wq);
 
-static DEFINE_IDA(nvme_subsystems_ida);
 static LIST_HEAD(nvme_subsystems);
 static DEFINE_MUTEX(nvme_subsystems_lock);
 
@@ -2316,7 +2315,6 @@ static void nvme_release_subsystem(struct device *dev)
 	struct nvme_subsystem *subsys =
 		container_of(dev, struct nvme_subsystem, dev);
 
-	ida_simple_remove(&nvme_subsystems_ida, subsys->instance);
 	kfree(subsys);
 }
 
@@ -2445,12 +2443,8 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
 	subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
 	if (!subsys)
 		return -ENOMEM;
-	ret = ida_simple_get(&nvme_subsystems_ida, 0, 0, GFP_KERNEL);
-	if (ret < 0) {
-		kfree(subsys);
-		return ret;
-	}
-	subsys->instance = ret;
+
+	subsys->instance = ctrl->instance;
 	mutex_init(&subsys->lock);
 	kref_init(&subsys->ref);
 	INIT_LIST_HEAD(&subsys->ctrls);
@@ -4051,7 +4045,6 @@ static int __init nvme_core_init(void)
 
 static void __exit nvme_core_exit(void)
 {
-	ida_destroy(&nvme_subsystems_ida);
 	class_destroy(nvme_subsys_class);
 	class_destroy(nvme_class);
 	unregister_chrdev_region(nvme_chr_devt, NVME_MINORS);
-- 
2.22.0




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux