From a73bad3ed22f39de907f7a325ede4c55367ba8fb Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 28 Mar 2020 16:24:43 -0400 Subject: [PATCH] nvme_disk: Add locking around request queue access. Should help with #15123 further. --- .../drivers/disk/nvme/libnvme/nvme_internal.h | 1 + .../drivers/disk/nvme/libnvme/nvme_qpair.c | 6 ++++-- .../drivers/disk/nvme/libnvme/nvme_request.c | 19 +++++++++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_internal.h b/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_internal.h index 5b0b45b8e9..01bc052575 100644 --- a/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_internal.h +++ b/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_internal.h @@ -708,6 +708,7 @@ nvme_request_allocate_contig(struct nvme_qpair *qpair, nvme_cmd_cb cb_fn, void *cb_arg); extern void nvme_request_free(struct nvme_request *req); +extern void nvme_request_free_locked(struct nvme_request *req); extern void nvme_request_add_child(struct nvme_request *parent, struct nvme_request *child); diff --git a/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_qpair.c b/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_qpair.c index 33854d42a4..9998389075 100644 --- a/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_qpair.c +++ b/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_qpair.c @@ -401,7 +401,7 @@ static void nvme_qpair_complete_tracker(struct nvme_qpair *qpair, if (req->cb_fn) req->cb_fn(req->cb_arg, cpl); - nvme_request_free(req); + nvme_request_free_locked(req); done: tr->req = NULL; @@ -418,6 +418,8 @@ done: !qpair->ctrlr->resetting) { req = STAILQ_FIRST(&qpair->queued_req); STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq); + + pthread_mutex_unlock(&qpair->lock); nvme_qpair_submit_request(qpair, req); } } @@ -464,7 +466,7 @@ static void nvme_qpair_manual_complete_request(struct nvme_qpair *qpair, if (req->cb_fn) req->cb_fn(req->cb_arg, &cpl); - nvme_request_free(req); + nvme_request_free_locked(req); } static void nvme_qpair_abort_aers(struct nvme_qpair *qpair) diff --git a/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_request.c b/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_request.c index 9ca24452d4..b246d27bd8 100644 --- a/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_request.c +++ b/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_request.c @@ -40,12 +40,16 @@ static struct nvme_request *nvme_alloc_request(struct nvme_qpair *qpair) { struct nvme_request *req; + pthread_mutex_lock(&qpair->lock); + req = STAILQ_FIRST(&qpair->free_req); if (req) { STAILQ_REMOVE_HEAD(&qpair->free_req, stailq); memset(&req->cmd, 0, sizeof(struct nvme_cmd)); } + pthread_mutex_unlock(&qpair->lock); + return req; } @@ -169,13 +173,20 @@ struct nvme_request *nvme_request_allocate_null(struct nvme_qpair *qpair, return nvme_request_allocate_contig(qpair, NULL, 0, cb_fn, cb_arg); } -void nvme_request_free(struct nvme_request *req) +void nvme_request_free_locked(struct nvme_request *req) { - struct nvme_qpair *qpair = req->qpair; - nvme_assert(req->child_reqs == 0, "Number of child request not 0\n"); - STAILQ_INSERT_HEAD(&qpair->free_req, req, stailq); + STAILQ_INSERT_HEAD(&req->qpair->free_req, req, stailq); +} + +void nvme_request_free(struct nvme_request *req) +{ + pthread_mutex_lock(&req->qpair->lock); + + nvme_request_free_locked(req); + + pthread_mutex_unlock(&req->qpair->lock); } void nvme_request_add_child(struct nvme_request *parent,