Commit 03d1fb3a authored by Suganath prabu Subramani's avatar Suganath prabu Subramani Committed by Martin K. Petersen

mpt3sas: Fix for Asynchronous completion of timedout IO and task abort of timedout IO.

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: default avatarSuganath prabu Subramani <suganath-prabu.subramani@avagotech.com>
Signed-off-by: default avatarChaitra P B <chaitra.basappa@avagotech.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5c739b61
...@@ -2261,6 +2261,12 @@ mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr) ...@@ -2261,6 +2261,12 @@ mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr)
return ioc->reply + (phys_addr - (u32)ioc->reply_dma); 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 * mpt3sas_base_get_smid - obtain a free smid from internal queue
* @ioc: per adapter object * @ioc: per adapter object
...@@ -2321,6 +2327,7 @@ mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, ...@@ -2321,6 +2327,7 @@ mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx,
request->scmd = scmd; request->scmd = scmd;
request->cb_idx = cb_idx; request->cb_idx = cb_idx;
smid = request->smid; smid = request->smid;
request->msix_io = _base_get_msix_index(ioc);
list_del(&request->tracker_list); list_del(&request->tracker_list);
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
return smid; return smid;
...@@ -2443,12 +2450,6 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) ...@@ -2443,12 +2450,6 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock)
} }
#endif #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 * mpt3sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
* @ioc: per adapter object * @ioc: per adapter object
...@@ -2502,18 +2503,19 @@ mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, ...@@ -2502,18 +2503,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 * mpt3sas_base_put_smid_hi_priority - send Task Managment request to firmware
* @ioc: per adapter object * @ioc: per adapter object
* @smid: system request message index * @smid: system request message index
* * @msix_task: msix_task will be same as msix of IO incase of task abort else 0.
* Return nothing. * Return nothing.
*/ */
void 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; Mpi2RequestDescriptorUnion_t descriptor;
u64 *request = (u64 *)&descriptor; u64 *request = (u64 *)&descriptor;
descriptor.HighPriority.RequestFlags = descriptor.HighPriority.RequestFlags =
MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
descriptor.HighPriority.MSIxIndex = 0; descriptor.HighPriority.MSIxIndex = msix_task;
descriptor.HighPriority.SMID = cpu_to_le16(smid); descriptor.HighPriority.SMID = cpu_to_le16(smid);
descriptor.HighPriority.LMID = 0; descriptor.HighPriority.LMID = 0;
descriptor.HighPriority.Reserved1 = 0; descriptor.HighPriority.Reserved1 = 0;
......
...@@ -649,6 +649,7 @@ struct chain_tracker { ...@@ -649,6 +649,7 @@ struct chain_tracker {
* @cb_idx: callback index * @cb_idx: callback index
* @direct_io: To indicate whether I/O is direct (WARPDRIVE) * @direct_io: To indicate whether I/O is direct (WARPDRIVE)
* @tracker_list: list of free request (ioc->free_list) * @tracker_list: list of free request (ioc->free_list)
* @msix_io: IO's msix
*/ */
struct scsiio_tracker { struct scsiio_tracker {
u16 smid; u16 smid;
...@@ -657,6 +658,7 @@ struct scsiio_tracker { ...@@ -657,6 +658,7 @@ struct scsiio_tracker {
u8 direct_io; u8 direct_io;
struct list_head chain_list; struct list_head chain_list;
struct list_head tracker_list; struct list_head tracker_list;
u16 msix_io;
}; };
/** /**
...@@ -1245,7 +1247,8 @@ void mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, ...@@ -1245,7 +1247,8 @@ void mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 handle); u16 handle);
void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 handle); 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_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid);
void mpt3sas_base_initialize_callback_handler(void); void mpt3sas_base_initialize_callback_handler(void);
u8 mpt3sas_base_register_callback_handler(MPT_CALLBACK cb_func); u8 mpt3sas_base_register_callback_handler(MPT_CALLBACK cb_func);
......
...@@ -832,7 +832,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, ...@@ -832,7 +832,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
tm_request->DevHandle)); tm_request->DevHandle));
ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
data_in_dma, data_in_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; break;
} }
case MPI2_FUNCTION_SMP_PASSTHROUGH: case MPI2_FUNCTION_SMP_PASSTHROUGH:
......
...@@ -2217,6 +2217,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2217,6 +2217,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
unsigned long timeleft; unsigned long timeleft;
struct scsiio_tracker *scsi_lookup = NULL; struct scsiio_tracker *scsi_lookup = NULL;
int rc; int rc;
u16 msix_task = 0;
if (m_type == TM_MUTEX_ON) if (m_type == TM_MUTEX_ON)
mutex_lock(&ioc->tm_cmds.mutex); mutex_lock(&ioc->tm_cmds.mutex);
...@@ -2280,7 +2281,12 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2280,7 +2281,12 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
mpt3sas_scsih_set_tm_flag(ioc, handle); mpt3sas_scsih_set_tm_flag(ioc, handle);
init_completion(&ioc->tm_cmds.done); 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); timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) {
pr_err(MPT3SAS_FMT "%s: timeout\n", pr_err(MPT3SAS_FMT "%s: timeout\n",
...@@ -3187,7 +3193,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3187,7 +3193,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
mpi_request->DevHandle = cpu_to_le16(handle); mpi_request->DevHandle = cpu_to_le16(handle);
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; 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); mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
out: out:
...@@ -3376,7 +3382,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3376,7 +3382,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
mpi_request->DevHandle = cpu_to_le16(handle); mpi_request->DevHandle = cpu_to_le16(handle);
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; 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);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment