From: Ashok Vairavan Date: Thu, 8 Dec 2016 00:10:38 +0000 (-0800) Subject: NVMe: reduce admin queue depth as workaround for Samsung EPIC SQ errata X-Git-Tag: v4.1.12-102.0.20170601_1400~65 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f68721333fcfce60d62dd0ed8d853f7a3c11da7e;p=users%2Fjedix%2Flinux-maple.git 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 --- diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index f0b0b0c97d8e4..55bac17cb94d9 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))