Commit 3c114224 authored by GangCao's avatar GangCao Committed by Daniel Verkamp
Browse files

nvme: acquire ctrlr_lock when submitting and completing admin IOs



Change-Id: I19f395d1859f75a665a1a0cd7bef1d88ebb15631
Signed-off-by: default avatarGangCao <gang.cao@intel.com>
parent c61bd850
Loading
Loading
Loading
Loading
+31 −18
Original line number Diff line number Diff line
@@ -721,6 +721,9 @@ nvme_pcie_copy_command(struct spdk_nvme_cmd *dst, const struct spdk_nvme_cmd *sr
#endif
}

/**
 * Note: the ctrlr_lock must be held when calling this function.
 */
static void
nvme_pcie_qpair_insert_pending_admin_request(struct spdk_nvme_qpair *qpair,
		struct nvme_request *req, struct spdk_nvme_cpl *cpl)
@@ -737,9 +740,6 @@ nvme_pcie_qpair_insert_pending_admin_request(struct spdk_nvme_qpair *qpair,
	assert(nvme_qpair_is_admin_queue(qpair));
	assert(active_req->pid != getpid());

	/* Acquire the recursive lock first if not held already. */
	pthread_mutex_lock(&ctrlr->ctrlr_lock);

	TAILQ_FOREACH_SAFE(active_proc, &ctrlr->active_procs, tailq, tmp) {
		if (active_proc->pid == active_req->pid) {
			/* Saved the original completion information */
@@ -751,8 +751,6 @@ nvme_pcie_qpair_insert_pending_admin_request(struct spdk_nvme_qpair *qpair,
		}
	}

	pthread_mutex_unlock(&ctrlr->ctrlr_lock);

	if (pending_on_proc == false) {
		SPDK_ERRLOG("The owning process is not found. Drop the request.\n");

@@ -760,6 +758,9 @@ nvme_pcie_qpair_insert_pending_admin_request(struct spdk_nvme_qpair *qpair,
	}
}

/**
 * Note: the ctrlr_lock must be held when calling this function.
 */
static void
nvme_pcie_qpair_complete_pending_admin_request(struct spdk_nvme_qpair *qpair)
{
@@ -775,9 +776,6 @@ nvme_pcie_qpair_complete_pending_admin_request(struct spdk_nvme_qpair *qpair)
	 */
	assert(nvme_qpair_is_admin_queue(qpair));

	/* Acquire the recursive lock if not held already */
	pthread_mutex_lock(&ctrlr->ctrlr_lock);

	TAILQ_FOREACH(proc, &ctrlr->active_procs, tailq) {
		if (proc->pid == pid) {
			proc_found = true;
@@ -786,8 +784,6 @@ nvme_pcie_qpair_complete_pending_admin_request(struct spdk_nvme_qpair *qpair)
		}
	}

	pthread_mutex_unlock(&ctrlr->ctrlr_lock);

	if (proc_found == false) {
		SPDK_ERRLOG("the active process is not found for this controller.");
		assert(proc_found);
@@ -1534,12 +1530,16 @@ int
nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req)
{
	struct nvme_tracker	*tr;
	int rc;
	int			rc = 0;
	struct spdk_nvme_ctrlr	*ctrlr = qpair->ctrlr;
	struct nvme_pcie_qpair	*pqpair = nvme_pcie_qpair(qpair);

	nvme_pcie_qpair_check_enabled(qpair);

	if (nvme_qpair_is_admin_queue(qpair)) {
		pthread_mutex_lock(&ctrlr->ctrlr_lock);
	}

	tr = LIST_FIRST(&pqpair->free_tr);

	if (tr == NULL || !pqpair->is_enabled) {
@@ -1553,7 +1553,7 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
		 *  completed.
		 */
		STAILQ_INSERT_TAIL(&qpair->queued_req, req, stailq);
		return 0;
		goto exit;
	}

	LIST_REMOVE(tr, list); /* remove tr from free_tr */
@@ -1579,11 +1579,17 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
	}

	if (rc < 0) {
		return rc;
		goto exit;
	}

	nvme_pcie_qpair_submit_tracker(qpair, tr);
	return 0;

exit:
	if (nvme_qpair_is_admin_queue(qpair)) {
		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
	}

	return rc;
}

int32_t
@@ -1593,6 +1599,7 @@ nvme_pcie_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_
	struct nvme_tracker	*tr;
	struct spdk_nvme_cpl	*cpl;
	uint32_t		 num_completions = 0;
	struct spdk_nvme_ctrlr	*ctrlr = qpair->ctrlr;

	if (!nvme_pcie_qpair_check_enabled(qpair)) {
		/*
@@ -1604,6 +1611,10 @@ nvme_pcie_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_
		return 0;
	}

	if (nvme_qpair_is_admin_queue(qpair)) {
		pthread_mutex_lock(&ctrlr->ctrlr_lock);
	}

	if (max_completions == 0 || (max_completions > (qpair->num_entries - 1U))) {

		/*
@@ -1647,6 +1658,8 @@ nvme_pcie_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_
	/* Before returning, complete any pending admin request. */
	if (nvme_qpair_is_admin_queue(qpair)) {
		nvme_pcie_qpair_complete_pending_admin_request(qpair);

		pthread_mutex_unlock(&ctrlr->ctrlr_lock);
	}

	return num_completions;