[PATCH 2/5] scsi: elx: efct: free the HIO when the WQE cannot be built

Ali Ahmet Memis <[email protected]>
Newsgroups org.kernel.vger.target-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-scsi
Message-ID <[email protected]>
efct_els_hw_srrs_send() and efct_hw_bls_send() allocate an HIO, ask sli4
to build a WQE into it, and give up when that fails without putting the
HIO back:

	if (sli_els_request64_wqe(&hw->sli, hio->wqe.wqebuf, hio->sgl,
				  &els_params)) {
		efc_log_err(hw->os, "REQ WQE error\n");
		rc = -EIO;
	}

Nothing has been submitted at that point, so no completion will arrive to
release it, and the entry sits on hw->io_inuse until the adapter is torn
down. Each failure costs the pool one entry, and once it is empty
efct_hw_io_alloc() fails and no further ELS, CT or BLS frame can be sent.

Release the HIO on those paths. The efct_hw_wq_write() failure below is
deliberately left alone: it can return an error while this request is
still queued on wq->pending_list, so the HIO cannot be handed back there
without more care.

Fixes: dd53d333aadb ("scsi: elx: efct: Hardware I/O submission routines")
Signed-off-by: Ali Ahmet Memis <[email protected]>
---
 drivers/scsi/elx/efct/efct_hw.c | 38 ++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/elx/efct/efct_hw.c b/drivers/scsi/elx/efct/efct_hw.c
index 15c37ff1d52e..6cc48fa3e656 100644
--- a/drivers/scsi/elx/efct/efct_hw.c
+++ b/drivers/scsi/elx/efct/efct_hw.c
@@ -2609,6 +2609,7 @@ efct_hw_bls_send(struct efct *efct, u32 type, struct sli_bls_params *bls_params,
 	if (sli_xmit_bls_rsp64_wqe(&hw->sli, hio->wqe.wqebuf,
 				   &bls, bls_params)) {
 		efc_log_err(hw->os, "XMIT_BLS_RSP64 WQE error\n");
+		efct_hw_io_free(hw, hio);
 		return -EIO;
 	}
 
@@ -2820,24 +2821,27 @@ efct_els_hw_srrs_send(struct efc *efc, struct efc_disc_io *io)
 		rc = -EIO;
 	}
 
-	if (rc == 0) {
-		hio->xbusy = true;
+	if (rc) {
+		efct_hw_io_free(hw, hio);
+		return rc;
+	}
 
-		/*
-		 * Add IO to active io wqe list before submitting, in case the
-		 * wcqe processing preempts this thread.
-		 */
-		hio->wq->use_count++;
-		rc = efct_hw_wq_write(hio->wq, &hio->wqe);
-		if (rc >= 0) {
-			/* non-negative return is success */
-			rc = 0;
-		} else {
-			/* failed to write wqe, remove from active wqe list */
-			efc_log_err(hw->os,
-				    "sli_queue_write failed: %d\n", rc);
-			hio->xbusy = false;
-		}
+	hio->xbusy = true;
+
+	/*
+	 * Add IO to active io wqe list before submitting, in case the
+	 * wcqe processing preempts this thread.
+	 */
+	hio->wq->use_count++;
+	rc = efct_hw_wq_write(hio->wq, &hio->wqe);
+	if (rc >= 0) {
+		/* non-negative return is success */
+		rc = 0;
+	} else {
+		/* failed to write wqe, remove from active wqe list */
+		efc_log_err(hw->os,
+			    "sli_queue_write failed: %d\n", rc);
+		hio->xbusy = false;
 	}
 
 	return rc;
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.