Commit 7fa3174b authored by Chandrakanth Patil's avatar Chandrakanth Patil Committed by Martin K. Petersen

scsi: megaraid_sas: Release Mutex lock before OCR in case of DCMD timeout

Issue: There is possibility of few DCMDs timing out with 'reset_mutex' lock
held. As part of DCMD timeout handling, driver calls function
megasas_reset_fusion which also tries to acquire same lock 'reset_mutex'
and end up with deadlock.

Fix: Upon timeout of DCMDs (which are fired with 'reset_mutex' lock held),
driver will release 'reset_mutex' before calling OCR function and will
acquire lock again after OCR function returns.
Signed-off-by: default avatarSumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: default avatarChandrakanth Patil <chandrakanth.patil@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a6ffd5bf
...@@ -4369,8 +4369,10 @@ megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev) ...@@ -4369,8 +4369,10 @@ megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev)
switch (dcmd_timeout_ocr_possible(instance)) { switch (dcmd_timeout_ocr_possible(instance)) {
case INITIATE_OCR: case INITIATE_OCR:
cmd->flags |= DRV_DCMD_SKIP_REFIRE; cmd->flags |= DRV_DCMD_SKIP_REFIRE;
mutex_unlock(&instance->reset_mutex);
megasas_reset_fusion(instance->host, megasas_reset_fusion(instance->host,
MFI_IO_TIMEOUT_OCR); MFI_IO_TIMEOUT_OCR);
mutex_lock(&instance->reset_mutex);
break; break;
case KILL_ADAPTER: case KILL_ADAPTER:
megaraid_sas_kill_hba(instance); megaraid_sas_kill_hba(instance);
...@@ -4861,8 +4863,10 @@ megasas_host_device_list_query(struct megasas_instance *instance, ...@@ -4861,8 +4863,10 @@ megasas_host_device_list_query(struct megasas_instance *instance,
switch (dcmd_timeout_ocr_possible(instance)) { switch (dcmd_timeout_ocr_possible(instance)) {
case INITIATE_OCR: case INITIATE_OCR:
cmd->flags |= DRV_DCMD_SKIP_REFIRE; cmd->flags |= DRV_DCMD_SKIP_REFIRE;
mutex_unlock(&instance->reset_mutex);
megasas_reset_fusion(instance->host, megasas_reset_fusion(instance->host,
MFI_IO_TIMEOUT_OCR); MFI_IO_TIMEOUT_OCR);
mutex_lock(&instance->reset_mutex);
break; break;
case KILL_ADAPTER: case KILL_ADAPTER:
megaraid_sas_kill_hba(instance); megaraid_sas_kill_hba(instance);
...@@ -5010,8 +5014,10 @@ void megasas_get_snapdump_properties(struct megasas_instance *instance) ...@@ -5010,8 +5014,10 @@ void megasas_get_snapdump_properties(struct megasas_instance *instance)
switch (dcmd_timeout_ocr_possible(instance)) { switch (dcmd_timeout_ocr_possible(instance)) {
case INITIATE_OCR: case INITIATE_OCR:
cmd->flags |= DRV_DCMD_SKIP_REFIRE; cmd->flags |= DRV_DCMD_SKIP_REFIRE;
mutex_unlock(&instance->reset_mutex);
megasas_reset_fusion(instance->host, megasas_reset_fusion(instance->host,
MFI_IO_TIMEOUT_OCR); MFI_IO_TIMEOUT_OCR);
mutex_lock(&instance->reset_mutex);
break; break;
case KILL_ADAPTER: case KILL_ADAPTER:
megaraid_sas_kill_hba(instance); megaraid_sas_kill_hba(instance);
...@@ -5141,8 +5147,10 @@ megasas_get_ctrl_info(struct megasas_instance *instance) ...@@ -5141,8 +5147,10 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
switch (dcmd_timeout_ocr_possible(instance)) { switch (dcmd_timeout_ocr_possible(instance)) {
case INITIATE_OCR: case INITIATE_OCR:
cmd->flags |= DRV_DCMD_SKIP_REFIRE; cmd->flags |= DRV_DCMD_SKIP_REFIRE;
mutex_unlock(&instance->reset_mutex);
megasas_reset_fusion(instance->host, megasas_reset_fusion(instance->host,
MFI_IO_TIMEOUT_OCR); MFI_IO_TIMEOUT_OCR);
mutex_lock(&instance->reset_mutex);
break; break;
case KILL_ADAPTER: case KILL_ADAPTER:
megaraid_sas_kill_hba(instance); megaraid_sas_kill_hba(instance);
...@@ -6398,8 +6406,10 @@ megasas_get_target_prop(struct megasas_instance *instance, ...@@ -6398,8 +6406,10 @@ megasas_get_target_prop(struct megasas_instance *instance,
switch (dcmd_timeout_ocr_possible(instance)) { switch (dcmd_timeout_ocr_possible(instance)) {
case INITIATE_OCR: case INITIATE_OCR:
cmd->flags |= DRV_DCMD_SKIP_REFIRE; cmd->flags |= DRV_DCMD_SKIP_REFIRE;
mutex_unlock(&instance->reset_mutex);
megasas_reset_fusion(instance->host, megasas_reset_fusion(instance->host,
MFI_IO_TIMEOUT_OCR); MFI_IO_TIMEOUT_OCR);
mutex_lock(&instance->reset_mutex);
break; break;
case KILL_ADAPTER: case KILL_ADAPTER:
megaraid_sas_kill_hba(instance); megaraid_sas_kill_hba(instance);
...@@ -7801,10 +7811,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -7801,10 +7811,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
opcode = le32_to_cpu(cmd->frame->dcmd.opcode); opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
if (opcode == MR_DCMD_CTRL_SHUTDOWN) { if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
mutex_lock(&instance->reset_mutex);
if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) {
megasas_return_cmd(instance, cmd); megasas_return_cmd(instance, cmd);
mutex_unlock(&instance->reset_mutex);
return -1; return -1;
} }
mutex_unlock(&instance->reset_mutex);
} }
if (opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) { if (opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) {
......
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