From ab4538cd6fb47c5a3475d0652830a1d4c8c46167 Mon Sep 17 00:00:00 2001 From: Ashok Vairavan Date: Wed, 7 Dec 2016 16:10:38 -0800 Subject: [PATCH] NVMe: reduce admin queue depth as workaround for Samsung EPIC SQ errata Orabug: 25186219 PCIe analyzer tracing by Oracle and Samsung revealed an errata in Samsung's firmware for EPIC SSDs where the invalid completion entries in admin queue and IO queue can occur when the queues straddle an 8MB DMA address boundary. This patch limits admin queue depth to 64 for EPIC SSDs. Signed-off-by: Ashok Vairavan Reviewed-by: Martin K. Petersen Signed-off-by: Dhaval Giani --- drivers/nvme/host/pci.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 27558d4ad858..7b94ca1a23aa 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1710,7 +1710,6 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) if (!dev->admin_q) { dev->admin_tagset.ops = &nvme_mq_admin_ops; dev->admin_tagset.nr_hw_queues = 1; - dev->admin_tagset.queue_depth = NVME_AQ_DEPTH - 1; dev->admin_tagset.reserved_tags = 1; dev->admin_tagset.timeout = ADMIN_TIMEOUT; dev->admin_tagset.numa_node = dev_to_node(dev->dev); @@ -1770,7 +1769,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) nvmeq = dev->queues[0]; if (!nvmeq) { - nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH); + nvmeq = nvme_alloc_queue(dev, 0, dev->admin_tagset.queue_depth + 1); if (!nvmeq) return -ENOMEM; } @@ -2677,10 +2676,17 @@ static int nvme_pci_enable(struct nvme_dev *dev) * size should not span a DMA page (64 x 64B) unless NVME_CAP_MQES(cap) * already restricted it further. */ - if (pdev->vendor == PCI_VENDOR_ID_SAMSUNG && pdev->device == 0xa821 ) { - dev->q_depth = min_t(int, dev->q_depth, 64); - dev_warn(dev->dev, "detected Samsung NVMe controller, limit " - "queue depth=%u.\n", dev->q_depth); + + dev->admin_tagset.queue_depth = NVME_AQ_DEPTH - 1; + + if (pdev->vendor == PCI_VENDOR_ID_SAMSUNG) { + if(pdev->device == 0xa821 || pdev->device == 0xa822) { + dev->q_depth = min_t(int, dev->q_depth, 64); + dev->admin_tagset.queue_depth = min_t(int, NVME_AQ_DEPTH, 64) - 1; + dev_warn(dev->dev, "detected Samsung PM172x controller, limit " + "IO queue depth to %u and admin queue depth to %u.\n", + dev->q_depth, dev->admin_tagset.queue_depth); + } } if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) -- 2.50.1