Patch "nvme-pci: 512 byte aligned dma pool segment quirk" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    nvme-pci: 512 byte aligned dma pool segment quirk

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     nvme-pci-512-byte-aligned-dma-pool-segment-quirk.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4bf8d6a45448632dcf55c336f5d19a6fcc50607f
Author: Robert Beckett <bob.beckett@xxxxxxxxxxxxx>
Date:   Tue Nov 12 19:50:00 2024 +0000

    nvme-pci: 512 byte aligned dma pool segment quirk
    
    [ Upstream commit ebefac5647968679f6ef5803e5d35a71997d20fa ]
    
    We initially introduced a quick fix limiting the queue depth to 1 as
    experimentation showed that it fixed data corruption on 64GB steamdecks.
    
    Further experimentation revealed corruption only happens when the last
    PRP data element aligns to the end of the page boundary. The device
    appears to treat this as a PRP chain to a new list instead of the data
    element that it actually is. This implementation is in violation of the
    spec. Encountering this errata with the Linux driver requires the host
    request a 128k transfer and coincidently be handed the last small pool
    dma buffer within a page.
    
    The QD1 quirk effectly works around this because the last data PRP
    always was at a 248 byte offset from the page start, so it never
    appeared at the end of the page, but comes at the expense of throttling
    IO and wasting the remainder of the PRP page beyond 256 bytes. Also to
    note, the MDTS on these devices is small enough that the "large" prp
    pool can hold enough PRP elements to never reach the end, so that pool
    is not a problem either.
    
    Introduce a new quirk to ensure the small pool is always aligned such
    that the last PRP element can't appear a the end of the page. This comes
    at the expense of wasting 256 bytes per small pool page allocated.
    
    Link: https://lore.kernel.org/linux-nvme/20241113043151.GA20077@xxxxxx/T/#u
    Fixes: 83bdfcbdbe5d ("nvme-pci: qdepth 1 quirk")
    Cc: Paweł Anikiel <panikiel@xxxxxxxxxx>
    Signed-off-by: Robert Beckett <bob.beckett@xxxxxxxxxxxxx>
    Signed-off-by: Keith Busch <kbusch@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index bddc068d58c7..e867ac859a87 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -172,6 +172,11 @@ enum nvme_quirks {
 	 * MSI (but not MSI-X) interrupts are broken and never fire.
 	 */
 	NVME_QUIRK_BROKEN_MSI			= (1 << 21),
+
+	/*
+	 * Align dma pool segment size to 512 bytes
+	 */
+	NVME_QUIRK_DMAPOOL_ALIGN_512		= (1 << 22),
 };
 
 /*
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index d525fa1229d7..52c8fd3d5c47 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2653,15 +2653,20 @@ static int nvme_disable_prepare_reset(struct nvme_dev *dev, bool shutdown)
 
 static int nvme_setup_prp_pools(struct nvme_dev *dev)
 {
+	size_t small_align = 256;
+
 	dev->prp_page_pool = dma_pool_create("prp list page", dev->dev,
 						NVME_CTRL_PAGE_SIZE,
 						NVME_CTRL_PAGE_SIZE, 0);
 	if (!dev->prp_page_pool)
 		return -ENOMEM;
 
+	if (dev->ctrl.quirks & NVME_QUIRK_DMAPOOL_ALIGN_512)
+		small_align = 512;
+
 	/* Optimisation for I/Os between 4k and 128k */
 	dev->prp_small_pool = dma_pool_create("prp list 256", dev->dev,
-						256, 256, 0);
+						256, small_align, 0);
 	if (!dev->prp_small_pool) {
 		dma_pool_destroy(dev->prp_page_pool);
 		return -ENOMEM;
@@ -3403,7 +3408,7 @@ static const struct pci_device_id nvme_id_table[] = {
 	{ PCI_VDEVICE(REDHAT, 0x0010),	/* Qemu emulated controller */
 		.driver_data = NVME_QUIRK_BOGUS_NID, },
 	{ PCI_DEVICE(0x1217, 0x8760), /* O2 Micro 64GB Steam Deck */
-		.driver_data = NVME_QUIRK_QDEPTH_ONE },
+		.driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, },
 	{ PCI_DEVICE(0x126f, 0x2262),	/* Silicon Motion generic */
 		.driver_data = NVME_QUIRK_NO_DEEPEST_PS |
 				NVME_QUIRK_BOGUS_NID, },




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux