Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Matthew R. Ochs and committed by
Martin K. Petersen
1a9e3941 48a17ad5

+10 -3
+10 -3
drivers/scsi/cxlflash/superpipe.c
··· 1651 1651 u64 ctxid = DECODE_CTXID(recover->context_id), 1652 1652 rctxid = recover->context_id; 1653 1653 long reg; 1654 + bool locked = true; 1654 1655 int lretry = 20; /* up to 2 seconds */ 1655 1656 int new_adap_fd = -1; 1656 1657 int rc = 0; ··· 1660 1659 up_read(&cfg->ioctl_rwsem); 1661 1660 rc = mutex_lock_interruptible(mutex); 1662 1661 down_read(&cfg->ioctl_rwsem); 1663 - if (rc) 1662 + if (rc) { 1663 + locked = false; 1664 1664 goto out; 1665 + } 1666 + 1665 1667 rc = check_state(cfg); 1666 1668 if (rc) { 1667 1669 dev_err(dev, "%s: Failed state rc=%d\n", __func__, rc); ··· 1698 1694 mutex_unlock(mutex); 1699 1695 msleep(100); 1700 1696 rc = mutex_lock_interruptible(mutex); 1701 - if (rc) 1697 + if (rc) { 1698 + locked = false; 1702 1699 goto out; 1700 + } 1703 1701 goto retry_recover; 1704 1702 } 1705 1703 ··· 1745 1739 out: 1746 1740 if (likely(ctxi)) 1747 1741 put_context(ctxi); 1748 - mutex_unlock(mutex); 1742 + if (locked) 1743 + mutex_unlock(mutex); 1749 1744 atomic_dec_if_positive(&cfg->recovery_threads); 1750 1745 return rc; 1751 1746 }