diff mbox series

[v6] libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD.

Message ID 20210903094411.58749-1-hpa@redhat.com
State New
Headers show
Series [v6] libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD. | expand

Commit Message

Kate Hsuan Sept. 3, 2021, 9:44 a.m. UTC
Many users are reporting that the Samsung 860 and 870 SSD are having
various issues when combined with AMD/ATI (vendor ID 0x1002)  SATA
controllers and only completely disabling NCQ helps to avoid these
issues.

Always disabling NCQ for Samsung 860/870 SSDs regardless of the host
SATA adapter vendor will cause I/O performance degradation with well
behaved adapters. To limit the performance impact to ATI adapters,
introduce the ATA_HORKAGE_NO_NCQ_ON_ATI flag to force disable NCQ
only for these adapters.

Also, two libata.force parameters (noncqati and ncqati) are introduced
to disable and enable the NCQ for the system which equipped with ATI
SATA adapter and Samsung 860 and 870 SSDs. The user can determine NCQ
function to be enabled or disabled according to the demand.

After verifying the chipset from the user reports, the issue appears
on AMD/ATI SB7x0/SB8x0/SB9x0 SATA Controllers and does not appear on
recent AMD SATA adapters. The vendor ID of ATI should be 0x1002.
Therefore, ATA_HORKAGE_NO_NCQ_ON_AMD was modified to
ATA_HORKAGE_NO_NCQ_ON_ATI.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=201693
Signed-off-by: Kate Hsuan <hpa@redhat.com>
---
Changes in v6:
* The adapter vendor ID check was revised to PCI_VENDOR_ID_ATI.
* ATA_HORKAGE_NO_NCQ_ON_AMD was revised to ATA_HORKAGE_NO_NCQ_ON_ATI.
* Two libata.force parameters was modified to noncqati and ncqati.

Changes in v5:
* The libata.force parameters ncqamd and noncqamd are used to enable and
  disable the NCQ for the systems equiped with AMD SATA adapter and
  Samsung 860 and 870 SSDs.
* The character encoding of the patch comment was fixed.

Changes in v4:
* A function ata_dev_check_adapter() is added to check the vendor ID of
  the adapter.
* ATA_HORKAGE_NONCQ_ON_AMD was modified to ATA_HORKAGE_NO_NCQ_ON_AMD to
  align with the naming convention.
* Commit messages were improved according to reviewer comments.

Changes in v3:
* ATA_HORKAGE_NONCQ_ON_ASMEDIA_AMD_MARVELL was modified to
  ATA_HORKAGE_NONCQ_ON_AMD.
* Codes were fixed to completely disable NCQ on AMD controller.

---
 drivers/ata/libata-core.c | 34 ++++++++++++++++++++++++++++++++--
 include/linux/libata.h    |  1 +
 2 files changed, 33 insertions(+), 2 deletions(-)

--
2.31.1

Comments

Hans de Goede Sept. 3, 2021, 10:03 a.m. UTC | #1
Hi,

On 9/3/21 11:44 AM, Kate Hsuan wrote:
> Many users are reporting that the Samsung 860 and 870 SSD are having
> various issues when combined with AMD/ATI (vendor ID 0x1002)  SATA
> controllers and only completely disabling NCQ helps to avoid these
> issues.
> 
> Always disabling NCQ for Samsung 860/870 SSDs regardless of the host
> SATA adapter vendor will cause I/O performance degradation with well
> behaved adapters. To limit the performance impact to ATI adapters,
> introduce the ATA_HORKAGE_NO_NCQ_ON_ATI flag to force disable NCQ
> only for these adapters.
> 
> Also, two libata.force parameters (noncqati and ncqati) are introduced
> to disable and enable the NCQ for the system which equipped with ATI
> SATA adapter and Samsung 860 and 870 SSDs. The user can determine NCQ
> function to be enabled or disabled according to the demand.
> 
> After verifying the chipset from the user reports, the issue appears
> on AMD/ATI SB7x0/SB8x0/SB9x0 SATA Controllers and does not appear on
> recent AMD SATA adapters. The vendor ID of ATI should be 0x1002.
> Therefore, ATA_HORKAGE_NO_NCQ_ON_AMD was modified to
> ATA_HORKAGE_NO_NCQ_ON_ATI.
> 
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=201693
> Signed-off-by: Kate Hsuan <hpa@redhat.com>

Thanks, patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans


> ---
> Changes in v6:
> * The adapter vendor ID check was revised to PCI_VENDOR_ID_ATI.
> * ATA_HORKAGE_NO_NCQ_ON_AMD was revised to ATA_HORKAGE_NO_NCQ_ON_ATI.
> * Two libata.force parameters was modified to noncqati and ncqati.
> 
> Changes in v5:
> * The libata.force parameters ncqamd and noncqamd are used to enable and
>   disable the NCQ for the systems equiped with AMD SATA adapter and
>   Samsung 860 and 870 SSDs.
> * The character encoding of the patch comment was fixed.
> 
> Changes in v4:
> * A function ata_dev_check_adapter() is added to check the vendor ID of
>   the adapter.
> * ATA_HORKAGE_NONCQ_ON_AMD was modified to ATA_HORKAGE_NO_NCQ_ON_AMD to
>   align with the naming convention.
> * Commit messages were improved according to reviewer comments.
> 
> Changes in v3:
> * ATA_HORKAGE_NONCQ_ON_ASMEDIA_AMD_MARVELL was modified to
>   ATA_HORKAGE_NONCQ_ON_AMD.
> * Codes were fixed to completely disable NCQ on AMD controller.
> 
> ---
>  drivers/ata/libata-core.c | 34 ++++++++++++++++++++++++++++++++--
>  include/linux/libata.h    |  1 +
>  2 files changed, 33 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 3eda3291952b..85e4e56c0681 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -2199,6 +2199,25 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
> 
>  }
> 
> +static bool ata_dev_check_adapter(struct ata_device *dev,
> +				  unsigned short vendor_id)
> +{
> +	struct pci_dev *pcidev = NULL;
> +	struct device *parent_dev = NULL;
> +
> +	for (parent_dev = dev->tdev.parent; parent_dev != NULL;
> +	     parent_dev = parent_dev->parent) {
> +		if (dev_is_pci(parent_dev)) {
> +			pcidev = to_pci_dev(parent_dev);
> +			if (pcidev->vendor == vendor_id)
> +				return true;
> +			break;
> +		}
> +	}
> +
> +	return false;
> +}
> +
>  static int ata_dev_config_ncq(struct ata_device *dev,
>  			       char *desc, size_t desc_sz)
>  {
> @@ -2217,6 +2236,13 @@ static int ata_dev_config_ncq(struct ata_device *dev,
>  		snprintf(desc, desc_sz, "NCQ (not used)");
>  		return 0;
>  	}
> +
> +	if (dev->horkage & ATA_HORKAGE_NO_NCQ_ON_ATI &&
> +	    ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI)) {
> +		snprintf(desc, desc_sz, "NCQ (not used)");
> +		return 0;
> +	}
> +
>  	if (ap->flags & ATA_FLAG_NCQ) {
>  		hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE);
>  		dev->flags |= ATA_DFLAG_NCQ;
> @@ -3951,9 +3977,11 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
>  	{ "Samsung SSD 850*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
>  						ATA_HORKAGE_ZERO_AFTER_TRIM, },
>  	{ "Samsung SSD 860*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
> -						ATA_HORKAGE_ZERO_AFTER_TRIM, },
> +						ATA_HORKAGE_ZERO_AFTER_TRIM |
> +						ATA_HORKAGE_NO_NCQ_ON_ATI, },
>  	{ "Samsung SSD 870*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
> -						ATA_HORKAGE_ZERO_AFTER_TRIM, },
> +						ATA_HORKAGE_ZERO_AFTER_TRIM |
> +						ATA_HORKAGE_NO_NCQ_ON_ATI, },
>  	{ "FCCT*M500*",			NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
>  						ATA_HORKAGE_ZERO_AFTER_TRIM, },
> 
> @@ -6108,6 +6136,8 @@ static int __init ata_parse_force_one(char **cur,
>  		{ "ncq",	.horkage_off	= ATA_HORKAGE_NONCQ },
>  		{ "noncqtrim",	.horkage_on	= ATA_HORKAGE_NO_NCQ_TRIM },
>  		{ "ncqtrim",	.horkage_off	= ATA_HORKAGE_NO_NCQ_TRIM },
> +		{ "noncqati",	.horkage_on	= ATA_HORKAGE_NO_NCQ_ON_ATI },
> +		{ "ncqati",	.horkage_off	= ATA_HORKAGE_NO_NCQ_ON_ATI },
>  		{ "dump_id",	.horkage_on	= ATA_HORKAGE_DUMP_ID },
>  		{ "pio0",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 0) },
>  		{ "pio1",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 1) },
> diff --git a/include/linux/libata.h b/include/linux/libata.h
> index 3fcd24236793..cb95d3f3337d 100644
> --- a/include/linux/libata.h
> +++ b/include/linux/libata.h
> @@ -422,6 +422,7 @@ enum {
>  	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 */
> +	ATA_HORKAGE_NO_NCQ_ON_ATI = (1 << 27),	/* Disable NCQ on ATI chipset */
> 
>  	 /* DMA mask for user DMA control: User visible values; DO NOT
>  	    renumber */
> --
> 2.31.1
>
Jens Axboe Sept. 3, 2021, 12:35 p.m. UTC | #2
On 9/3/21 3:44 AM, Kate Hsuan wrote:
> Many users are reporting that the Samsung 860 and 870 SSD are having
> various issues when combined with AMD/ATI (vendor ID 0x1002)  SATA
> controllers and only completely disabling NCQ helps to avoid these
> issues.
> 
> Always disabling NCQ for Samsung 860/870 SSDs regardless of the host
> SATA adapter vendor will cause I/O performance degradation with well
> behaved adapters. To limit the performance impact to ATI adapters,
> introduce the ATA_HORKAGE_NO_NCQ_ON_ATI flag to force disable NCQ
> only for these adapters.
> 
> Also, two libata.force parameters (noncqati and ncqati) are introduced
> to disable and enable the NCQ for the system which equipped with ATI
> SATA adapter and Samsung 860 and 870 SSDs. The user can determine NCQ
> function to be enabled or disabled according to the demand.
> 
> After verifying the chipset from the user reports, the issue appears
> on AMD/ATI SB7x0/SB8x0/SB9x0 SATA Controllers and does not appear on
> recent AMD SATA adapters. The vendor ID of ATI should be 0x1002.
> Therefore, ATA_HORKAGE_NO_NCQ_ON_AMD was modified to
> ATA_HORKAGE_NO_NCQ_ON_ATI.

What's this patch against?
Martin K. Petersen Sept. 3, 2021, 1:08 p.m. UTC | #3
Kate,

> Many users are reporting that the Samsung 860 and 870 SSD are having
> various issues when combined with AMD/ATI (vendor ID 0x1002) SATA
> controllers and only completely disabling NCQ helps to avoid these
> issues.

Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Hans de Goede Sept. 3, 2021, 2:03 p.m. UTC | #4
Hi,

On 9/3/21 2:35 PM, Jens Axboe wrote:
> On 9/3/21 3:44 AM, Kate Hsuan wrote:
>> Many users are reporting that the Samsung 860 and 870 SSD are having
>> various issues when combined with AMD/ATI (vendor ID 0x1002)  SATA
>> controllers and only completely disabling NCQ helps to avoid these
>> issues.
>>
>> Always disabling NCQ for Samsung 860/870 SSDs regardless of the host
>> SATA adapter vendor will cause I/O performance degradation with well
>> behaved adapters. To limit the performance impact to ATI adapters,
>> introduce the ATA_HORKAGE_NO_NCQ_ON_ATI flag to force disable NCQ
>> only for these adapters.
>>
>> Also, two libata.force parameters (noncqati and ncqati) are introduced
>> to disable and enable the NCQ for the system which equipped with ATI
>> SATA adapter and Samsung 860 and 870 SSDs. The user can determine NCQ
>> function to be enabled or disabled according to the demand.
>>
>> After verifying the chipset from the user reports, the issue appears
>> on AMD/ATI SB7x0/SB8x0/SB9x0 SATA Controllers and does not appear on
>> recent AMD SATA adapters. The vendor ID of ATI should be 0x1002.
>> Therefore, ATA_HORKAGE_NO_NCQ_ON_AMD was modified to
>> ATA_HORKAGE_NO_NCQ_ON_ATI.
> 
> What's this patch against?

linux-block/for-next + my pre-cursor patch from here:

https://lore.kernel.org/linux-ide/20210823095220.30157-1-hdegoede@redhat.com/T/#u

Regards,

Hans
Jens Axboe Sept. 3, 2021, 2:05 p.m. UTC | #5
On 9/3/21 8:03 AM, Hans de Goede wrote:
> Hi,
> 
> On 9/3/21 2:35 PM, Jens Axboe wrote:
>> On 9/3/21 3:44 AM, Kate Hsuan wrote:
>>> Many users are reporting that the Samsung 860 and 870 SSD are having
>>> various issues when combined with AMD/ATI (vendor ID 0x1002)  SATA
>>> controllers and only completely disabling NCQ helps to avoid these
>>> issues.
>>>
>>> Always disabling NCQ for Samsung 860/870 SSDs regardless of the host
>>> SATA adapter vendor will cause I/O performance degradation with well
>>> behaved adapters. To limit the performance impact to ATI adapters,
>>> introduce the ATA_HORKAGE_NO_NCQ_ON_ATI flag to force disable NCQ
>>> only for these adapters.
>>>
>>> Also, two libata.force parameters (noncqati and ncqati) are introduced
>>> to disable and enable the NCQ for the system which equipped with ATI
>>> SATA adapter and Samsung 860 and 870 SSDs. The user can determine NCQ
>>> function to be enabled or disabled according to the demand.
>>>
>>> After verifying the chipset from the user reports, the issue appears
>>> on AMD/ATI SB7x0/SB8x0/SB9x0 SATA Controllers and does not appear on
>>> recent AMD SATA adapters. The vendor ID of ATI should be 0x1002.
>>> Therefore, ATA_HORKAGE_NO_NCQ_ON_AMD was modified to
>>> ATA_HORKAGE_NO_NCQ_ON_ATI.
>>
>> What's this patch against?
> 
> linux-block/for-next + my pre-cursor patch from here:
> 
> https://lore.kernel.org/linux-ide/20210823095220.30157-1-hdegoede@redhat.com/T/#u

Still had to fixup a hunk, but it was trivial. In any case, I've applied
both now, thanks!
diff mbox series

Patch

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3eda3291952b..85e4e56c0681 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2199,6 +2199,25 @@  static void ata_dev_config_ncq_prio(struct ata_device *dev)

 }

+static bool ata_dev_check_adapter(struct ata_device *dev,
+				  unsigned short vendor_id)
+{
+	struct pci_dev *pcidev = NULL;
+	struct device *parent_dev = NULL;
+
+	for (parent_dev = dev->tdev.parent; parent_dev != NULL;
+	     parent_dev = parent_dev->parent) {
+		if (dev_is_pci(parent_dev)) {
+			pcidev = to_pci_dev(parent_dev);
+			if (pcidev->vendor == vendor_id)
+				return true;
+			break;
+		}
+	}
+
+	return false;
+}
+
 static int ata_dev_config_ncq(struct ata_device *dev,
 			       char *desc, size_t desc_sz)
 {
@@ -2217,6 +2236,13 @@  static int ata_dev_config_ncq(struct ata_device *dev,
 		snprintf(desc, desc_sz, "NCQ (not used)");
 		return 0;
 	}
+
+	if (dev->horkage & ATA_HORKAGE_NO_NCQ_ON_ATI &&
+	    ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI)) {
+		snprintf(desc, desc_sz, "NCQ (not used)");
+		return 0;
+	}
+
 	if (ap->flags & ATA_FLAG_NCQ) {
 		hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE);
 		dev->flags |= ATA_DFLAG_NCQ;
@@ -3951,9 +3977,11 @@  static const struct ata_blacklist_entry ata_device_blacklist [] = {
 	{ "Samsung SSD 850*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
 	{ "Samsung SSD 860*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
-						ATA_HORKAGE_ZERO_AFTER_TRIM, },
+						ATA_HORKAGE_ZERO_AFTER_TRIM |
+						ATA_HORKAGE_NO_NCQ_ON_ATI, },
 	{ "Samsung SSD 870*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
-						ATA_HORKAGE_ZERO_AFTER_TRIM, },
+						ATA_HORKAGE_ZERO_AFTER_TRIM |
+						ATA_HORKAGE_NO_NCQ_ON_ATI, },
 	{ "FCCT*M500*",			NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },

@@ -6108,6 +6136,8 @@  static int __init ata_parse_force_one(char **cur,
 		{ "ncq",	.horkage_off	= ATA_HORKAGE_NONCQ },
 		{ "noncqtrim",	.horkage_on	= ATA_HORKAGE_NO_NCQ_TRIM },
 		{ "ncqtrim",	.horkage_off	= ATA_HORKAGE_NO_NCQ_TRIM },
+		{ "noncqati",	.horkage_on	= ATA_HORKAGE_NO_NCQ_ON_ATI },
+		{ "ncqati",	.horkage_off	= ATA_HORKAGE_NO_NCQ_ON_ATI },
 		{ "dump_id",	.horkage_on	= ATA_HORKAGE_DUMP_ID },
 		{ "pio0",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 0) },
 		{ "pio1",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 1) },
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 3fcd24236793..cb95d3f3337d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -422,6 +422,7 @@  enum {
 	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 */
+	ATA_HORKAGE_NO_NCQ_ON_ATI = (1 << 27),	/* Disable NCQ on ATI chipset */

 	 /* DMA mask for user DMA control: User visible values; DO NOT
 	    renumber */