Commit b90d7b5b authored by Jim Harris's avatar Jim Harris Committed by Tomasz Zawadzki
Browse files

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: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I417cd3cdc7e3ba512ec412f4876b0e0b7432341c
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14220


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
parent 0447dca4
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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

+1 −0
Original line number Diff line number Diff line
@@ -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
/**
+9 −0
Original line number Diff line number Diff line
@@ -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",
+6 −0
Original line number Diff line number Diff line
@@ -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)
+2 −3
Original line number Diff line number Diff line
@@ -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);
Loading