OSDN Git Service

scsi: mpt3sas: Fix for Crusader to achieve product targets with SAS devices.
authorChaitra P B <chaitra.basappa@broadcom.com>
Mon, 23 Jan 2017 09:56:08 +0000 (15:26 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 1 Feb 2017 03:03:35 +0000 (22:03 -0500)
Small glitch/degraded performance in Crusader is improved with SAS
drives by removing unnecessary spinlocks while clearing scsi command in
drivers internal lookup table.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
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 f00ef88..722fab9 100644 (file)
@@ -5522,6 +5522,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
                goto out_free_resources;
 
        ioc->non_operational_loop = 0;
+       ioc->got_task_abort_from_ioctl = 0;
        return 0;
 
  out_free_resources:
index 394fe13..5c13877 100644 (file)
@@ -988,6 +988,7 @@ struct MPT3SAS_ADAPTER {
        u8              broadcast_aen_busy;
        u16             broadcast_aen_pending;
        u8              shost_recovery;
+       u8              got_task_abort_from_ioctl;
 
        struct mutex    reset_in_progress_mutex;
        spinlock_t      ioc_reset_in_progress_lock;
index 95f0f24..02fe1c4 100644 (file)
@@ -826,16 +826,18 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
                        "TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n",
                        ioc->name,
                    le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
-
+               ioc->got_task_abort_from_ioctl = 1;
                if (tm_request->TaskType ==
                    MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
                    tm_request->TaskType ==
                    MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {
                        if (_ctl_set_task_mid(ioc, &karg, tm_request)) {
                                mpt3sas_base_free_smid(ioc, smid);
+                               ioc->got_task_abort_from_ioctl = 0;
                                goto out;
                        }
                }
+               ioc->got_task_abort_from_ioctl = 0;
 
                if (test_bit(device_handle, ioc->device_remove_in_progress)) {
                        dtmprintk(ioc, pr_info(MPT3SAS_FMT
index 8f524a2..b8cd0a1 100644 (file)
@@ -1074,6 +1074,26 @@ _scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 }
 
 /**
+ * __scsih_scsi_lookup_get_clear - returns scmd entry without
+ *                                             holding any lock.
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ * Then will dereference the stored scmd pointer.
+ */
+static inline struct scsi_cmnd *
+__scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc,
+               u16 smid)
+{
+       struct scsi_cmnd *scmd = NULL;
+
+       swap(scmd, ioc->scsi_lookup[smid - 1].scmd);
+
+       return scmd;
+}
+
+/**
  * _scsih_scsi_lookup_get_clear - returns scmd entry
  * @ioc: per adapter object
  * @smid: system request message index
@@ -1088,8 +1108,7 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid)
        struct scsi_cmnd *scmd;
 
        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       scmd = ioc->scsi_lookup[smid - 1].scmd;
-       ioc->scsi_lookup[smid - 1].scmd = NULL;
+       scmd = __scsih_scsi_lookup_get_clear(ioc, smid);
        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 
        return scmd;
@@ -4646,7 +4665,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
        unsigned long flags;
 
        mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-       scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+
+       if (ioc->broadcast_aen_busy || ioc->pci_error_recovery ||
+                       ioc->got_task_abort_from_ioctl)
+               scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+       else
+               scmd = __scsih_scsi_lookup_get_clear(ioc, smid);
+
        if (scmd == NULL)
                return 1;