[PATCH-v2] qla2xxx: Kick target ATIO queue after qla2x00_fw_ready() completion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Roland Dreier <roland@xxxxxxxxxxxxxxx>

This patch addresses an issue between the assignment of vha->flags.online = 1
to signal operational status in process context via qla2x00_do_dpc() ->
qla2x00_abort_isp() -> qla2x00_restart_isp(), and processing of individual
ATIO packets in interrupt context within qla_tgt_24xx_process_atio_queue().
This was causing qla_tgt_24xx_process_atio_queue() to explictly ignore
new packets with non-operational status before completion of qla2x00_restart_isp()
-> target mode operation transition, and more specifically ELS packets
that are expected to drive the re-creation of active qla_tgt_sess nexuses in
qla_target.c + tcm_qla2xxx code.

This v3 patch is a simplified version that sets scsi_qla_host->atio_ignored
during reset when qla_tgt_24xx_process_atio_queue() is invoked from interrupt
handler context, and then makes the direct call once vha->flags.online is set
upon completion of qla2x00_fw_ready() within qla2x00_restart_isp() from
process context.

This patch also depends upon 'Disable initial LIP' being cleared within
qla_tgt_24xx_config_nvram_stage1() for firmware_options_1:

        /* Enable initial LIP */
        nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_9);

Enabling this bit to 'Disable initial LIP' ends up causing intermittent
reset hangs with target mode operation, eventually causing the port to
be taken offline.

Signed-off-by: Roland Dreier <roland@xxxxxxxxxxxxxxx>
Cc: Patrick Lee <patrick@xxxxxxxxxxxxxxx>
Cc: Andrew Vasquez <andrew.vasquez@xxxxxxxxxx>
Cc: Madhuranath Iyengar <mni@xxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxxxxxxxx>
---
 drivers/scsi/qla2xxx/qla_def.h    |    1 +
 drivers/scsi/qla2xxx/qla_init.c   |   15 +++++++++++++++
 drivers/scsi/qla2xxx/qla_target.c |    5 ++++-
 3 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c584c11..0e63bbf 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2894,6 +2894,7 @@ typedef struct scsi_qla_host {
 		uint32_t	online			:1;
 		uint32_t	rscn_queue_overflow	:1;
 		uint32_t	reset_active		:1;
+		uint32_t	atio_ignored		:1;
 
 		uint32_t	management_server_logged_in :1;
 		uint32_t	process_response_queue	:1;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index fca50d5..032c2fb 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -506,6 +506,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
 
 	/* Clear adapter flags. */
 	vha->flags.online = 0;
+	vha->flags.atio_ignored = 0;
 	ha->flags.chip_reset_done = 0;
 	vha->flags.reset_active = 0;
 	ha->flags.pci_channel_io_perm_failure = 0;
@@ -4256,6 +4257,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req = ha->req_q_map[0];
 	struct rsp_que *rsp = ha->rsp_q_map[0];
+	unsigned long flags;
 
 	/* If firmware needs to be loaded */
 	if (qla2x00_isp_firmware(vha)) {
@@ -4280,6 +4282,19 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
 			qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
 
 			vha->flags.online = 1;
+
+			/*
+			 * Process any ATIO queue entries that came in
+			 * while we weren't online.
+			 */
+			spin_lock_irqsave(&ha->hardware_lock, flags);
+			if (vha->flags.atio_ignored) {
+				qla_printk(KERN_INFO, ha, "Processing ignored ATIO entries\n");
+				vha->flags.atio_ignored = 0;
+			}
+			qla_tgt_24xx_process_atio_queue(vha);
+			spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
 			/* Wait at most MAX_TARGET RSCNs for a stable link. */
 			wait_time = 256;
 			do {
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 757e971..5f0f335 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5329,8 +5329,11 @@ qla_tgt_24xx_process_atio_queue(struct scsi_qla_host *vha)
 	atio_t *pkt;
 	int cnt, i;
 
-	if (!vha->flags.online)
+	if (!vha->flags.online) {
+		vha->flags.atio_ignored = 1;
+		qla_printk(KERN_INFO, ha, "ATIO entry ignored because online == 0\n");
 		return;
+	}
 
 	while (ha->atio_ring_ptr->signature != ATIO_PROCESSED) {
 		pkt = ha->atio_ring_ptr;
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux