nvme_disk: Fix nvme_qpair_submit_queued_requests.

I added this function to make the queued requests logic more robust,
but I failed to notice that since it is called from nvme_qpair_submit_request,
it would just result in a deadlock of any qpair that had requests
queued.

May help with some of the "qpair lockup" tickets.

Change-Id: I5ff63b509ae8812356d0d33f019027d3159b6685
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2735
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Augustin Cavalier 2020-05-17 19:58:00 -04:00 committed by waddlesplash
parent f37d2d10a0
commit cb53bf1e28

View File

@ -412,22 +412,30 @@ done:
static void nvme_qpair_submit_queued_requests(struct nvme_qpair *qpair)
{
STAILQ_HEAD(, nvme_request) req_queue;
STAILQ_INIT(&req_queue);
pthread_mutex_lock(&qpair->lock);
STAILQ_CONCAT(&req_queue, &qpair->queued_req);
/*
* If the controller is in the middle of a reset, don't
* try to submit queued requests - let the reset logic
* handle that instead.
*/
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);
while (!qpair->ctrlr->resetting && LIST_FIRST(&qpair->free_tr)
&& !STAILQ_EMPTY(&req_queue)) {
struct nvme_request *req = STAILQ_FIRST(&req_queue);
STAILQ_REMOVE_HEAD(&req_queue, stailq);
pthread_mutex_unlock(&qpair->lock);
nvme_qpair_submit_request(qpair, req);
pthread_mutex_lock(&qpair->lock);
}
STAILQ_CONCAT(&qpair->queued_req, &req_queue);
pthread_mutex_unlock(&qpair->lock);
}