[PATCH 1/5] scsi: elx: efct: check the HW state before allocating an HIO

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() takes an HIO from the pool and only then looks at
hw->state, returning without giving it back when the HW is not active:

	hio = efct_hw_io_alloc(hw);
	if (!hio) {
		pr_err("HIO alloc failed\n");
		return -EIO;
	}

	if (hw->state != EFCT_HW_STATE_ACTIVE) {
		efc_log_debug(hw->os,
			      "cannot send SRRS, HW state=%d\n", hw->state);
		return -EIO;
	}

_efct_hw_io_alloc() moves the entry from hw->io_free to hw->io_inuse and
initialises its reference, and the only thing that puts it back is the
completion of a submitted WQE. Nothing is submitted here, so the entry
stays on hw->io_inuse for the lifetime of the adapter. The memory is
reclaimed in efct_hw_teardown(), which frees hw->io[] as a whole, but the
pool loses one usable entry for every ELS or CT send that takes this
path. Once it is empty efct_hw_io_alloc() starts failing and no further
ELS or CT traffic can be sent.

Check the state first, the way efct_hw_bls_send() already does.

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 | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/elx/efct/efct_hw.c b/drivers/scsi/elx/efct/efct_hw.c
index b79c6a7ea791..15c37ff1d52e 100644
--- a/drivers/scsi/elx/efct/efct_hw.c
+++ b/drivers/scsi/elx/efct/efct_hw.c
@@ -2706,18 +2706,18 @@ efct_els_hw_srrs_send(struct efc *efc, struct efc_disc_io *io)
 	u32 sge0_flags;
 	u32 sge1_flags;
 
-	hio = efct_hw_io_alloc(hw);
-	if (!hio) {
-		pr_err("HIO alloc failed\n");
-		return -EIO;
-	}
-
 	if (hw->state != EFCT_HW_STATE_ACTIVE) {
 		efc_log_debug(hw->os,
 			      "cannot send SRRS, HW state=%d\n", hw->state);
 		return -EIO;
 	}
 
+	hio = efct_hw_io_alloc(hw);
+	if (!hio) {
+		pr_err("HIO alloc failed\n");
+		return -EIO;
+	}
+
 	hio->done = efct_els_ssrs_send_cb;
 	hio->arg  = io;
 
-- 
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.