Commit 76469b2c authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

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: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent a987bd16
Loading
Loading
Loading
Loading
+6 −25
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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;

+3 −7
Original line number Diff line number Diff line
@@ -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) {
+3 −0
Original line number Diff line number Diff line
@@ -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;