From f68721333fcfce60d62dd0ed8d853f7a3c11da7e 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, 13 insertions(+), 5 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index f0b0b0c97d8e..55bac17cb94d 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1200,6 +1200,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) * condition. See NVM-Express 1.2 specification, section 4.1.2. */ dev->admin_tagset.queue_depth = NVME_AQ_BLKMQ_DEPTH - 1; + dev->admin_tagset.reserved_tags = 1; dev->admin_tagset.timeout = ADMIN_TIMEOUT; dev->admin_tagset.numa_node = dev_to_node(dev->dev); dev->admin_tagset.cmd_size = nvme_cmd_size(dev); @@ -1244,7 +1245,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; } @@ -1696,10 +1697,17 @@ static int nvme_dev_map(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 + NVME_REG_VS) >= NVME_VS(1, 2)) -- 2.50.1