Commit 116a7584 authored by Suganath prabu Subramani's avatar Suganath prabu Subramani Committed by Greg Kroah-Hartman

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

[ Upstream commit 03d1fb3a ]

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>
Signed-off-by: default avatarSasha Levin <alexander.levin@verizon.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8b208a5d
...@@ -2242,6 +2242,12 @@ mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr) ...@@ -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); 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
...@@ -2302,6 +2308,7 @@ mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, ...@@ -2302,6 +2308,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;
...@@ -2424,12 +2431,6 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) ...@@ -2424,12 +2431,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
...@@ -2483,18 +2484,19 @@ mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, ...@@ -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 * 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;
......
...@@ -643,6 +643,7 @@ struct chain_tracker { ...@@ -643,6 +643,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;
...@@ -651,6 +652,7 @@ struct scsiio_tracker { ...@@ -651,6 +652,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;
}; };
/** /**
...@@ -1213,7 +1215,8 @@ void mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, ...@@ -1213,7 +1215,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);
......
...@@ -817,7 +817,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, ...@@ -817,7 +817,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:
......
...@@ -2193,6 +2193,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2193,6 +2193,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);
...@@ -2256,7 +2257,12 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -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); 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",
...@@ -3151,7 +3157,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3151,7 +3157,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:
...@@ -3332,7 +3338,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -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->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