nvme: guard admin qpair error injection queue

Admin commands can be sent and polled from any thread, which also means
that the error injection queue on the admin qpair can be accessed from
multiple threads.  Therefore, any modifications to that queue should be
done under the ctrlr lock.

Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ib1ed194405cb5b93f65a007b9749fd4433dc367d
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11099
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Michael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
Konrad Sztyber 2022-01-14 13:14:54 +01:00 committed by Tomasz Zawadzki
parent 88e676f7b1
commit a7d61bef5a
2 changed files with 21 additions and 4 deletions

View File

@ -1076,9 +1076,11 @@ spdk_nvme_qpair_add_cmd_error_injection(struct spdk_nvme_ctrlr *ctrlr,
uint8_t sct, uint8_t sc)
{
struct nvme_error_cmd *entry, *cmd = NULL;
int rc = 0;
if (qpair == NULL) {
qpair = ctrlr->adminq;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
}
TAILQ_FOREACH(entry, &qpair->err_cmd_head, link) {
@ -1091,7 +1093,8 @@ spdk_nvme_qpair_add_cmd_error_injection(struct spdk_nvme_ctrlr *ctrlr,
if (cmd == NULL) {
cmd = spdk_zmalloc(sizeof(*cmd), 64, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (!cmd) {
return -ENOMEM;
rc = -ENOMEM;
goto out;
}
TAILQ_INSERT_TAIL(&qpair->err_cmd_head, cmd, link);
}
@ -1102,8 +1105,12 @@ spdk_nvme_qpair_add_cmd_error_injection(struct spdk_nvme_ctrlr *ctrlr,
cmd->opc = opc;
cmd->status.sct = sct;
cmd->status.sc = sc;
out:
if (nvme_qpair_is_admin_queue(qpair)) {
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
}
return 0;
return rc;
}
void
@ -1115,17 +1122,20 @@ spdk_nvme_qpair_remove_cmd_error_injection(struct spdk_nvme_ctrlr *ctrlr,
if (qpair == NULL) {
qpair = ctrlr->adminq;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
}
TAILQ_FOREACH_SAFE(cmd, &qpair->err_cmd_head, link, entry) {
if (cmd->opc == opc) {
TAILQ_REMOVE(&qpair->err_cmd_head, cmd, link);
spdk_free(cmd);
return;
break;
}
}
return;
if (nvme_qpair_is_admin_queue(qpair)) {
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
}
}
uint16_t

View File

@ -445,11 +445,17 @@ test_nvme_qpair_add_cmd_error_injection(void)
{
struct spdk_nvme_qpair qpair = {};
struct spdk_nvme_ctrlr ctrlr = {};
pthread_mutexattr_t attr;
int rc;
prepare_submit_request_test(&qpair, &ctrlr);
ctrlr.adminq = &qpair;
SPDK_CU_ASSERT_FATAL(pthread_mutexattr_init(&attr) == 0);
SPDK_CU_ASSERT_FATAL(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0);
SPDK_CU_ASSERT_FATAL(pthread_mutex_init(&ctrlr.ctrlr_lock, &attr) == 0);
pthread_mutexattr_destroy(&attr);
/* Admin error injection at submission path */
MOCK_CLEAR(spdk_zmalloc);
rc = spdk_nvme_qpair_add_cmd_error_injection(&ctrlr, NULL,
@ -498,6 +504,7 @@ test_nvme_qpair_add_cmd_error_injection(void)
CU_ASSERT(TAILQ_EMPTY(&qpair.err_cmd_head));
pthread_mutex_destroy(&ctrlr.ctrlr_lock);
cleanup_submit_request_test(&qpair);
}