Patch "ata,scsi: do not issue START STOP UNIT on resume" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ata,scsi: do not issue START STOP UNIT on resume

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     ata-scsi-do-not-issue-start-stop-unit-on-resume.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 3bdffcb01d762ec932de44fbb950d6d3a828d08f
Author: Damien Le Moal <dlemoal@xxxxxxxxxx>
Date:   Mon Jul 24 13:23:14 2023 +0900

    ata,scsi: do not issue START STOP UNIT on resume
    
    [ Upstream commit 0a8589055936d8feb56477123a8373ac634018fa ]
    
    During system resume, ata_port_pm_resume() triggers ata EH to
    1) Resume the controller
    2) Reset and rescan the ports
    3) Revalidate devices
    This EH execution is started asynchronously from ata_port_pm_resume(),
    which means that when sd_resume() is executed, none or only part of the
    above processing may have been executed. However, sd_resume() issues a
    START STOP UNIT to wake up the drive from sleep mode. This command is
    translated to ATA with ata_scsi_start_stop_xlat() and issued to the
    device. However, depending on the state of execution of the EH process
    and revalidation triggerred by ata_port_pm_resume(), two things may
    happen:
    1) The START STOP UNIT fails if it is received before the controller has
       been reenabled at the beginning of the EH execution. This is visible
       with error messages like:
    
    ata10.00: device reported invalid CHS sector 0
    sd 9:0:0:0: [sdc] Start/Stop Unit failed: Result: hostbyte=DID_OK driverbyte=DRIVER_OK
    sd 9:0:0:0: [sdc] Sense Key : Illegal Request [current]
    sd 9:0:0:0: [sdc] Add. Sense: Unaligned write command
    sd 9:0:0:0: PM: dpm_run_callback(): scsi_bus_resume+0x0/0x90 returns -5
    sd 9:0:0:0: PM: failed to resume async: error -5
    
    2) The START STOP UNIT command is received while the EH process is
       on-going, which mean that it is stopped and must wait for its
       completion, at which point the command is rather useless as the drive
       is already fully spun up already. This case results also in a
       significant delay in sd_resume() which is observable by users as
       the entire system resume completion is delayed.
    
    Given that ATA devices will be woken up by libata activity on resume,
    sd_resume() has no need to issue a START STOP UNIT command, which solves
    the above mentioned problems. Do not issue this command by introducing
    the new scsi_device flag no_start_on_resume and setting this flag to 1
    in ata_scsi_dev_config(). sd_resume() is modified to issue a START STOP
    UNIT command only if this flag is not set.
    
    Reported-by: Paul Ausbeck <paula@xxxxxxxxxxxx>
    Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215880
    Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
    Signed-off-by: Damien Le Moal <dlemoal@xxxxxxxxxx>
    Tested-by: Tanner Watkins <dalzot@xxxxxxxxx>
    Tested-by: Paul Ausbeck <paula@xxxxxxxxxxxx>
    Reviewed-by: Hannes Reinecke <hare@xxxxxxx>
    Reviewed-by: Bart Van Assche <bvanassche@xxxxxxx>
    Stable-dep-of: 99398d2070ab ("scsi: sd: Do not issue commands to suspended disks on shutdown")
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index d28628b964e29..9c8dd9f86cbb3 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1081,7 +1081,14 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev)
 		}
 	} else {
 		sdev->sector_size = ata_id_logical_sector_size(dev->id);
+		/*
+		 * Stop the drive on suspend but do not issue START STOP UNIT
+		 * on resume as this is not necessary and may fail: the device
+		 * will be woken up by ata_port_pm_resume() with a port reset
+		 * and device revalidation.
+		 */
 		sdev->manage_start_stop = 1;
+		sdev->no_start_on_resume = 1;
 	}
 
 	/*
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index e934779bf05c8..5bfca49415113 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3718,7 +3718,7 @@ static int sd_suspend_runtime(struct device *dev)
 static int sd_resume(struct device *dev)
 {
 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
-	int ret;
+	int ret = 0;
 
 	if (!sdkp)	/* E.g.: runtime resume at the start of sd_probe() */
 		return 0;
@@ -3726,8 +3726,11 @@ static int sd_resume(struct device *dev)
 	if (!sdkp->device->manage_start_stop)
 		return 0;
 
-	sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
-	ret = sd_start_stop_device(sdkp, 1);
+	if (!sdkp->device->no_start_on_resume) {
+		sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
+		ret = sd_start_stop_device(sdkp, 1);
+	}
+
 	if (!ret)
 		opal_unlock_from_suspend(sdkp->opal_dev);
 	return ret;
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 006858ed04e8c..9fdc77db3a2a8 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -193,6 +193,7 @@ struct scsi_device {
 	unsigned no_start_on_add:1;	/* do not issue start on add */
 	unsigned allow_restart:1; /* issue START_UNIT in error handler */
 	unsigned manage_start_stop:1;	/* Let HLD (sd) manage start/stop */
+	unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */
 	unsigned start_stop_pwr_cond:1;	/* Set power cond. in START_STOP_UNIT */
 	unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
 	unsigned select_no_atn:1;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux