mpt3sas: Fix for Asynchronous completion of timedout IO and task abort of timedout IO.
authorSuganath prabu Subramani <suganath-prabu.subramani@avagotech.com>
Thu, 28 Jan 2016 06:37:06 +0000 (12:07 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Sep 2016 06:27:43 +0000 (08:27 +0200)
[ Upstream commit 03d1fb3a65783979f23bd58b5a0387e6992d9e26 ]

Track msix of each IO and use the same msix for issuing abort to timed
out IO. With this driver will process IO's reply first followed by TM.

Signed-off-by: Suganath prabu Subramani <suganath-prabu.subramani@avagotech.com>
Signed-off-by: Chaitra P B <chaitra.basappa@avagotech.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/mpt3sas/mpt3sas_base.h
drivers/scsi/mpt3sas/mpt3sas_ctl.c
drivers/scsi/mpt3sas/mpt3sas_scsih.c

index 9137ae2b841f8177d8971f025f3310e15e5c21c0..5b2c37f1e9080ab4c2dea4f919f13faf0d44b8f6 100644 (file)
@@ -2242,6 +2242,12 @@ mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr)
        return ioc->reply + (phys_addr - (u32)ioc->reply_dma);
 }
 
+static inline u8
+_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc)
+{
+       return ioc->cpu_msix_table[raw_smp_processor_id()];
+}
+
 /**
  * mpt3sas_base_get_smid - obtain a free smid from internal queue
  * @ioc: per adapter object
@@ -2302,6 +2308,7 @@ mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx,
        request->scmd = scmd;
        request->cb_idx = cb_idx;
        smid = request->smid;
+       request->msix_io = _base_get_msix_index(ioc);
        list_del(&request->tracker_list);
        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
        return smid;
@@ -2424,12 +2431,6 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock)
 }
 #endif
 
-static inline u8
-_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc)
-{
-       return ioc->cpu_msix_table[raw_smp_processor_id()];
-}
-
 /**
  * mpt3sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
  * @ioc: per adapter object
@@ -2483,18 +2484,19 @@ mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
  * mpt3sas_base_put_smid_hi_priority - send Task Managment request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
- *
+ * @msix_task: msix_task will be same as msix of IO incase of task abort else 0.
  * Return nothing.
  */
 void
-mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+       u16 msix_task)
 {
        Mpi2RequestDescriptorUnion_t descriptor;
        u64 *request = (u64 *)&descriptor;
 
        descriptor.HighPriority.RequestFlags =
            MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
-       descriptor.HighPriority.MSIxIndex =  0;
+       descriptor.HighPriority.MSIxIndex =  msix_task;
        descriptor.HighPriority.SMID = cpu_to_le16(smid);
        descriptor.HighPriority.LMID = 0;
        descriptor.HighPriority.Reserved1 = 0;
index 5ad271efbd45e760eabd72d8218bd6cefc6a0e23..92648a5ea2d202f715759e2eeea0e252ba3929fd 100644 (file)
@@ -643,6 +643,7 @@ struct chain_tracker {
  * @cb_idx: callback index
  * @direct_io: To indicate whether I/O is direct (WARPDRIVE)
  * @tracker_list: list of free request (ioc->free_list)
+ * @msix_io: IO's msix
  */
 struct scsiio_tracker {
        u16     smid;
@@ -651,6 +652,7 @@ struct scsiio_tracker {
        u8      direct_io;
        struct list_head chain_list;
        struct list_head tracker_list;
+       u16     msix_io;
 };
 
 /**
@@ -1213,7 +1215,8 @@ void mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid,
        u16 handle);
 void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
        u16 handle);
-void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid);
+void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc,
+       u16 smid, u16 msix_task);
 void mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 void mpt3sas_base_initialize_callback_handler(void);
 u8 mpt3sas_base_register_callback_handler(MPT_CALLBACK cb_func);
index d8366b056b70f48c046b1fcb06637f70174914ee..4ccde5a05b7010cfef1f0b8f27124d45c49c4844 100644 (file)
@@ -817,7 +817,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
                    tm_request->DevHandle));
                ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
                    data_in_dma, data_in_sz);
-               mpt3sas_base_put_smid_hi_priority(ioc, smid);
+               mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
                break;
        }
        case MPI2_FUNCTION_SMP_PASSTHROUGH:
index 9ab77b06434d19a61a92bb771aef0e70da0f31d8..6180f7970bbf73c0d9dcfefd6e86ffe3bf4f27f4 100644 (file)
@@ -2193,6 +2193,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
        unsigned long timeleft;
        struct scsiio_tracker *scsi_lookup = NULL;
        int rc;
+       u16 msix_task = 0;
 
        if (m_type == TM_MUTEX_ON)
                mutex_lock(&ioc->tm_cmds.mutex);
@@ -2256,7 +2257,12 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
        int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
        mpt3sas_scsih_set_tm_flag(ioc, handle);
        init_completion(&ioc->tm_cmds.done);
-       mpt3sas_base_put_smid_hi_priority(ioc, smid);
+       if ((type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) &&
+                       (scsi_lookup->msix_io < ioc->reply_queue_count))
+               msix_task = scsi_lookup->msix_io;
+       else
+               msix_task = 0;
+       mpt3sas_base_put_smid_hi_priority(ioc, smid, msix_task);
        timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
        if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) {
                pr_err(MPT3SAS_FMT "%s: timeout\n",
@@ -3151,7 +3157,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
        mpi_request->DevHandle = cpu_to_le16(handle);
        mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-       mpt3sas_base_put_smid_hi_priority(ioc, smid);
+       mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
        mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
 
 out:
@@ -3332,7 +3338,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
        mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
        mpi_request->DevHandle = cpu_to_le16(handle);
        mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-       mpt3sas_base_put_smid_hi_priority(ioc, smid);
+       mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
 }
 
 /**