From: Minwoo Im <minwoo.im.dev@gmail.com>
To: qemu-devel@nongnu.org, qemu-block@nongnu.org
Cc: Keith Busch <kbusch@kernel.org>, Klaus Jensen <its@irrelevant.dk>,
Minwoo Im <minwoo.im.dev@gmail.com>,
Kevin Wolf <kwolf@redhat.com>, Max Reitz <mreitz@redhat.com>
Subject: [RFC PATCH V2 09/11] hw/block/nvme: support for multi-controller in subsystem
Date: Sun, 17 Jan 2021 23:53:39 +0900 [thread overview]
Message-ID: <20210117145341.23310-10-minwoo.im.dev@gmail.com> (raw)
In-Reply-To: <20210117145341.23310-1-minwoo.im.dev@gmail.com>
We have nvme-subsys and nvme devices mapped together. To support
multi-controller scheme to this setup, controller identifier(id) has to
be managed. Earlier, cntlid(controller id) used to be always 0 because
we didn't have any subsystem scheme that controller id matters.
This patch introduced 'cntlid' attribute to the nvme controller
instance(NvmeCtrl) and make it allocated by the nvme-subsys device
mapped to the controller. If nvme-subsys is not given to the
controller, then it will always be 0 as it was.
Added 'ctrls' array in the nvme-subsys instance to manage attached
controllers to the subsystem with a limit(32). This patch didn't take
list for the controllers to make it seamless with nvme-ns device.
Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
---
hw/block/nvme-subsys.c | 21 +++++++++++++++++++++
hw/block/nvme-subsys.h | 4 ++++
hw/block/nvme.c | 32 ++++++++++++++++++++++++++++++--
hw/block/nvme.h | 1 +
4 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/hw/block/nvme-subsys.c b/hw/block/nvme-subsys.c
index f1dc71d588d9..a01003136b12 100644
--- a/hw/block/nvme-subsys.c
+++ b/hw/block/nvme-subsys.c
@@ -22,6 +22,27 @@
#include "nvme.h"
#include "nvme-subsys.h"
+int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp)
+{
+ NvmeSubsystem *subsys = n->subsys;
+ int cntlid;
+
+ for (cntlid = 0; cntlid < ARRAY_SIZE(subsys->ctrls); cntlid++) {
+ if (!subsys->ctrls[cntlid]) {
+ break;
+ }
+ }
+
+ if (cntlid == ARRAY_SIZE(subsys->ctrls)) {
+ error_setg(errp, "no more free controller id");
+ return -1;
+ }
+
+ subsys->ctrls[cntlid] = n;
+
+ return cntlid;
+}
+
static void nvme_subsys_setup(NvmeSubsystem *subsys)
{
char *subnqn;
diff --git a/hw/block/nvme-subsys.h b/hw/block/nvme-subsys.h
index 40f06a4c7db0..4eba50d96a1d 100644
--- a/hw/block/nvme-subsys.h
+++ b/hw/block/nvme-subsys.h
@@ -20,6 +20,10 @@ typedef struct NvmeNamespace NvmeNamespace;
typedef struct NvmeSubsystem {
DeviceState parent_obj;
uint8_t subnqn[256];
+
+ NvmeCtrl *ctrls[NVME_SUBSYS_MAX_CTRLS];
} NvmeSubsystem;
+int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp);
+
#endif /* NVME_SUBSYS_H */
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index af5b2162e2b5..2aeb164dd508 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -4242,7 +4242,7 @@ static void nvme_init_subnqn(NvmeCtrl *n)
}
}
-static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
+static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev, uint16_t cntlid)
{
NvmeIdCtrl *id = &n->id_ctrl;
uint8_t *pci_conf = pci_dev->config;
@@ -4252,6 +4252,9 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
strpadcpy((char *)id->mn, sizeof(id->mn), "QEMU NVMe Ctrl", ' ');
strpadcpy((char *)id->fr, sizeof(id->fr), "1.0", ' ');
strpadcpy((char *)id->sn, sizeof(id->sn), n->params.serial, ' ');
+
+ id->cntlid = cntlid;
+
id->rab = 6;
id->ieee[0] = 0x00;
id->ieee[1] = 0x02;
@@ -4297,6 +4300,10 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
id->psd[0].enlat = cpu_to_le32(0x10);
id->psd[0].exlat = cpu_to_le32(0x4);
+ if (n->subsys) {
+ id->cmic |= NVME_CMIC_MULTI_CTRL;
+ }
+
NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);
NVME_CAP_SET_CQR(n->bar.cap, 1);
NVME_CAP_SET_TO(n->bar.cap, 0xf);
@@ -4309,11 +4316,28 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
n->bar.intmc = n->bar.intms = 0;
}
+static int nvme_init_subsys(NvmeCtrl *n, Error **errp)
+{
+ int cntlid;
+
+ if (!n->subsys) {
+ return 0;
+ }
+
+ cntlid = nvme_subsys_register_ctrl(n, errp);
+ if (cntlid < 0) {
+ return -1;
+ }
+
+ return cntlid;
+}
+
static void nvme_realize(PCIDevice *pci_dev, Error **errp)
{
NvmeCtrl *n = NVME(pci_dev);
NvmeNamespace *ns;
Error *local_err = NULL;
+ int cntlid;
nvme_check_constraints(n, &local_err);
if (local_err) {
@@ -4329,7 +4353,11 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
return;
}
- nvme_init_ctrl(n, pci_dev);
+ cntlid = nvme_init_subsys(n, errp);
+ if (cntlid < 0) {
+ return;
+ }
+ nvme_init_ctrl(n, pci_dev, cntlid);
/* setup a namespace if the controller drive property was given */
if (n->namespace.blkconf.blk) {
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 2061e53e2cee..329902a9fc04 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -129,6 +129,7 @@ typedef struct NvmeCtrl {
NvmeBus bus;
BlockConf conf;
+ uint16_t cntlid;
bool qs_created;
uint32_t page_size;
uint16_t page_bits;
--
2.17.1
next prev parent reply other threads:[~2021-01-17 15:05 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-17 14:53 [RFC PATCH V2 00/11] hw/block/nvme: support multi-path for ctrl/ns Minwoo Im
2021-01-17 14:53 ` [RFC PATCH V2 01/11] hw/block/nvme: remove unused argument in nvme_ns_init_zoned Minwoo Im
2021-01-18 20:00 ` Klaus Jensen
2021-01-17 14:53 ` [RFC PATCH V2 02/11] hw/block/nvme: open code for volatile write cache Minwoo Im
2021-01-18 20:04 ` Klaus Jensen
2021-01-19 7:32 ` Klaus Jensen
2021-01-19 8:04 ` Minwoo Im
2021-02-11 6:45 ` Sai Pavan Boddu
2021-02-11 6:58 ` Sai Pavan Boddu
2021-01-17 14:53 ` [RFC PATCH V2 03/11] hw/block/nvme: remove unused argument in nvme_ns_init_blk Minwoo Im
2021-01-18 20:05 ` Klaus Jensen
2021-01-17 14:53 ` [RFC PATCH V2 04/11] hw/block/nvme: split setup and register for namespace Minwoo Im
2021-01-18 20:08 ` Klaus Jensen
2021-01-17 14:53 ` [RFC PATCH V2 05/11] hw/block/nvme: remove unused argument in nvme_ns_setup Minwoo Im
2021-01-18 20:09 ` Klaus Jensen
2021-01-17 14:53 ` [RFC PATCH V2 06/11] hw/block/nvme: introduce nvme-subsys device Minwoo Im
2021-01-17 14:53 ` [RFC PATCH V2 07/11] hw/block/nvme: support to map controller to a subsystem Minwoo Im
2021-01-17 14:53 ` [RFC PATCH V2 08/11] hw/block/nvme: add CMIC enum value for Identify Controller Minwoo Im
2021-01-17 14:53 ` Minwoo Im [this message]
2021-01-17 14:53 ` [RFC PATCH V2 10/11] hw/block/nvme: add NMIC enum value for Identify Namespace Minwoo Im
2021-01-18 20:25 ` Klaus Jensen
2021-01-19 2:12 ` Minwoo Im
2021-01-17 14:53 ` [RFC PATCH V2 11/11] hw/block/nvme: support for shared namespace in subsystem Minwoo Im
2021-01-18 21:14 ` [RFC PATCH V2 00/11] hw/block/nvme: support multi-path for ctrl/ns Klaus Jensen
2021-01-19 3:21 ` Minwoo Im
2021-01-19 6:04 ` Klaus Jensen
2021-01-19 7:51 ` Minwoo Im
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210117145341.23310-10-minwoo.im.dev@gmail.com \
--to=minwoo.im.dev@gmail.com \
--cc=its@irrelevant.dk \
--cc=kbusch@kernel.org \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.