nvme_disk: Further rework of qpair locking behavior.

This makes the logic, especially around queued requests,
much more robust.
This commit is contained in:
Augustin Cavalier
2020-04-20 23:50:46 -04:00
parent b6fccb7930
commit fdfb71a406
@@ -408,20 +408,27 @@ done:
LIST_REMOVE(tr, list);
LIST_INSERT_HEAD(&qpair->free_tr, tr, list);
}
static void nvme_qpair_submit_queued_requests(struct nvme_qpair *qpair)
{
pthread_mutex_lock(&qpair->lock);
/*
* If the controller is in the middle of a reset, don't
* try to submit queued requests here - let the reset logic
* try to submit queued requests - let the reset logic
* handle that instead.
*/
if (!STAILQ_EMPTY(&qpair->queued_req) &&
!qpair->ctrlr->resetting) {
req = STAILQ_FIRST(&qpair->queued_req);
while (!STAILQ_EMPTY(&qpair->queued_req) && !qpair->ctrlr->resetting) {
struct nvme_request *req = STAILQ_FIRST(&qpair->queued_req);
STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq);
pthread_mutex_unlock(&qpair->lock);
nvme_qpair_submit_request(qpair, req);
pthread_mutex_lock(&qpair->lock);
}
pthread_mutex_unlock(&qpair->lock);
}
static void nvme_qpair_manual_complete_tracker(struct nvme_qpair *qpair,
@@ -1040,6 +1047,7 @@ int nvme_qpair_submit_request(struct nvme_qpair *qpair,
* completion or when the controller reset is completed.
*/
STAILQ_INSERT_TAIL(&qpair->queued_req, req, stailq);
pthread_mutex_unlock(&qpair->lock);
return 0;
}
@@ -1134,6 +1142,9 @@ unsigned int nvme_qpair_poll(struct nvme_qpair *qpair,
pthread_mutex_unlock(&qpair->lock);
if (!STAILQ_EMPTY(&qpair->queued_req))
nvme_qpair_submit_queued_requests(qpair);
return num_completions;
}