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

Commit 1cb14cce authored by Anand Lodnoor's avatar Anand Lodnoor Committed by Greg Kroah-Hartman
Browse files

scsi: megaraid_sas: Do not initiate OCR if controller is not in ready state

commit 6d7537270e3283b92f9b327da9d58a4de40fe8d0 upstream.

Driver initiates OCR if a DCMD command times out. But there is a deadlock
if the driver attempts to invoke another OCR before the mutex lock
(reset_mutex) is released from the previous session of OCR.

This patch takes care of the above scenario using new flag
MEGASAS_FUSION_OCR_NOT_POSSIBLE to indicate if OCR is possible.

Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/1579000882-20246-9-git-send-email-anand.lodnoor@broadcom.com


Signed-off-by: default avatarShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: default avatarAnand Lodnoor <anand.lodnoor@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1de085c8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -4177,7 +4177,8 @@ dcmd_timeout_ocr_possible(struct megasas_instance *instance) {
	if (instance->adapter_type == MFI_SERIES)
		return KILL_ADAPTER;
	else if (instance->unload ||
			test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
			test_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE,
				 &instance->reset_flags))
		return IGNORE_TIMEOUT;
	else
		return INITIATE_OCR;
+2 −1
Original line number Diff line number Diff line
@@ -4558,6 +4558,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
		del_timer_sync(&instance->sriov_heartbeat_timer);
	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
	set_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags);
	atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING);
	instance->instancet->disable_intr(instance);
	megasas_sync_irqs((unsigned long)instance);
@@ -4747,7 +4748,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
		atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
	}
out:
	clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
	clear_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags);
	mutex_unlock(&instance->reset_mutex);
	return retval;
}
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {

#define MEGASAS_FP_CMD_LEN	16
#define MEGASAS_FUSION_IN_RESET 0
#define MEGASAS_FUSION_OCR_NOT_POSSIBLE 1
#define THRESHOLD_REPLY_COUNT 50
#define RAID_1_PEER_CMDS 2
#define JBOD_MAPS_COUNT	2