nvme: acquire ctrlr_lock when submitting and completing admin IOs

Change-Id: I19f395d1859f75a665a1a0cd7bef1d88ebb15631
Signed-off-by: GangCao <gang.cao@intel.com>
This commit is contained in:
GangCao 2016-11-22 04:31:46 -05:00 committed by Daniel Verkamp
parent c61bd850f0
commit 3c11422403

View File

@ -721,6 +721,9 @@ nvme_pcie_copy_command(struct spdk_nvme_cmd *dst, const struct spdk_nvme_cmd *sr
#endif #endif
} }
/**
* Note: the ctrlr_lock must be held when calling this function.
*/
static void static void
nvme_pcie_qpair_insert_pending_admin_request(struct spdk_nvme_qpair *qpair, nvme_pcie_qpair_insert_pending_admin_request(struct spdk_nvme_qpair *qpair,
struct nvme_request *req, struct spdk_nvme_cpl *cpl) 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(nvme_qpair_is_admin_queue(qpair));
assert(active_req->pid != getpid()); 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) { TAILQ_FOREACH_SAFE(active_proc, &ctrlr->active_procs, tailq, tmp) {
if (active_proc->pid == active_req->pid) { if (active_proc->pid == active_req->pid) {
/* Saved the original completion information */ /* 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) { if (pending_on_proc == false) {
SPDK_ERRLOG("The owning process is not found. Drop the request.\n"); 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 static void
nvme_pcie_qpair_complete_pending_admin_request(struct spdk_nvme_qpair *qpair) 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)); 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) { TAILQ_FOREACH(proc, &ctrlr->active_procs, tailq) {
if (proc->pid == pid) { if (proc->pid == pid) {
proc_found = true; 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) { if (proc_found == false) {
SPDK_ERRLOG("the active process is not found for this controller."); SPDK_ERRLOG("the active process is not found for this controller.");
assert(proc_found); assert(proc_found);
@ -1534,12 +1530,16 @@ int
nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req) nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req)
{ {
struct nvme_tracker *tr; struct nvme_tracker *tr;
int rc; int rc = 0;
struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr; struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr;
struct nvme_pcie_qpair *pqpair = nvme_pcie_qpair(qpair); struct nvme_pcie_qpair *pqpair = nvme_pcie_qpair(qpair);
nvme_pcie_qpair_check_enabled(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); tr = LIST_FIRST(&pqpair->free_tr);
if (tr == NULL || !pqpair->is_enabled) { if (tr == NULL || !pqpair->is_enabled) {
@ -1553,7 +1553,7 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
* completed. * completed.
*/ */
STAILQ_INSERT_TAIL(&qpair->queued_req, req, stailq); STAILQ_INSERT_TAIL(&qpair->queued_req, req, stailq);
return 0; goto exit;
} }
LIST_REMOVE(tr, list); /* remove tr from free_tr */ 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) { if (rc < 0) {
return rc; goto exit;
} }
nvme_pcie_qpair_submit_tracker(qpair, tr); 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 int32_t
@ -1593,6 +1599,7 @@ nvme_pcie_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_
struct nvme_tracker *tr; struct nvme_tracker *tr;
struct spdk_nvme_cpl *cpl; struct spdk_nvme_cpl *cpl;
uint32_t num_completions = 0; uint32_t num_completions = 0;
struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr;
if (!nvme_pcie_qpair_check_enabled(qpair)) { 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; 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))) { 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. */ /* Before returning, complete any pending admin request. */
if (nvme_qpair_is_admin_queue(qpair)) { if (nvme_qpair_is_admin_queue(qpair)) {
nvme_pcie_qpair_complete_pending_admin_request(qpair); nvme_pcie_qpair_complete_pending_admin_request(qpair);
pthread_mutex_unlock(&ctrlr->ctrlr_lock);
} }
return num_completions; return num_completions;