scsi: cxlflash: Avoid double mutex unlock
authorMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Fri, 25 Aug 2017 22:18:03 +0000 (17:18 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 25 Aug 2017 22:23:34 +0000 (18:23 -0400)
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>
drivers/scsi/cxlflash/superpipe.c

index 08da593..ed46e8d 100644 (file)
@@ -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;
 }