Re: [PATCH 2/2] qla2xxx: Kick target ATIO queue after qla2x00_abort_isp completion

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

 



Does this really have to be so hard?

First of all I'm not sure I understand the changes about interrupt
handling / IS_NOPOLLING_TYPE -- I don't see how we go back to legacy
interrupt mode, since MSI-X is still enabled as far as I can tell.  In
any case what's wrong with getting interrupts during the restart?

Also why do we need to move the "online=1" out of restart_isp?  I
haven't tried the stress test you did, but it seemed to work in my
testing just to add a call to process the atio queue right after the
existing "online=1" assignment.  The patch that I came up with
(independent of yours and probably not as rigorously tested) is the
following, which is pretty small if you leave out the debugging check
junk I put in:

--- linux-2.6.git.orig/drivers/scsi/qla2xxx/qla_def.h	2011-09-25
22:08:59.026884599 -0700
+++ linux-2.6.git/drivers/scsi/qla2xxx/qla_def.h	2011-09-25
22:09:32.996971614 -0700
@@ -2886,6 +2886,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;
--- linux-2.6.git.orig/drivers/scsi/qla2xxx/qla_init.c	2011-09-25
22:10:17.357085241 -0700
+++ linux-2.6.git/drivers/scsi/qla2xxx/qla_init.c	2011-09-25
22:13:46.467620871 -0700
@@ -498,6 +498,7 @@ qla2x00_initialize_adapter(scsi_qla_host

 	/* 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;
@@ -4248,6 +4249,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)) {
@@ -4272,6 +4274,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 {
--- linux-2.6.git.orig/drivers/scsi/qla2xxx/qla_target.c	2011-09-25
22:07:24.917072474 -0700
+++ linux-2.6.git/drivers/scsi/qla2xxx/qla_target.c	2011-09-25
22:10:03.537049841 -0700
@@ -5340,8 +5340,11 @@ qla_tgt_24xx_process_atio_queue(struct s
 	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;


On Sun, Sep 25, 2011 at 9:26 PM, Nicholas A. Bellinger
<nab@xxxxxxxxxxxxxxx> wrote:
> From: Nicholas Bellinger <nab@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 v2 patch takes a different approach than v1, which originally tried to
> allow ATIO ring processing in qla_tgt_24xx_process_atio_queue() during
> qla2x00_abort_isp() reset operation.  This patch:
>
> *) Keep !vha->flags.online check in qla_tgt_24xx_process_atio_queue() to
>   prevent all ATIO ring processing during qla2x00_abort_isp() reset.
> *) Prevent vha->flags.online = 1 from being set during qla2x00_abort_isp()
>   and qla2x00_restart_isp() processing.
> *) Set vha->flags.online = 1 upon the completion of qla2x00_abort_isp(),
>   and make a direct call into qla_tgt_24xx_process_atio_queue() from
>   qla2x00_do_dpc() process context to handle ATIO packets that have
>   accumulated during qla2x00_abort_isp().
> *) Add extra paranoid qla_tgt_mode_enabled_base_vha() checks around
>   existing IS_NOPOLLING_TYPE() usage in qla2x00_mailbox_command(),
>   qla24xx_disable_intrs() and qla24xx_reset_risc().  This allows
>   target mode to run in legacy interrupt mode for mailbox commands
>   during qla2x00_abort_isp() reset, and allows qla24xx_disable_intrs()
>   to clear qla_hw_data->interrupts_on during reset.
>
> 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.
>
> Reported-by: Roland Dreier <roland@xxxxxxxxxxxxxxx>
> Cc: Roland Dreier <roland@xxxxxxxxxxxxxxx>
> Reported-by: Patrick Lee <patrick@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_init.c   |   20 +++++++++++++++++---
>  drivers/scsi/qla2xxx/qla_mbx.c    |    7 ++++---
>  drivers/scsi/qla2xxx/qla_os.c     |    2 +-
>  drivers/scsi/qla2xxx/qla_target.c |    8 +++++++-
>  drivers/scsi/qla2xxx/qla_target.h |    8 ++++++++
>  5 files changed, 37 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index fca50d5..de8810d 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -1068,7 +1068,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
>
>        spin_unlock_irqrestore(&ha->hardware_lock, flags);
>
> -       if (IS_NOPOLLING_TYPE(ha))
> +       if (IS_NOPOLLING_TYPE(ha) && !qla_tgt_mode_enabled_base_vha(ha))
>                ha->isp_ops->enable_intrs(ha);
>  }
>
> @@ -4133,7 +4133,8 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
>                                vha->marker_needed = 1;
>                        }
>
> -                       vha->flags.online = 1;
> +                       if (!qla_tgt_mode_enabled(vha))
> +                               vha->flags.online = 1;
>
>                        qla_tgt_abort_isp(vha);
>
> @@ -4229,6 +4230,17 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
>                        }
>                }
>                spin_unlock_irqrestore(&ha->vport_slock, flags);
> +               /*
> +                * For target mode, wait until the last moment to set the
> +                * online flag and kick the ATIO ring to process new packets
> +                * that have accumulated during qla2x00_abort_isp().
> +                */
> +               if (qla_tgt_mode_enabled(vha)) {
> +                       spin_lock_irqsave(&ha->hardware_lock, flags);
> +                       vha->flags.online = 1;
> +                       qla_tgt_24xx_process_atio_queue(vha);
> +                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
> +               }
>
>        } else {
>                qla_printk(KERN_INFO, ha,
> @@ -4279,7 +4291,9 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
>                        /* Issue a marker after FW becomes ready. */
>                        qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
>
> -                       vha->flags.online = 1;
> +                       if (!qla_tgt_mode_enabled(vha))
> +                               vha->flags.online = 1;
> +
>                        /* Wait at most MAX_TARGET RSCNs for a stable link. */
>                        wait_time = 256;
>                        do {
> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
> index 087b2cc..3813306 100644
> --- a/drivers/scsi/qla2xxx/qla_mbx.c
> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
> @@ -148,7 +148,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
>
>        /* Wait for mbx cmd completion until timeout */
>
> -       if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
> +       if ((!abort_active && io_lock_on) ||
> +           (IS_NOPOLLING_TYPE(ha) && !qla_tgt_mode_enabled_base_vha(ha))) {
>                set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
>
>                if (IS_QLA82XX(ha)) {
> @@ -278,8 +279,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
>
>        /* Clean up */
>        ha->mcp = NULL;
> -
> -       if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
> +       if ((abort_active || !io_lock_on) &&
> +           (!IS_NOPOLLING_TYPE(ha) || qla_tgt_mode_enabled_base_vha(ha))) {
>                DEBUG11(printk("%s(%ld): checking for additional resp "
>                    "interrupt.\n", __func__, base_vha->host_no));
>
> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
> index 2ab9564..0b61ca7 100644
> --- a/drivers/scsi/qla2xxx/qla_os.c
> +++ b/drivers/scsi/qla2xxx/qla_os.c
> @@ -1486,7 +1486,7 @@ qla24xx_disable_intrs(struct qla_hw_data *ha)
>        unsigned long flags = 0;
>        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
>
> -       if (IS_NOPOLLING_TYPE(ha))
> +       if (IS_NOPOLLING_TYPE(ha) && !qla_tgt_mode_enabled_base_vha(ha))
>                return;
>        spin_lock_irqsave(&ha->hardware_lock, flags);
>        ha->interrupts_on = 0;
> diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
> index 757e971..f26b743 100644
> --- a/drivers/scsi/qla2xxx/qla_target.c
> +++ b/drivers/scsi/qla2xxx/qla_target.c
> @@ -5328,7 +5328,13 @@ qla_tgt_24xx_process_atio_queue(struct scsi_qla_host *vha)
>        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
>        atio_t *pkt;
>        int cnt, i;
> -
> +       /*
> +        * During qla2x00_abort_isp() we expect to hit this check in order
> +        * to prevent processing during reset.  Upon completion of reset,
> +        * qla2x00_abort_isp() will set vha->flags.online=1 and make a
> +        * direct call to qla_tgt_24xx_process_atio_queue() to kick off
> +        * ATIO ring processing from qla2x00_do_dpc() process context.
> +        */
>        if (!vha->flags.online)
>                return;
>
> diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
> index 42d5479..e89a7e3 100644
> --- a/drivers/scsi/qla2xxx/qla_target.h
> +++ b/drivers/scsi/qla2xxx/qla_target.h
> @@ -1023,6 +1023,14 @@ static inline bool qla_tgt_mode_enabled(struct scsi_qla_host *ha)
>        return ha->host->active_mode & MODE_TARGET;
>  }
>
> +static inline bool qla_tgt_mode_enabled_base_vha(struct qla_hw_data *hw)
> +{
> +       if (!hw->qla_tgt || !hw->qla_tgt->vha)
> +               return false;
> +
> +       return qla_tgt_mode_enabled(hw->qla_tgt->vha);
> +}
> +
>  static inline bool qla_ini_mode_enabled(struct scsi_qla_host *ha)
>  {
>        return ha->host->active_mode & MODE_INITIATOR;
> --
> 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