scsi: mpi3mr: Fix premature TM timeouts on virtual drives

Task Management to virtual drives may timeout prematurely when using a
static default timeout.

Read Abort and Reset timeouts from Device Page 0 and apply the maximum
of the firmware value and the default.

This fixes premature TM failures on virtual drives.

Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Link: https://lore.kernel.org/r/20250820084138.228471-6-chandrakanth.patil@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Chandrakanth Patil 2025-08-20 14:11:37 +05:30 committed by Martin K. Petersen
parent a4ca63001e
commit 4af864784d
2 changed files with 17 additions and 5 deletions

View File

@ -697,6 +697,8 @@ struct tgt_dev_vd {
u16 tg_id;
u32 tg_high;
u32 tg_low;
u8 abort_to;
u8 reset_to;
struct mpi3mr_throttle_group_info *tg;
};
@ -738,6 +740,8 @@ enum mpi3mr_dev_state {
* @wwid: World wide ID
* @enclosure_logical_id: Enclosure logical identifier
* @dev_spec: Device type specific information
* @abort_to: Timeout for abort TM
* @reset_to: Timeout for Target/LUN reset TM
* @ref_count: Reference count
* @state: device state
*/

View File

@ -1308,6 +1308,12 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
if (vdinf->vd_state == MPI3_DEVICE0_VD_STATE_OFFLINE)
tgtdev->is_hidden = 1;
tgtdev->non_stl = 1;
tgtdev->dev_spec.vd_inf.reset_to =
max_t(u8, vdinf->vd_reset_to,
MPI3MR_INTADMCMD_TIMEOUT);
tgtdev->dev_spec.vd_inf.abort_to =
max_t(u8, vdinf->vd_abort_to,
MPI3MR_INTADMCMD_TIMEOUT);
tgtdev->dev_spec.vd_inf.tg_id = vdinf_io_throttle_group;
tgtdev->dev_spec.vd_inf.tg_high =
le16_to_cpu(vdinf->io_throttle_group_high) * 2048;
@ -3917,11 +3923,13 @@ int mpi3mr_issue_tm(struct mpi3mr_ioc *mrioc, u8 tm_type,
if (scsi_tgt_priv_data)
atomic_inc(&scsi_tgt_priv_data->block_io);
if (tgtdev && (tgtdev->dev_type == MPI3_DEVICE_DEVFORM_PCIE)) {
if (cmd_priv && tgtdev->dev_spec.pcie_inf.abort_to)
timeout = tgtdev->dev_spec.pcie_inf.abort_to;
else if (!cmd_priv && tgtdev->dev_spec.pcie_inf.reset_to)
timeout = tgtdev->dev_spec.pcie_inf.reset_to;
if (tgtdev) {
if (tgtdev->dev_type == MPI3_DEVICE_DEVFORM_PCIE)
timeout = cmd_priv ? tgtdev->dev_spec.pcie_inf.abort_to
: tgtdev->dev_spec.pcie_inf.reset_to;
else if (tgtdev->dev_type == MPI3_DEVICE_DEVFORM_VD)
timeout = cmd_priv ? tgtdev->dev_spec.vd_inf.abort_to
: tgtdev->dev_spec.vd_inf.reset_to;
}
init_completion(&drv_cmd->done);