libata: implement ATA_HORKAGE_MAX_TRIM_128M and apply to Sandisks
authorTejun Heo <tj@kernel.org>
Wed, 2 Sep 2020 16:32:45 +0000 (12:32 -0400)
committerJens Axboe <axboe@kernel.dk>
Wed, 2 Sep 2020 17:31:23 +0000 (11:31 -0600)
All three generations of Sandisk SSDs lock up hard intermittently.
Experiments showed that disabling NCQ lowered the failure rate significantly
and the kernel has been disabling NCQ for some models of SD7's and 8's,
which is obviously undesirable.

Karthik worked with Sandisk to root cause the hard lockups to trim commands
larger than 128M. This patch implements ATA_HORKAGE_MAX_TRIM_128M which
limits max trim size to 128M and applies it to all three generations of
Sandisk SSDs.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Karthik Shivaram <karthikgs@fb.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
include/linux/libata.h

index b1cd4d97bc2a75994361aa88e7c86a305aa8f5d7..1be73d29119ab8890bb247f208305be4f0195d13 100644 (file)
@@ -3868,9 +3868,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
        { "C300-CTFDDAC128MAG", "0001",         ATA_HORKAGE_NONCQ, },
 
-       /* Some Sandisk SSDs lock up hard with NCQ enabled.  Reported on
-          SD7SN6S256G and SD8SN8U256G */
-       { "SanDisk SD[78]SN*G", NULL,           ATA_HORKAGE_NONCQ, },
+       /* Sandisk SD7/8/9s lock up hard on large trims */
+       { "SanDisk SD[789]*",   NULL,           ATA_HORKAGE_MAX_TRIM_128M, },
 
        /* devices which puke on READ_NATIVE_MAX */
        { "HDS724040KLSA80",    "KFAOA20N",     ATA_HORKAGE_BROKEN_HPA, },
index ec233208585bd4ad58a4feab9b7d3fb442f07f1c..c7b5049b42d1f9c2488bd8cd69726a5e1aed1ad4 100644 (file)
@@ -2080,6 +2080,7 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
 
 static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
 {
+       struct ata_device *dev = args->dev;
        u16 min_io_sectors;
 
        rbuf[1] = 0xb0;
@@ -2105,7 +2106,12 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
         * with the unmap bit set.
         */
        if (ata_id_has_trim(args->id)) {
-               put_unaligned_be64(65535 * ATA_MAX_TRIM_RNUM, &rbuf[36]);
+               u64 max_blocks = 65535 * ATA_MAX_TRIM_RNUM;
+
+               if (dev->horkage & ATA_HORKAGE_MAX_TRIM_128M)
+                       max_blocks = 128 << (20 - SECTOR_SHIFT);
+
+               put_unaligned_be64(max_blocks, &rbuf[36]);
                put_unaligned_be32(1, &rbuf[28]);
        }
 
index 77ccf040a128b1461f9a1762eaf3c6439eabc6eb..5f550eb27f811ad7b73c72d9a84daae3c730c900 100644 (file)
@@ -421,6 +421,7 @@ enum {
        ATA_HORKAGE_NO_DMA_LOG  = (1 << 23),    /* don't use DMA for log read */
        ATA_HORKAGE_NOTRIM      = (1 << 24),    /* don't use TRIM */
        ATA_HORKAGE_MAX_SEC_1024 = (1 << 25),   /* Limit max sects to 1024 */
+       ATA_HORKAGE_MAX_TRIM_128M = (1 << 26),  /* Limit max trim size to 128M */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */