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

Commit 982ea6f9 authored by Bart Van Assche's avatar Bart Van Assche Committed by Martin K. Petersen
Browse files

scsi: mpt3sas: Fix a race condition in mpt3sas_base_hard_reset_handler()



Since ioc->shost_recovery is set after ioc->reset_in_progress_mutex is
obtained, if concurrent resets are issued there is a short time during
which ioc->reset_in_progress_mutex is locked and ioc->shost_recovery ==
0. Avoid that this can cause trouble by unconditionally locking
ioc->shost_recovery.

Signed-off-by: default avatarBart Van Assche <bart.vanassche@wdc.com>
Cc: Sathya Prakash <sathya.prakash@broadcom.com>
Cc: Chaitra P B <chaitra.basappa@broadcom.com>
Cc: Suganath Prabu Subramani <suganath-prabu.subramani@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 91b7bdb2
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -6959,14 +6959,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
		mpt3sas_halt_firmware(ioc);

	/* wait for an active reset in progress to complete */
	if (!mutex_trylock(&ioc->reset_in_progress_mutex)) {
		do {
			ssleep(1);
		} while (ioc->shost_recovery == 1);
		dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name,
		    __func__));
		return ioc->ioc_reset_in_progress_status;
	}
	mutex_lock(&ioc->reset_in_progress_mutex);

	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
	ioc->shost_recovery = 1;
@@ -7015,7 +7008,6 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
	    ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED")));

	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
	ioc->ioc_reset_in_progress_status = r;
	ioc->shost_recovery = 0;
	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
	ioc->ioc_reset_count++;
+0 −1
Original line number Diff line number Diff line
@@ -1166,7 +1166,6 @@ struct MPT3SAS_ADAPTER {
	struct mutex	reset_in_progress_mutex;
	spinlock_t	ioc_reset_in_progress_lock;
	u8		ioc_link_reset_in_progress;
	u8		ioc_reset_in_progress_status;

	u8		ignore_loginfos;
	u8		remove_host;