Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libata: implement ATA_HORKAGE_MAX_TRIM_128M and apply to Sandisks

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>

authored by

Tejun Heo and committed by
Jens Axboe
3b545563 e276c9bd

+10 -4
+2 -3
drivers/ata/libata-core.c
··· 3868 3868 /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ 3869 3869 { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, }, 3870 3870 3871 - /* Some Sandisk SSDs lock up hard with NCQ enabled. Reported on 3872 - SD7SN6S256G and SD8SN8U256G */ 3873 - { "SanDisk SD[78]SN*G", NULL, ATA_HORKAGE_NONCQ, }, 3871 + /* Sandisk SD7/8/9s lock up hard on large trims */ 3872 + { "SanDisk SD[789]*", NULL, ATA_HORKAGE_MAX_TRIM_128M, }, 3874 3873 3875 3874 /* devices which puke on READ_NATIVE_MAX */ 3876 3875 { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },
+7 -1
drivers/ata/libata-scsi.c
··· 2080 2080 2081 2081 static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) 2082 2082 { 2083 + struct ata_device *dev = args->dev; 2083 2084 u16 min_io_sectors; 2084 2085 2085 2086 rbuf[1] = 0xb0; ··· 2106 2105 * with the unmap bit set. 2107 2106 */ 2108 2107 if (ata_id_has_trim(args->id)) { 2109 - put_unaligned_be64(65535 * ATA_MAX_TRIM_RNUM, &rbuf[36]); 2108 + u64 max_blocks = 65535 * ATA_MAX_TRIM_RNUM; 2109 + 2110 + if (dev->horkage & ATA_HORKAGE_MAX_TRIM_128M) 2111 + max_blocks = 128 << (20 - SECTOR_SHIFT); 2112 + 2113 + put_unaligned_be64(max_blocks, &rbuf[36]); 2110 2114 put_unaligned_be32(1, &rbuf[28]); 2111 2115 } 2112 2116
+1
include/linux/libata.h
··· 421 421 ATA_HORKAGE_NO_DMA_LOG = (1 << 23), /* don't use DMA for log read */ 422 422 ATA_HORKAGE_NOTRIM = (1 << 24), /* don't use TRIM */ 423 423 ATA_HORKAGE_MAX_SEC_1024 = (1 << 25), /* Limit max sects to 1024 */ 424 + ATA_HORKAGE_MAX_TRIM_128M = (1 << 26), /* Limit max trim size to 128M */ 424 425 425 426 /* DMA mask for user DMA control: User visible values; DO NOT 426 427 renumber */