On 10/4/23 05:07, Petr Tesařík wrote: > I just want to confirm that my understanding of the issue is correct > now. After applying the patch below, my laptop has just survived half a > dozen suspend/resume cycles with autosuspend enabled for the SATA SSD > disk. Without the patch, it usually freezes on first attempt. > > diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c > index a371b497035e..87000f89319e 100644 > --- a/drivers/ata/libata-scsi.c > +++ b/drivers/ata/libata-scsi.c > @@ -4768,6 +4768,14 @@ void ata_scsi_dev_rescan(struct work_struct *work) > ata_for_each_dev(dev, link, ENABLED) { > struct scsi_device *sdev = dev->sdev; > > + /* > + * If the queue accepts only PM, bail out. > + */ > + if (blk_queue_pm_only(sdev->request_queue)) { > + ret = -EAGAIN; > + goto unlock; > + } > + > /* > * If the port was suspended before this was scheduled, > * bail out. This seems sensible to me: scsi_rescan_device() only checks that the device is running, without checking that the device queue is also resumed. So the right place for this check is scsi_rescan_device(): diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 3db4d31a03a1..b05a55f498a2 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1627,12 +1627,13 @@ int scsi_rescan_device(struct scsi_device *sdev) device_lock(dev); /* - * Bail out if the device is not running. Otherwise, the rescan may - * block waiting for commands to be executed, with us holding the - * device lock. This can result in a potential deadlock in the power - * management core code when system resume is on-going. + * Bail out if the device or its queue are not running. Otherwise, + * the rescan may block waiting for commands to be executed, with us + * holding the device lock. This can result in a potential deadlock + * in the power management core code when system resume is on-going. */ - if (sdev->sdev_state != SDEV_RUNNING) { + if (sdev->sdev_state != SDEV_RUNNING || + blk_queue_pm_only(sdev->request_queue)) { ret = -EWOULDBLOCK; goto unlock; } Can you try the above to confirm it works for you ? It should, as that is essentially the same as you did. -- Damien Le Moal Western Digital Research