Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -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);
}

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
@@ -2321,6 +2327,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;
@@ -2443,12 +2450,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
@@ -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
 * @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;
+4 −1
Original line number Diff line number Diff line
@@ -649,6 +649,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;
@@ -657,6 +658,7 @@ struct scsiio_tracker {
	u8	direct_io;
	struct list_head chain_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,
	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);
+1 −1
Original line number Diff line number Diff line
@@ -832,7 +832,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:
+9 −3
Original line number Diff line number Diff line
@@ -2217,6 +2217,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);
@@ -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);
	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",
@@ -3187,7 +3193,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:
@@ -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->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);
}

/**