]> www.infradead.org Git - nvme.git/commit
nvme-pci: 512 byte aligned dma pool segment quirk
authorRobert Beckett <bob.beckett@collabora.com>
Tue, 12 Nov 2024 19:50:00 +0000 (19:50 +0000)
committerKeith Busch <kbusch@kernel.org>
Wed, 11 Dec 2024 22:46:23 +0000 (14:46 -0800)
commitebefac5647968679f6ef5803e5d35a71997d20fa
treed5ece58dff8906da369d565686bae9d92f4c1337
parent790eb09e59709a1ffc1c64fe4aae2789120851b0
nvme-pci: 512 byte aligned dma pool segment quirk

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@lst.de/T/#u
Fixes: 83bdfcbdbe5d ("nvme-pci: qdepth 1 quirk")
Cc: Paweł Anikiel <panikiel@google.com>
Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c