|
|
From f0241cb5899f514e51799f85fc884d30210e00a4 Mon Sep 17 00:00:00 2001
|
|
|
From: Tomas Henzl <thenzl@redhat.com>
|
|
|
Date: Fri, 9 Oct 2020 14:06:29 -0400
|
|
|
Subject: [PATCH 11/33] [scsi] scsi: mpt3sas: Postprocessing of target and LUN
|
|
|
reset
|
|
|
|
|
|
Message-id: <20201009140636.7976-12-thenzl@redhat.com>
|
|
|
Patchwork-id: 330368
|
|
|
Patchwork-instance: patchwork
|
|
|
O-Subject: [RHEL8.4 e-stor PATCH 11/18] scsi: mpt3sas: Postprocessing of target and LUN reset
|
|
|
Bugzilla: 1851440
|
|
|
RH-Acked-by: Ewan Milne <emilne@redhat.com>
|
|
|
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
|
|
|
RH-Acked-by: Maurizio Lombardi <mlombard@redhat.com>
|
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
|
|
If driver has not received the interrupt for the aborted SCSI command
|
|
|
before processing the TM reply, driver polls all the reply descriptor pools
|
|
|
looking for the reply for the aborted SCSI command before marking TM as
|
|
|
FAILED. If it finds the reply, then it marks the TM as SUCCESS otherwise it
|
|
|
marks it FAILED.
|
|
|
|
|
|
scsih_tm_cmd_map_status() checks whether TM has aborted the timed out SCSI
|
|
|
command or not. If TM has aborted the IO, then it returns SUCCESS else it
|
|
|
returns FAILED.
|
|
|
|
|
|
Link: https://lore.kernel.org/r/1596096229-3341-7-git-send-email-suganath-prabu.subramani@broadcom.com
|
|
|
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
|
|
|
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
|
(cherry picked from commit 711a923c14d9a48d15a30a2c085184954bf04931)
|
|
|
Signed-off-by: Tomas Henzl <thenzl@redhat.com>
|
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
|
---
|
|
|
drivers/scsi/mpt3sas/mpt3sas_base.c | 6 +-
|
|
|
drivers/scsi/mpt3sas/mpt3sas_base.h | 2 +-
|
|
|
drivers/scsi/mpt3sas/mpt3sas_scsih.c | 136 ++++++++++++++++++++++++++++++++++-
|
|
|
3 files changed, 139 insertions(+), 5 deletions(-)
|
|
|
|
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
|
|
|
index 7f0de6a96b88..53a835b37fa9 100644
|
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
|
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
|
|
|
@@ -1785,12 +1785,14 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc)
|
|
|
/**
|
|
|
* mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts
|
|
|
* @ioc: per adapter object
|
|
|
+ * @poll: poll over reply descriptor pools incase interrupt for
|
|
|
+ * timed-out SCSI command got delayed
|
|
|
* Context: non ISR conext
|
|
|
*
|
|
|
* Called when a Task Management request has completed.
|
|
|
*/
|
|
|
void
|
|
|
-mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc)
|
|
|
+mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll)
|
|
|
{
|
|
|
struct adapter_reply_queue *reply_q;
|
|
|
|
|
|
@@ -1820,6 +1822,8 @@ mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc)
|
|
|
}
|
|
|
synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index));
|
|
|
}
|
|
|
+ if (poll)
|
|
|
+ _base_process_reply_queue(reply_q);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
|
index bd892230a87b..87b50f59c2eb 100644
|
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
|
@@ -1528,7 +1528,7 @@ __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
|
|
|
u16 smid);
|
|
|
void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid);
|
|
|
dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid);
|
|
|
-void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
|
|
|
+void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll);
|
|
|
void mpt3sas_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc);
|
|
|
void mpt3sas_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc);
|
|
|
|
|
|
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
|
index 83bef0809f47..8e9edfd8239c 100644
|
|
|
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
|
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
|
|
|
@@ -2761,6 +2761,96 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * scsih_tm_cmd_map_status - map the target reset & LUN reset TM status
|
|
|
+ * @ioc - per adapter object
|
|
|
+ * @channel - the channel assigned by the OS
|
|
|
+ * @id: the id assigned by the OS
|
|
|
+ * @lun: lun number
|
|
|
+ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
|
|
+ * @smid_task: smid assigned to the task
|
|
|
+ *
|
|
|
+ * Look whether TM has aborted the timed out SCSI command, if
|
|
|
+ * TM has aborted the IO then return SUCCESS else return FAILED.
|
|
|
+ */
|
|
|
+static int
|
|
|
+scsih_tm_cmd_map_status(struct MPT3SAS_ADAPTER *ioc, uint channel,
|
|
|
+ uint id, uint lun, u8 type, u16 smid_task)
|
|
|
+{
|
|
|
+
|
|
|
+ if (smid_task <= ioc->shost->can_queue) {
|
|
|
+ switch (type) {
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
|
|
|
+ if (!(_scsih_scsi_lookup_find_by_target(ioc,
|
|
|
+ id, channel)))
|
|
|
+ return SUCCESS;
|
|
|
+ break;
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
|
|
|
+ if (!(_scsih_scsi_lookup_find_by_lun(ioc, id,
|
|
|
+ lun, channel)))
|
|
|
+ return SUCCESS;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return SUCCESS;
|
|
|
+ }
|
|
|
+ } else if (smid_task == ioc->scsih_cmds.smid) {
|
|
|
+ if ((ioc->scsih_cmds.status & MPT3_CMD_COMPLETE) ||
|
|
|
+ (ioc->scsih_cmds.status & MPT3_CMD_NOT_USED))
|
|
|
+ return SUCCESS;
|
|
|
+ } else if (smid_task == ioc->ctl_cmds.smid) {
|
|
|
+ if ((ioc->ctl_cmds.status & MPT3_CMD_COMPLETE) ||
|
|
|
+ (ioc->ctl_cmds.status & MPT3_CMD_NOT_USED))
|
|
|
+ return SUCCESS;
|
|
|
+ }
|
|
|
+
|
|
|
+ return FAILED;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * scsih_tm_post_processing - post processing of target & LUN reset
|
|
|
+ * @ioc - per adapter object
|
|
|
+ * @handle: device handle
|
|
|
+ * @channel - the channel assigned by the OS
|
|
|
+ * @id: the id assigned by the OS
|
|
|
+ * @lun: lun number
|
|
|
+ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
|
|
+ * @smid_task: smid assigned to the task
|
|
|
+ *
|
|
|
+ * Post processing of target & LUN reset. Due to interrupt latency
|
|
|
+ * issue it possible that interrupt for aborted IO might not be
|
|
|
+ * received yet. So before returning failure status, poll the
|
|
|
+ * reply descriptor pools for the reply of timed out SCSI command.
|
|
|
+ * Return FAILED status if reply for timed out is not received
|
|
|
+ * otherwise return SUCCESS.
|
|
|
+ */
|
|
|
+static int
|
|
|
+scsih_tm_post_processing(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
|
|
+ uint channel, uint id, uint lun, u8 type, u16 smid_task)
|
|
|
+{
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ rc = scsih_tm_cmd_map_status(ioc, channel, id, lun, type, smid_task);
|
|
|
+ if (rc == SUCCESS)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ ioc_info(ioc,
|
|
|
+ "Poll ReplyDescriptor queues for completion of"
|
|
|
+ " smid(%d), task_type(0x%02x), handle(0x%04x)\n",
|
|
|
+ smid_task, type, handle);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Due to interrupt latency issues, driver may receive interrupt for
|
|
|
+ * TM first and then for aborted SCSI IO command. So, poll all the
|
|
|
+ * ReplyDescriptor pools before returning the FAILED status to SML.
|
|
|
+ */
|
|
|
+ mpt3sas_base_mask_interrupts(ioc);
|
|
|
+ mpt3sas_base_sync_reply_irqs(ioc, 1);
|
|
|
+ mpt3sas_base_unmask_interrupts(ioc);
|
|
|
+
|
|
|
+ return scsih_tm_cmd_map_status(ioc, channel, id, lun, type, smid_task);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
* mpt3sas_scsih_issue_tm - main routine for sending tm requests
|
|
|
* @ioc: per adapter struct
|
|
|
* @handle: device handle
|
|
|
@@ -2788,6 +2878,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
|
|
{
|
|
|
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
|
|
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
|
|
+ Mpi25SCSIIORequest_t *request;
|
|
|
u16 smid = 0;
|
|
|
u32 ioc_state;
|
|
|
int rc;
|
|
|
@@ -2843,7 +2934,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
|
|
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
|
|
mpi_request->DevHandle = cpu_to_le16(handle);
|
|
|
mpi_request->TaskType = type;
|
|
|
- mpi_request->MsgFlags = tr_method;
|
|
|
+ if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
|
|
|
+ type == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK)
|
|
|
+ mpi_request->MsgFlags = tr_method;
|
|
|
mpi_request->TaskMID = cpu_to_le16(smid_task);
|
|
|
int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
|
|
|
mpt3sas_scsih_set_tm_flag(ioc, handle);
|
|
|
@@ -2863,7 +2956,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
|
|
}
|
|
|
|
|
|
/* sync IRQs in case those were busy during flush. */
|
|
|
- mpt3sas_base_sync_reply_irqs(ioc);
|
|
|
+ mpt3sas_base_sync_reply_irqs(ioc, 0);
|
|
|
|
|
|
if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) {
|
|
|
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
|
|
|
@@ -2880,7 +2973,44 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
|
|
sizeof(Mpi2SCSITaskManagementRequest_t)/4);
|
|
|
}
|
|
|
}
|
|
|
- rc = SUCCESS;
|
|
|
+
|
|
|
+ switch (type) {
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
|
|
|
+ rc = SUCCESS;
|
|
|
+ /*
|
|
|
+ * If DevHandle filed in smid_task's entry of request pool
|
|
|
+ * doesn't match with device handle on which this task abort
|
|
|
+ * TM is received then it means that TM has successfully
|
|
|
+ * aborted the timed out command. Since smid_task's entry in
|
|
|
+ * request pool will be memset to zero once the timed out
|
|
|
+ * command is returned to the SML. If the command is not
|
|
|
+ * aborted then smid_task’s entry won’t be cleared and it
|
|
|
+ * will have same DevHandle value on which this task abort TM
|
|
|
+ * is received and driver will return the TM status as FAILED.
|
|
|
+ */
|
|
|
+ request = mpt3sas_base_get_msg_frame(ioc, smid_task);
|
|
|
+ if (le16_to_cpu(request->DevHandle) != handle)
|
|
|
+ break;
|
|
|
+
|
|
|
+ ioc_info(ioc, "Task abort tm failed: handle(0x%04x),"
|
|
|
+ "timeout(%d) tr_method(0x%x) smid(%d) msix_index(%d)\n",
|
|
|
+ handle, timeout, tr_method, smid_task, msix_task);
|
|
|
+ rc = FAILED;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
|
|
|
+ rc = scsih_tm_post_processing(ioc, handle, channel, id, lun,
|
|
|
+ type, smid_task);
|
|
|
+ break;
|
|
|
+ case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
|
|
|
+ rc = SUCCESS;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ rc = FAILED;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
out:
|
|
|
mpt3sas_scsih_clear_tm_flag(ioc, handle);
|
|
|
--
|
|
|
2.13.6
|
|
|
|