nvme: add admin queue size quirk for Hyper-V

Hyper-V NVMe SSD controllers require admin queue
size to be even multiples of a page. Add quirk to
adjust the admin queue size if user overrides the
default value to something other than an even
multiple.

As part of this change, set the quirks earlier
when constructing a pcie controller, so that the
quirks value can be used in the generic
nvme_ctrlr_construct() function.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I417cd3cdc7e3ba512ec412f4876b0e0b7432341c
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14220
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
Jim Harris 2022-08-25 17:53:20 +00:00 committed by Tomasz Zawadzki
parent 0447dca450
commit b90d7b5b43
6 changed files with 26 additions and 3 deletions

View File

@ -32,6 +32,11 @@ extern "C" {
#define SPDK_NVME_ADMIN_QUEUE_MIN_ENTRIES SPDK_NVME_QUEUE_MIN_ENTRIES
#define SPDK_NVME_ADMIN_QUEUE_MAX_ENTRIES 4096
/* Controllers with quirk NVME_QUIRK_MINIMUM_ADMIN_QUEUE_SIZE must have
* admin queue size entries that are an even multiple of this number.
*/
#define SPDK_NVME_ADMIN_QUEUE_QUIRK_ENTRIES_MULTIPLE 64
#define SPDK_NVME_IO_QUEUE_MIN_ENTRIES SPDK_NVME_QUEUE_MIN_ENTRIES
#define SPDK_NVME_IO_QUEUE_MAX_ENTRIES 65536

View File

@ -27,6 +27,7 @@ extern "C" {
#define SPDK_PCI_VID_REDHAT 0x1b36
#define SPDK_PCI_VID_NUTANIX 0x4e58
#define SPDK_PCI_VID_HUAWEI 0x19e5
#define SPDK_PCI_VID_MICROSOFT 0x1414
#define SPDK_PCI_CLASS_ANY_ID 0xffffff
/**

View File

@ -4065,6 +4065,15 @@ nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr)
ctrlr->opts.admin_queue_size = SPDK_NVME_ADMIN_QUEUE_MAX_ENTRIES;
}
if (ctrlr->quirks & NVME_QUIRK_MINIMUM_ADMIN_QUEUE_SIZE &&
(ctrlr->opts.admin_queue_size % SPDK_NVME_ADMIN_QUEUE_QUIRK_ENTRIES_MULTIPLE) != 0) {
NVME_CTRLR_ERRLOG(ctrlr,
"admin_queue_size %u is invalid for this NVMe device, adjust to next multiple\n",
ctrlr->opts.admin_queue_size);
ctrlr->opts.admin_queue_size = SPDK_ALIGN_CEIL(ctrlr->opts.admin_queue_size,
SPDK_NVME_ADMIN_QUEUE_QUIRK_ENTRIES_MULTIPLE);
}
if (ctrlr->opts.admin_queue_size < SPDK_NVME_ADMIN_QUEUE_MIN_ENTRIES) {
NVME_CTRLR_ERRLOG(ctrlr,
"admin_queue_size %u is less than minimum defined by NVMe spec, use min value\n",

View File

@ -141,6 +141,12 @@ extern pid_t g_spdk_nvme_pid;
*/
#define NVME_QUIRK_NOT_USE_SGL 0x10000
/*
* Some SSDs require the admin submission queue size to equate to an even
* 4KiB multiple.
*/
#define NVME_QUIRK_MINIMUM_ADMIN_QUEUE_SIZE 0x20000
#define NVME_MAX_ASYNC_EVENTS (8)
#define NVME_MAX_ADMIN_TIMEOUT_IN_SECS (30)

View File

@ -907,6 +907,8 @@ static struct spdk_nvme_ctrlr *
pctrlr->ctrlr.trid = *trid;
pctrlr->ctrlr.opts.admin_queue_size = spdk_max(pctrlr->ctrlr.opts.admin_queue_size,
NVME_PCIE_MIN_ADMIN_QUEUE_SIZE);
pci_id = spdk_pci_device_get_id(pci_dev);
pctrlr->ctrlr.quirks = nvme_get_quirks(&pci_id);
rc = nvme_ctrlr_construct(&pctrlr->ctrlr);
if (rc != 0) {
@ -938,9 +940,6 @@ static struct spdk_nvme_ctrlr *
* but we want multiples of 4, so drop the + 2 */
pctrlr->doorbell_stride_u32 = 1 << cap.bits.dstrd;
pci_id = spdk_pci_device_get_id(pci_dev);
pctrlr->ctrlr.quirks = nvme_get_quirks(&pci_id);
rc = nvme_pcie_ctrlr_construct_admin_qpair(&pctrlr->ctrlr, pctrlr->ctrlr.opts.admin_queue_size);
if (rc != 0) {
nvme_ctrlr_destruct(&pctrlr->ctrlr);

View File

@ -84,6 +84,9 @@ static const struct nvme_quirk nvme_quirks[] = {
{ {SPDK_PCI_CLASS_NVME, SPDK_PCI_VID_HUAWEI, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID},
NVME_QUIRK_NOT_USE_SGL
},
{ {SPDK_PCI_CLASS_NVME, SPDK_PCI_VID_MICROSOFT, 0xb111, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID},
NVME_QUIRK_MINIMUM_ADMIN_QUEUE_SIZE
},
{ {0x000000, 0x0000, 0x0000, 0x0000, 0x0000}, 0}
};