]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
NVMe: reduce admin queue depth as workaround for Samsung EPIC SQ errata
authorAshok Vairavan <ashok.vairavan@oracle.com>
Thu, 8 Dec 2016 00:10:38 +0000 (16:10 -0800)
committerDhaval Giani <dhaval.giani@oracle.com>
Sat, 21 Jan 2017 01:53:53 +0000 (20:53 -0500)
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 <ashok.vairavan@oracle.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Dhaval Giani <dhaval.giani@oracle.com>
drivers/nvme/host/pci.c

index 27558d4ad8582672f0a72c967699cdf7fbc755b8..7b94ca1a23aa6deb2595e9faeeb3238528a29d70 100644 (file)
@@ -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))