mpt3sas: Eliminate conditional locking in mpt3sas_scsih_issue_tm()
This flag that conditionally acquires the mutex is confusing and prone to bugginess: refactor it into two separate function calls, and make the unlocked one complain if it's called outside the mutex. Signed-off-by: Calvin Owens <calvinowens@fb.com> Acked-by: Chaitra P B <chaitra.basappa@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
310c8e40d5
commit
96902835e7
|
@ -794,16 +794,6 @@ struct reply_post_struct {
|
||||||
dma_addr_t reply_post_free_dma;
|
dma_addr_t reply_post_free_dma;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* enum mutex_type - task management mutex type
|
|
||||||
* @TM_MUTEX_OFF: mutex is not required becuase calling function is acquiring it
|
|
||||||
* @TM_MUTEX_ON: mutex is required
|
|
||||||
*/
|
|
||||||
enum mutex_type {
|
|
||||||
TM_MUTEX_OFF = 0,
|
|
||||||
TM_MUTEX_ON = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
|
typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
|
||||||
/**
|
/**
|
||||||
* struct MPT3SAS_ADAPTER - per adapter struct
|
* struct MPT3SAS_ADAPTER - per adapter struct
|
||||||
|
@ -1291,7 +1281,11 @@ void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
|
||||||
|
|
||||||
int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
uint channel, uint id, uint lun, u8 type, u16 smid_task,
|
uint channel, uint id, uint lun, u8 type, u16 smid_task,
|
||||||
ulong timeout, enum mutex_type m_type);
|
ulong timeout);
|
||||||
|
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
|
uint channel, uint id, uint lun, u8 type, u16 smid_task,
|
||||||
|
ulong timeout);
|
||||||
|
|
||||||
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||||
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||||
void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
||||||
|
|
|
@ -1001,10 +1001,9 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
||||||
ioc->name,
|
ioc->name,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1));
|
le16_to_cpu(mpi_request->FunctionDependent1));
|
||||||
mpt3sas_halt_firmware(ioc);
|
mpt3sas_halt_firmware(ioc);
|
||||||
mpt3sas_scsih_issue_tm(ioc,
|
mpt3sas_scsih_issue_locked_tm(ioc,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
||||||
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30,
|
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30);
|
||||||
TM_MUTEX_ON);
|
|
||||||
} else
|
} else
|
||||||
mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
||||||
FORCE_BIG_HAMMER);
|
FORCE_BIG_HAMMER);
|
||||||
|
|
|
@ -2201,7 +2201,6 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
||||||
* @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
* @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
||||||
* @smid_task: smid assigned to the task
|
* @smid_task: smid assigned to the task
|
||||||
* @timeout: timeout in seconds
|
* @timeout: timeout in seconds
|
||||||
* @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
|
|
||||||
* Context: user
|
* Context: user
|
||||||
*
|
*
|
||||||
* A generic API for sending task management requests to firmware.
|
* A generic API for sending task management requests to firmware.
|
||||||
|
@ -2212,8 +2211,7 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
|
uint id, uint lun, u8 type, u16 smid_task, ulong timeout)
|
||||||
enum mutex_type m_type)
|
|
||||||
{
|
{
|
||||||
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
||||||
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
||||||
|
@ -2224,21 +2222,19 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
int rc;
|
int rc;
|
||||||
u16 msix_task = 0;
|
u16 msix_task = 0;
|
||||||
|
|
||||||
if (m_type == TM_MUTEX_ON)
|
lockdep_assert_held(&ioc->tm_cmds.mutex);
|
||||||
mutex_lock(&ioc->tm_cmds.mutex);
|
|
||||||
if (ioc->tm_cmds.status != MPT3_CMD_NOT_USED) {
|
if (ioc->tm_cmds.status != MPT3_CMD_NOT_USED) {
|
||||||
pr_info(MPT3SAS_FMT "%s: tm_cmd busy!!!\n",
|
pr_info(MPT3SAS_FMT "%s: tm_cmd busy!!!\n",
|
||||||
__func__, ioc->name);
|
__func__, ioc->name);
|
||||||
rc = FAILED;
|
return FAILED;
|
||||||
goto err_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioc->shost_recovery || ioc->remove_host ||
|
if (ioc->shost_recovery || ioc->remove_host ||
|
||||||
ioc->pci_error_recovery) {
|
ioc->pci_error_recovery) {
|
||||||
pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
|
pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
|
||||||
__func__, ioc->name);
|
__func__, ioc->name);
|
||||||
rc = FAILED;
|
return FAILED;
|
||||||
goto err_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ioc_state = mpt3sas_base_get_iocstate(ioc, 0);
|
ioc_state = mpt3sas_base_get_iocstate(ioc, 0);
|
||||||
|
@ -2247,8 +2243,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
"unexpected doorbell active!\n", ioc->name));
|
"unexpected doorbell active!\n", ioc->name));
|
||||||
rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
||||||
FORCE_BIG_HAMMER);
|
FORCE_BIG_HAMMER);
|
||||||
rc = (!rc) ? SUCCESS : FAILED;
|
return (!rc) ? SUCCESS : FAILED;
|
||||||
goto err_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
|
if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
|
||||||
|
@ -2256,16 +2251,14 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
MPI2_DOORBELL_DATA_MASK);
|
MPI2_DOORBELL_DATA_MASK);
|
||||||
rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
||||||
FORCE_BIG_HAMMER);
|
FORCE_BIG_HAMMER);
|
||||||
rc = (!rc) ? SUCCESS : FAILED;
|
return (!rc) ? SUCCESS : FAILED;
|
||||||
goto err_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
|
smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
|
||||||
if (!smid) {
|
if (!smid) {
|
||||||
pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
|
pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
|
||||||
ioc->name, __func__);
|
ioc->name, __func__);
|
||||||
rc = FAILED;
|
return FAILED;
|
||||||
goto err_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
|
if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
|
||||||
|
@ -2302,9 +2295,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
||||||
FORCE_BIG_HAMMER);
|
FORCE_BIG_HAMMER);
|
||||||
rc = (!rc) ? SUCCESS : FAILED;
|
rc = (!rc) ? SUCCESS : FAILED;
|
||||||
ioc->tm_cmds.status = MPT3_CMD_NOT_USED;
|
goto out;
|
||||||
mpt3sas_scsih_clear_tm_flag(ioc, handle);
|
|
||||||
goto err_out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2356,17 +2347,23 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
mpt3sas_scsih_clear_tm_flag(ioc, handle);
|
mpt3sas_scsih_clear_tm_flag(ioc, handle);
|
||||||
ioc->tm_cmds.status = MPT3_CMD_NOT_USED;
|
ioc->tm_cmds.status = MPT3_CMD_NOT_USED;
|
||||||
if (m_type == TM_MUTEX_ON)
|
|
||||||
mutex_unlock(&ioc->tm_cmds.mutex);
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
err_out:
|
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
if (m_type == TM_MUTEX_ON)
|
uint channel, uint id, uint lun, u8 type, u16 smid_task, ulong timeout)
|
||||||
mutex_unlock(&ioc->tm_cmds.mutex);
|
{
|
||||||
return rc;
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&ioc->tm_cmds.mutex);
|
||||||
|
ret = mpt3sas_scsih_issue_tm(ioc, handle, channel, id, lun, type,
|
||||||
|
smid_task, timeout);
|
||||||
|
mutex_unlock(&ioc->tm_cmds.mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2482,9 +2479,9 @@ scsih_abort(struct scsi_cmnd *scmd)
|
||||||
mpt3sas_halt_firmware(ioc);
|
mpt3sas_halt_firmware(ioc);
|
||||||
|
|
||||||
handle = sas_device_priv_data->sas_target->handle;
|
handle = sas_device_priv_data->sas_target->handle;
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, scmd->device->lun,
|
scmd->device->id, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON);
|
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
||||||
|
@ -2541,9 +2538,9 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, scmd->device->lun,
|
scmd->device->id, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON);
|
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
|
sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
|
||||||
|
@ -2603,9 +2600,9 @@ scsih_target_reset(struct scsi_cmnd *scmd)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
||||||
30, TM_MUTEX_ON);
|
30);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
|
starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
|
||||||
|
@ -6089,8 +6086,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30,
|
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
|
||||||
TM_MUTEX_OFF);
|
|
||||||
if (r == FAILED) {
|
if (r == FAILED) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
"mpt3sas_scsih_issue_tm: FAILED when sending "
|
"mpt3sas_scsih_issue_tm: FAILED when sending "
|
||||||
|
@ -6130,8 +6126,8 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
|
||||||
goto out_no_lock;
|
goto out_no_lock;
|
||||||
|
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
||||||
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
|
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid,
|
||||||
TM_MUTEX_OFF);
|
30);
|
||||||
if (r == FAILED) {
|
if (r == FAILED) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
||||||
|
|
Loading…
Reference in a new issue