Commit b4692083 authored by Ziye Yang's avatar Ziye Yang Committed by Ben Walker
Browse files

nvme: Fix the race condition in nvme_ctrlr_get_cc



When the applications call spdk_nvme_ctrlr_alloc_io_qpair,
there will be cmd to the admin qpairs in nvme_ctrlr_get_cc,
so there is contention. We should use the lock to protect
nvme_ctrl_get_cc.  Otherwise, the multiple threads will have
contention on the admin qpair, thus there will be coredump issue.

We get the bug when testing NVMe-oF TCP transport, and this
patch can address this issue.

Change-Id: I7247f98cdf890c2eafaf8fb94580ecd714010bd5
Signed-off-by: default avatarZiye Yang <optimistyzy@gmail.com>
Reviewed-on: https://review.gerrithub.io/435577


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarSeth Howell <seth.howell5141@gmail.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent d6c0c192
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -248,13 +248,16 @@ spdk_nvme_ctrlr_alloc_io_qpair(struct spdk_nvme_ctrlr *ctrlr,
		memcpy(&opts, user_opts, spdk_min(sizeof(opts), opts_size));
	}

	nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
	if (nvme_ctrlr_get_cc(ctrlr, &cc)) {
		SPDK_ERRLOG("get_cc failed\n");
		nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
		return NULL;
	}

	/* Only the low 2 bits (values 0, 1, 2, 3) of QPRIO are valid. */
	if ((opts.qprio & 3) != opts.qprio) {
		nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
		return NULL;
	}

@@ -264,11 +267,10 @@ spdk_nvme_ctrlr_alloc_io_qpair(struct spdk_nvme_ctrlr *ctrlr,
	 */
	if ((cc.bits.ams == SPDK_NVME_CC_AMS_RR) && (opts.qprio != SPDK_NVME_QPRIO_URGENT)) {
		SPDK_ERRLOG("invalid queue priority for default round robin arbitration method\n");
		nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
		return NULL;
	}

	nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);

	/*
	 * Get the first available I/O queue ID.
	 */