aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/cxlflash/superpipe.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c
index d8a5cb3cd2bd..ce1507023132 100644
--- a/drivers/scsi/cxlflash/superpipe.c
+++ b/drivers/scsi/cxlflash/superpipe.c
@@ -1615,6 +1615,13 @@ err1:
1615 * place at the same time and the failure was due to CXL services being 1615 * place at the same time and the failure was due to CXL services being
1616 * unable to keep up. 1616 * unable to keep up.
1617 * 1617 *
1618 * As this routine is called on ioctl context, it holds the ioctl r/w
1619 * semaphore that is used to drain ioctls in recovery scenarios. The
1620 * implementation to achieve the pacing described above (a local mutex)
1621 * requires that the ioctl r/w semaphore be dropped and reacquired to
1622 * avoid a 3-way deadlock when multiple process recoveries operate in
1623 * parallel.
1624 *
1618 * Because a user can detect an error condition before the kernel, it is 1625 * Because a user can detect an error condition before the kernel, it is
1619 * quite possible for this routine to act as the kernel's EEH detection 1626 * quite possible for this routine to act as the kernel's EEH detection
1620 * source (MMIO read of mbox_r). Because of this, there is a window of 1627 * source (MMIO read of mbox_r). Because of this, there is a window of
@@ -1642,9 +1649,17 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
1642 int rc = 0; 1649 int rc = 0;
1643 1650
1644 atomic_inc(&cfg->recovery_threads); 1651 atomic_inc(&cfg->recovery_threads);
1652 up_read(&cfg->ioctl_rwsem);
1645 rc = mutex_lock_interruptible(mutex); 1653 rc = mutex_lock_interruptible(mutex);
1654 down_read(&cfg->ioctl_rwsem);
1646 if (rc) 1655 if (rc)
1647 goto out; 1656 goto out;
1657 rc = check_state(cfg);
1658 if (rc) {
1659 dev_err(dev, "%s: Failed state! rc=%d\n", __func__, rc);
1660 rc = -ENODEV;
1661 goto out;
1662 }
1648 1663
1649 dev_dbg(dev, "%s: reason 0x%016llX rctxid=%016llX\n", 1664 dev_dbg(dev, "%s: reason 0x%016llX rctxid=%016llX\n",
1650 __func__, recover->reason, rctxid); 1665 __func__, recover->reason, rctxid);