nvme: if no command set is requested, use the most reasonable default

Since namespace types were introduced in NVMe, the CC.CSS register
has a new value (SPDK_NVME_CC_CSS_IOCS) which indicates that all
supported command sets should be selected/enabled. This possibly
includes command sets other than NVM and ADMIN only.

Therefore, if a SPDK application wants enable all the command sets
that the controller supports, it has to explicitly set
opts->command_set to SPDK_NVME_CC_CSS_IOCS.

To avoid possibly a lot of SPDK applications having to set this
parameter, check if the user requested a command set explicitly,
if not, make SPDK automatically use the most reasonable default,
based on the supported bits set by the controller.
The most common case is that you want to enable (all) the command
sets that the controller supports.

A user will still be able to restrict the controller to only use
the NVM command set (or ADMIN only), by setting opts->command_set
to a specific value.

Since the current default command set value specified by
spdk_nvme_ctrlr_get_default_ctrlr_opts() is SPDK_NVME_CC_CSS_NVM,
which is defined as 0, we cannot know if the user specified a
command set explicitly or not.
To solve this, change the default command set value specified by
spdk_nvme_ctrlr_get_default_ctrlr_opts() to CHAR_BIT (0x8), which
is larger than the largest value that can be set in CS.CSS (which
is only 3 bits wide, thus 0x7).

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Change-Id: I45ec148d3667ab87c41fbfb6d6612a1e0e5c9d9c
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4701
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Niklas Cassel 2020-10-15 10:39:01 +00:00 committed by Tomasz Zawadzki
parent 20b7b660c9
commit 198a3ad2fd
2 changed files with 28 additions and 1 deletions

View File

@ -162,6 +162,10 @@ A new API `spdk_ioat_get_max_descriptors` was added.
### nvme
If no specific command set is requested (by setting the command_set member in the
`spdk_nvme_ctrlr_opts` structure), SPDK will automatically select the most appropriate
command set based on what the controller supports.
An `opts_size`element was added in the `spdk_nvme_ctrlr_opts` structure
to solve the ABI compatiblity issue between different SPDK version.

View File

@ -188,7 +188,7 @@ spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t
}
if (FIELD_OK(command_set)) {
opts->command_set = SPDK_NVME_CC_CSS_NVM;
opts->command_set = CHAR_BIT;
}
if (FIELD_OK(admin_timeout_ms)) {
@ -1028,12 +1028,35 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
/* Page size is 2 ^ (12 + mps). */
cc.bits.mps = spdk_u32log2(ctrlr->page_size) - 12;
/*
* Since NVMe 1.0, a controller should have at least one bit set in CAP.CSS.
* A controller that does not have any bit set in CAP.CSS is not spec compliant.
* Try to support such a controller regardless.
*/
if (ctrlr->cap.bits.css == 0) {
SPDK_INFOLOG(nvme,
"Drive reports no command sets supported. Assuming NVM is supported.\n");
ctrlr->cap.bits.css = SPDK_NVME_CAP_CSS_NVM;
}
/*
* If the user did not explicitly request a command set, or supplied a value larger than
* what can be saved in CC.CSS, use the most reasonable default.
*/
if (ctrlr->opts.command_set >= CHAR_BIT) {
if (ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_IOCS) {
ctrlr->opts.command_set = SPDK_NVME_CC_CSS_IOCS;
} else if (ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_NVM) {
ctrlr->opts.command_set = SPDK_NVME_CC_CSS_NVM;
} else if (ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_NOIO) {
ctrlr->opts.command_set = SPDK_NVME_CC_CSS_NOIO;
} else {
/* Invalid supported bits detected, falling back to NVM. */
ctrlr->opts.command_set = SPDK_NVME_CC_CSS_NVM;
}
}
/* Verify that the selected command set is supported by the controller. */
if (!(ctrlr->cap.bits.css & (1u << ctrlr->opts.command_set))) {
SPDK_DEBUGLOG(nvme, "Requested I/O command set %u but supported mask is 0x%x\n",
ctrlr->opts.command_set, ctrlr->cap.bits.css);