diff options
author | Tejun Heo <tj@kernel.org> | 2020-09-02 12:32:45 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-09-02 11:31:23 -0600 |
commit | 3b5455636fe26ea21b4189d135a424a6da016418 (patch) | |
tree | 8658ea2acbc2338358ea2f86d1ad1d05c5c83c6d /drivers/ata/libata-scsi.c | |
parent | e276c9bd14c75278d1354efbaea278500147d6b3 (diff) | |
download | linux-stable-3b5455636fe26ea21b4189d135a424a6da016418.tar.gz linux-stable-3b5455636fe26ea21b4189d135a424a6da016418.tar.bz2 linux-stable-3b5455636fe26ea21b4189d135a424a6da016418.zip |
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>
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index ec233208585b..c7b5049b42d1 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -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]); } |