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: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466852
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Changpeng Liu 2019-08-29 04:11:20 -04:00
parent 8a857a3b30
commit acb9849c05
3 changed files with 69 additions and 0 deletions

View File

@ -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

View File

@ -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).
*

View File

@ -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