mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 01:56:42 +07:00
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: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
48a17ad593
commit
1a9e394154
@ -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,7 +1745,8 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
|
||||
out:
|
||||
if (likely(ctxi))
|
||||
put_context(ctxi);
|
||||
mutex_unlock(mutex);
|
||||
if (locked)
|
||||
mutex_unlock(mutex);
|
||||
atomic_dec_if_positive(&cfg->recovery_threads);
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user