From 1a9e394154e34728f58c1f697b993aaaf89a4db2 Mon Sep 17 00:00:00 2001 From: "Matthew R. Ochs" Date: Fri, 25 Aug 2017 17:18:03 -0500 Subject: [PATCH] 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 Signed-off-by: Uma Krishnan Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/superpipe.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index 08da593cb2f6..ed46e8df2e42 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -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 @@ retry_recover: 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 @@ retry_recover: out: if (likely(ctxi)) put_context(ctxi); - mutex_unlock(mutex); + if (locked) + mutex_unlock(mutex); atomic_dec_if_positive(&cfg->recovery_threads); return rc; } -- 2.11.0