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

Commit 1a9e3941 authored by Matthew R. Ochs's avatar Matthew R. Ochs Committed by Martin K. Petersen
Browse files

scsi: cxlflash: Avoid double mutex unlock



The AFU recovery routine uses an interruptible mutex to control the flow
of in-flight recoveries. Upon receiving an interruptible signal the code
branches to a common exit path which wrongly assumes the mutex is
held. Add a local variable to track when the mutex should be unlocked.

Signed-off-by: default avatarMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: default avatarUma Krishnan <ukrishn@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 48a17ad5
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -1651,6 +1651,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
	u64 ctxid = DECODE_CTXID(recover->context_id),
	    rctxid = recover->context_id;
	long reg;
	bool locked = true;
	int lretry = 20; /* up to 2 seconds */
	int new_adap_fd = -1;
	int rc = 0;
@@ -1659,8 +1660,11 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
	up_read(&cfg->ioctl_rwsem);
	rc = mutex_lock_interruptible(mutex);
	down_read(&cfg->ioctl_rwsem);
	if (rc)
	if (rc) {
		locked = false;
		goto out;
	}

	rc = check_state(cfg);
	if (rc) {
		dev_err(dev, "%s: Failed state rc=%d\n", __func__, rc);
@@ -1694,8 +1698,10 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
				mutex_unlock(mutex);
				msleep(100);
				rc = mutex_lock_interruptible(mutex);
				if (rc)
				if (rc) {
					locked = false;
					goto out;
				}
				goto retry_recover;
			}

@@ -1739,6 +1745,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
out:
	if (likely(ctxi))
		put_context(ctxi);
	if (locked)
		mutex_unlock(mutex);
	atomic_dec_if_positive(&cfg->recovery_threads);
	return rc;