From: Sungup Moon <sungup.moon@samsung.com>
To: "kbusch@kernel.org" <kbusch@kernel.org>,
"axboe@fb.com" <axboe@fb.com>, "hch@lst.de" <hch@lst.de>,
"sagi@grimberg.me" <sagi@grimberg.me>
Cc: "linux-nvme@lists.infradead.org" <linux-nvme@lists.infradead.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Sungup Moon <sungup.moon@samsung.com>
Subject: [PATCH v2] driver/nvme/host: Support duplicated nsid for the private ns
Date: Mon, 14 Mar 2022 20:05:45 +0900 [thread overview]
Message-ID: <20220314110545epcms2p4a227eac7c4652445050e70ee2350635d@epcms2p4> (raw)
In-Reply-To: <CGME20220314110545epcms2p4a227eac7c4652445050e70ee2350635d@epcms2p4>
When the multi-controller, managed by a special admin command, has private
namespace with same nsid, current linux driver raise "Duplicate unshared
namespace" error. But, NVMe Specification defines the NSID usage like this:
If Namespace Management, ANA Reporting, or NVM Sets are supported, the
NSIDs shall be unique within the NVM subsystem. If the Namespace
Management, ANA Reporting, and NVM Sets are not supported, then NSIDs:
a) for shared namespace shall be unique; and
b) for private namespace are not required to be unique.
(reference: 6.1.6 NSID and Namespace Usage; NVM Express 1.4c spec)
So, if a multi-controller, which is not managed by Namespace Management
function, creates some private namespaces without ANA and NVM Sets, the
duplicated NSID should be allowed because that is not a NVMe specification
violation.
But, current nvme driver checks only namespace is shared or not, so I
propose following patch:
1. nvme_ctrl has unique_nsid field to identify that controller should
assign unique nsid.
2. nvme_init_ns_head function creates new nvme_ns_head instance not only
head is null but controller's unique_nsid is false (no flagged
attribute) and namespace is not shared.
3. for creating bdev device file, nvme_mpath_set_disk_name will return
false when unique_nsid is false and namespace is not shared.
4. also, nvme_mpath_alloc_disk alto return 0 with same manner.
This patch has been modified the unique_nsid mechanism from flag based
to the checking function.
- v1: flag based initial patch
- v2: change from unique_nsid flag to nvme_check_unique_nsid
Signed-off-by: Sungup Moon <sungup.moon@samsung.com>
---
drivers/nvme/host/core.c | 9 ++++++++-
drivers/nvme/host/multipath.c | 5 +++--
drivers/nvme/host/nvme.h | 16 ++++++++++++++++
include/linux/nvme.h | 1 +
4 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 51c08f206cbf..5eedef9a781c 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3816,7 +3816,14 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
mutex_lock(&ctrl->subsys->lock);
head = nvme_find_ns_head(ctrl->subsys, nsid);
- if (!head) {
+ if (!head || !(nvme_check_unique_nsid(ctrl, head) || is_shared)) {
+ /*
+ * If the found ns head is null or both of ns are not shared
+ * without the unique namespace condition (this means both
+ * namespace are private namespaces and those can share the
+ * same nsid), allocate the new head. Private namespace can
+ * reuse nsid with the others.
+ */
ret = nvme_subsys_check_duplicate_ids(ctrl->subsys, ids);
if (ret) {
dev_err(ctrl->device,
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index ff775235534c..4671dc1b32da 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -88,7 +88,7 @@ void nvme_mpath_start_freeze(struct nvme_subsystem *subsys)
*/
bool nvme_mpath_set_disk_name(struct nvme_ns *ns, char *disk_name, int *flags)
{
- if (!multipath)
+ if (!multipath || !nvme_check_unique_nsid(ns->ctrl, ns->head))
return false;
if (!ns->head->disk) {
sprintf(disk_name, "nvme%dn%d", ns->ctrl->subsys->instance,
@@ -507,7 +507,8 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
* We also do this for private namespaces as the namespace sharing data could
* change after a rescan.
*/
- if (!(ctrl->subsys->cmic & NVME_CTRL_CMIC_MULTI_CTRL) || !multipath)
+ if (!(ctrl->subsys->cmic & NVME_CTRL_CMIC_MULTI_CTRL) || !multipath ||
+ !nvme_check_unique_nsid(ctrl, head))
return 0;
head->disk = blk_alloc_disk(ctrl->numa_node);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index e7ccdb119ede..50091ed3713b 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -719,6 +719,22 @@ static inline bool nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
return queue_live;
return __nvme_check_ready(ctrl, rq, queue_live);
}
+static inline bool nvme_check_unique_nsid(struct nvme_ctrl *ctrl,
+ struct nvme_ns_head *head)
+{
+ /*
+ * NSID should be unique on the following condition
+ * 1. Namespace Management support; or
+ * 2. ANA Reporing support; or
+ * 3. NVM Set support; or
+ * 4. Namespace is shared
+ * Other case, private namespace are not required to be unique.
+ */
+ return (ctrl->oacs & NVME_CTRL_OACS_NS_MNGT_SUPP) ||
+ (ctrl->subsys->cmic & NVME_CTRL_CMIC_ANA) ||
+ (ctrl->ctratt & NVME_CTRL_CTRATT_NVM_SETS) ||
+ (head->shared);
+}
int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
void *buf, unsigned bufflen);
int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 4f44f83817a9..f626a445d1a8 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -346,6 +346,7 @@ enum {
NVME_CTRL_ONCS_TIMESTAMP = 1 << 6,
NVME_CTRL_VWC_PRESENT = 1 << 0,
NVME_CTRL_OACS_SEC_SUPP = 1 << 0,
+ NVME_CTRL_OACS_NS_MNGT_SUPP = 1 << 3,
NVME_CTRL_OACS_DIRECTIVES = 1 << 5,
NVME_CTRL_OACS_DBBUF_SUPP = 1 << 8,
NVME_CTRL_LPA_CMD_EFFECTS_LOG = 1 << 1,
--
2.25.1
next parent reply other threads:[~2022-03-14 11:06 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20220314110545epcms2p4a227eac7c4652445050e70ee2350635d@epcms2p4>
2022-03-14 11:05 ` Sungup Moon [this message]
2022-03-15 7:12 ` hch
2022-03-15 7:19 ` hch
2022-03-15 8:18 ` Sagi Grimberg
2022-03-15 8:40 ` hch
2022-03-15 8:42 ` Sagi Grimberg
2022-03-15 8:46 ` hch
2022-03-15 8:54 ` Sagi Grimberg
[not found] ` <CGME20220314110545epcms2p4a227eac7c4652445050e70ee2350635d@epcms2p6>
2022-03-15 10:24 ` Sungup Moon
[not found] ` <CGME20220314110545epcms2p4a227eac7c4652445050e70ee2350635d@epcms2p3>
2022-03-15 9:56 ` Sungup Moon
2022-03-15 10:07 ` (2) " hch
2022-03-15 10:56 ` Sungup Moon
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=20220314110545epcms2p4a227eac7c4652445050e70ee2350635d@epcms2p4 \
--to=sungup.moon@samsung.com \
--cc=axboe@fb.com \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®