On 8/31/21 12:24 AM, Adrian Hunter wrote:
How does splitting the host_sem address the potential deadlock
between the error handler and runtime resume?
Hmm ... how do runtime resume and the error handler deadlock? If
shost->eh_noresume == 0 then scsi_error_handler() will call
scsi_autopm_get_host() before invoking the eh_strategy_handler callback.
The definition of scsi_autopm_get_host() is as follows:
int scsi_autopm_get_host(struct Scsi_Host *shost)
{
int err;
err = pm_runtime_get_sync(&shost->shost_gendev);
if (err < 0 && err !=-EACCES)
pm_runtime_put_sync(&shost->shost_gendev);
else
err = 0;
return err;
}
The power management operations used for shost_gendev instances are
defined by scsi_bus_pm_ops (see also scsi_host_alloc()). The following
function is the runtime resume function referenced by scsi_bus_pm_ops
and skips shost_gendevs since these are not SCSI devices:
static int scsi_runtime_resume(struct device *dev)
{
int err = 0;
dev_dbg(dev, "scsi_runtime_resume\n");
if (scsi_is_sdev_device(dev))
err = sdev_runtime_resume(dev);
/* Insert hooks here for targets, hosts, and transport classes*/
return err;
}
In addition to the above function the runtime resume callback of the UFS
platform device is also invoked. I think all these functions call
ufshcd_runtime_resume(). As far as I can see ufshcd_runtime_resume()
does not touch host_sem?
Bart.