Commit acb9849c authored by Changpeng Liu's avatar Changpeng Liu
Browse files

nvme: add arbitration configuration options to NVMe driver



Weighted Round Robin can be enabled for users, and users
can allocate different priority IO queues for different
purpose.  For now we will enable this feature in the
NVMe driver first, following patches will enable this
feature in bdev layer.

Change-Id: I0f799236ca04eb85ef3c9f972ed63ff2718563ba
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466852


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 8a857a3b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@ later again to initialize the controller to the ready state.
A controller flag `SPDK_NVME_CTRLR_WRR_SUPPORTED` was added to indicate the controller
can support weighted round robin arbitration feature with submission queue.

Added `arbitration_burst` option for arbitration feature, and added three
`low/medium/high_priority_weight` options for weighted round robin arbitration.

### iSCSI

Portals may no longer be associated with a cpumask. The scheduling of
+28 −0
Original line number Diff line number Diff line
@@ -81,6 +81,34 @@ struct spdk_nvme_ctrlr_opts {
	 */
	enum spdk_nvme_cc_ams arb_mechanism;

	/**
	 * Maximum number of commands that the controller may launch at one time.  The
	 * value is expressed as a power of two, valid values are from 0-7, and 7 means
	 * unlimited.
	 */
	uint8_t arbitration_burst;

	/**
	 * Number of commands that may be executed from the low priority queue in each
	 * arbitration round.  This field is only valid when arb_mechanism is set to
	 * SPDK_NVME_CC_AMS_WRR (weighted round robin).
	 */
	uint8_t low_priority_weight;

	/**
	 * Number of commands that may be executed from the medium priority queue in each
	 * arbitration round.  This field is only valid when arb_mechanism is set to
	 * SPDK_NVME_CC_AMS_WRR (weighted round robin).
	 */
	uint8_t medium_priority_weight;

	/**
	 * Number of commands that may be executed from the high priority queue in each
	 * arbitration round.  This field is only valid when arb_mechanism is set to
	 * SPDK_NVME_CC_AMS_WRR (weighted round robin).
	 */
	uint8_t high_priority_weight;

	/**
	 * Keep alive timeout in milliseconds (0 = disabled).
	 *
+38 −0
Original line number Diff line number Diff line
@@ -515,6 +515,42 @@ nvme_ctrlr_set_intel_supported_features(struct spdk_nvme_ctrlr *ctrlr)
	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_LATENCY_TRACKING] = true;
}

static void
nvme_ctrlr_set_arbitration_feature(struct spdk_nvme_ctrlr *ctrlr)
{
	uint32_t cdw11;
	struct nvme_completion_poll_status status;

	if (ctrlr->opts.arbitration_burst == 0) {
		return;
	}

	if (ctrlr->opts.arbitration_burst > 7) {
		SPDK_WARNLOG("Valid arbitration burst values is from 0-7\n");
		return;
	}

	cdw11 = ctrlr->opts.arbitration_burst;

	if (spdk_nvme_ctrlr_get_flags(ctrlr) & SPDK_NVME_CTRLR_WRR_SUPPORTED) {
		cdw11 |= (uint32_t)ctrlr->opts.low_priority_weight << 8;
		cdw11 |= (uint32_t)ctrlr->opts.medium_priority_weight << 16;
		cdw11 |= (uint32_t)ctrlr->opts.high_priority_weight << 24;
	}

	if (spdk_nvme_ctrlr_cmd_set_feature(ctrlr, SPDK_NVME_FEAT_ARBITRATION,
					    cdw11, 0, NULL, 0,
					    nvme_completion_poll_cb, &status) < 0) {
		SPDK_ERRLOG("Set arbitration feature failed\n");
		return;
	}

	if (spdk_nvme_wait_for_completion_timeout(ctrlr->adminq, &status,
			ctrlr->opts.admin_timeout_ms / 1000)) {
		SPDK_ERRLOG("Timeout to set arbitration feature\n");
	}
}

static void
nvme_ctrlr_set_supported_features(struct spdk_nvme_ctrlr *ctrlr)
{
@@ -542,6 +578,8 @@ nvme_ctrlr_set_supported_features(struct spdk_nvme_ctrlr *ctrlr)
	if (ctrlr->cdata.vid == SPDK_PCI_VID_INTEL) {
		nvme_ctrlr_set_intel_supported_features(ctrlr);
	}

	nvme_ctrlr_set_arbitration_feature(ctrlr);
}

void