nvme: cache CAP register in spdk_nvme_ctrlr
The value of CAP should not change during the lifetime of a controller, so read it once during ctrlr_construct and store it in the ctrlr. Change-Id: I089d4141b4e0c9aae6c53abf9bb0ef6577dabe0b Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
a987bd16c2
commit
76469b2cf7
@ -381,12 +381,6 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
|
||||
{
|
||||
union spdk_nvme_cc_register cc;
|
||||
union spdk_nvme_aqa_register aqa;
|
||||
union spdk_nvme_cap_register cap;
|
||||
|
||||
if (nvme_ctrlr_get_cap(ctrlr, &cap)) {
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVME, "get_cap() failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (nvme_ctrlr_get_cc(ctrlr, &cc)) {
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVME, "get_cc() failed\n");
|
||||
@ -431,12 +425,12 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
|
||||
case SPDK_NVME_CC_AMS_RR:
|
||||
break;
|
||||
case SPDK_NVME_CC_AMS_WRR:
|
||||
if (SPDK_NVME_CAP_AMS_WRR & cap.bits.ams) {
|
||||
if (SPDK_NVME_CAP_AMS_WRR & ctrlr->cap.bits.ams) {
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
case SPDK_NVME_CC_AMS_VS:
|
||||
if (SPDK_NVME_CAP_AMS_VS & cap.bits.ams) {
|
||||
if (SPDK_NVME_CAP_AMS_VS & ctrlr->cap.bits.ams) {
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
@ -781,19 +775,17 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
|
||||
{
|
||||
union spdk_nvme_cc_register cc;
|
||||
union spdk_nvme_csts_register csts;
|
||||
union spdk_nvme_cap_register cap;
|
||||
uint32_t ready_timeout_in_ms;
|
||||
int rc;
|
||||
|
||||
if (nvme_ctrlr_get_cc(ctrlr, &cc) ||
|
||||
nvme_ctrlr_get_csts(ctrlr, &csts) ||
|
||||
nvme_ctrlr_get_cap(ctrlr, &cap)) {
|
||||
nvme_ctrlr_get_csts(ctrlr, &csts)) {
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVME, "get registers failed\n");
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ready_timeout_in_ms = 500 * cap.bits.to;
|
||||
ready_timeout_in_ms = 500 * ctrlr->cap.bits.to;
|
||||
|
||||
/*
|
||||
* Check if the current initialization step is done or has timed out.
|
||||
@ -946,19 +938,13 @@ nvme_mutex_init_recursive_shared(pthread_mutex_t *mtx)
|
||||
int
|
||||
nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr)
|
||||
{
|
||||
union spdk_nvme_cap_register cap;
|
||||
int rc;
|
||||
|
||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_INIT, NVME_TIMEOUT_INFINITE);
|
||||
ctrlr->flags = 0;
|
||||
ctrlr->free_io_qids = NULL;
|
||||
|
||||
if (nvme_ctrlr_get_cap(ctrlr, &cap)) {
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVME, "get_cap() failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ctrlr->min_page_size = 1 << (12 + cap.bits.mpsmin);
|
||||
ctrlr->min_page_size = 1 << (12 + ctrlr->cap.bits.mpsmin);
|
||||
|
||||
rc = nvme_ctrlr_construct_admin_qpair(ctrlr);
|
||||
if (rc)
|
||||
@ -1027,12 +1013,7 @@ spdk_nvme_ctrlr_get_data(struct spdk_nvme_ctrlr *ctrlr)
|
||||
|
||||
union spdk_nvme_cap_register spdk_nvme_ctrlr_get_regs_cap(struct spdk_nvme_ctrlr *ctrlr)
|
||||
{
|
||||
union spdk_nvme_cap_register cap;
|
||||
|
||||
if (nvme_ctrlr_get_cap(ctrlr, &cap)) {
|
||||
cap.raw = 0;
|
||||
}
|
||||
return cap;
|
||||
return ctrlr->cap;
|
||||
}
|
||||
|
||||
union spdk_nvme_vs_register spdk_nvme_ctrlr_get_regs_vs(struct spdk_nvme_ctrlr *ctrlr)
|
||||
|
@ -436,6 +436,8 @@ struct spdk_nvme_ctrlr {
|
||||
|
||||
/* Cold data (not accessed in normal I/O path) is after this point. */
|
||||
|
||||
union spdk_nvme_cap_register cap;
|
||||
|
||||
enum nvme_ctrlr_state state;
|
||||
uint64_t state_timeout_tsc;
|
||||
|
||||
|
@ -312,6 +312,8 @@ static struct spdk_nvme_ctrlr *nvme_pcie_ctrlr_construct(void *devhandle)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pctrlr->ctrlr.cap = cap;
|
||||
|
||||
/* Doorbell stride is 2 ^ (dstrd + 2),
|
||||
* but we want multiples of 4, so drop the + 2 */
|
||||
pctrlr->doorbell_stride_u32 = 1 << cap.bits.dstrd;
|
||||
@ -838,17 +840,11 @@ nvme_pcie_ctrlr_create_io_qpair(struct spdk_nvme_ctrlr *ctrlr, uint16_t qid,
|
||||
enum spdk_nvme_qprio qprio)
|
||||
{
|
||||
struct spdk_nvme_qpair *qpair;
|
||||
union spdk_nvme_cap_register cap;
|
||||
uint32_t num_entries;
|
||||
int rc;
|
||||
|
||||
assert(ctrlr != NULL);
|
||||
|
||||
if (nvme_ctrlr_get_cap(ctrlr, &cap)) {
|
||||
SPDK_TRACELOG(SPDK_TRACE_NVME, "get_cap() failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qpair = calloc(1, sizeof(*qpair));
|
||||
if (qpair == NULL) {
|
||||
return NULL;
|
||||
@ -862,7 +858,7 @@ nvme_pcie_ctrlr_create_io_qpair(struct spdk_nvme_ctrlr *ctrlr, uint16_t qid,
|
||||
* devices may specify a smaller limit, so we need to check
|
||||
* the MQES field in the capabilities register.
|
||||
*/
|
||||
num_entries = nvme_min(NVME_IO_ENTRIES, cap.bits.mqes + 1);
|
||||
num_entries = nvme_min(NVME_IO_ENTRIES, ctrlr->cap.bits.mqes + 1);
|
||||
|
||||
rc = nvme_qpair_construct(qpair, qid, num_entries, ctrlr);
|
||||
if (rc != 0) {
|
||||
|
@ -475,6 +475,7 @@ test_nvme_ctrlr_init_en_0_rdy_0_ams_rr(void)
|
||||
* Default round robin enabled
|
||||
*/
|
||||
g_ut_nvme_regs.cap.bits.ams = 0x0;
|
||||
ctrlr.cap = g_ut_nvme_regs.cap;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr) == 0);
|
||||
ctrlr.cdata.nn = 1;
|
||||
@ -606,6 +607,7 @@ test_nvme_ctrlr_init_en_0_rdy_0_ams_wrr(void)
|
||||
* Weighted round robin enabled
|
||||
*/
|
||||
g_ut_nvme_regs.cap.bits.ams = SPDK_NVME_CAP_AMS_WRR;
|
||||
ctrlr.cap = g_ut_nvme_regs.cap;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr) == 0);
|
||||
ctrlr.cdata.nn = 1;
|
||||
@ -738,6 +740,7 @@ test_nvme_ctrlr_init_en_0_rdy_0_ams_vs(void)
|
||||
* Default round robin enabled
|
||||
*/
|
||||
g_ut_nvme_regs.cap.bits.ams = SPDK_NVME_CAP_AMS_VS;
|
||||
ctrlr.cap = g_ut_nvme_regs.cap;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr) == 0);
|
||||
ctrlr.cdata.nn = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user