Commit 8c36cde2 authored by Tejun Heo's avatar Tejun Heo Committed by Greg Kroah-Hartman

libata: implement ATA_HORKAGE_MAX_TRIM_128M and apply to Sandisks

commit 3b545563 upstream.

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: default avatarTejun Heo <tj@kernel.org>
Cc: Karthik Shivaram <karthikgs@fb.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d24c407b
...@@ -4371,9 +4371,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -4371,9 +4371,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
/* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
{ "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, }, { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, },
/* Some Sandisk SSDs lock up hard with NCQ enabled. Reported on /* Sandisk SD7/8/9s lock up hard on large trims */
SD7SN6S256G and SD8SN8U256G */ { "SanDisk SD[789]*", NULL, ATA_HORKAGE_MAX_TRIM_128M, },
{ "SanDisk SD[78]SN*G", NULL, ATA_HORKAGE_NONCQ, },
/* devices which puke on READ_NATIVE_MAX */ /* devices which puke on READ_NATIVE_MAX */
{ "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },
......
...@@ -2314,6 +2314,7 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2314,6 +2314,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) static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
{ {
struct ata_device *dev = args->dev;
u16 min_io_sectors; u16 min_io_sectors;
rbuf[1] = 0xb0; rbuf[1] = 0xb0;
...@@ -2339,7 +2340,12 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) ...@@ -2339,7 +2340,12 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
* with the unmap bit set. * with the unmap bit set.
*/ */
if (ata_id_has_trim(args->id)) { 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]); put_unaligned_be32(1, &rbuf[28]);
} }
......
...@@ -435,6 +435,7 @@ enum { ...@@ -435,6 +435,7 @@ enum {
ATA_HORKAGE_NO_NCQ_LOG = (1 << 23), /* don't use NCQ for log read */ ATA_HORKAGE_NO_NCQ_LOG = (1 << 23), /* don't use NCQ for log read */
ATA_HORKAGE_NOTRIM = (1 << 24), /* don't use TRIM */ ATA_HORKAGE_NOTRIM = (1 << 24), /* don't use TRIM */
ATA_HORKAGE_MAX_SEC_1024 = (1 << 25), /* Limit max sects to 1024 */ 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 /* DMA mask for user DMA control: User visible values; DO NOT
renumber */ renumber */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment