linux/drivers/nvme/host
Robert Beckett bfe52e8019 nvme-pci: 512 byte aligned dma pool segment quirk
[ Upstream commit ebefac5647 ]

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: 83bdfcbdbe ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2025-01-09 13:33:34 +01:00
..
apple.c for-6.11/block-20240710 2024-07-15 14:20:22 -07:00
auth.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
constants.c nvme: fix status magic numbers 2024-06-24 12:53:42 -07:00
core.c Revert "nvme: make keep-alive synchronous operation" 2024-12-14 20:04:09 +01:00
fabrics.c nvme-tcp: check for invalidated or revoked key 2024-08-22 13:25:07 -07:00
fabrics.h nvme-pci: do not directly handle subsys reset fallout 2024-06-26 07:02:22 -07:00
fault_inject.c fault-inject: improve build for CONFIG_FAULT_INJECTION=n 2024-09-01 20:43:33 -07:00
fc.c nvme-pci: do not directly handle subsys reset fallout 2024-06-26 07:02:22 -07:00
fc.h nvme-fc: Update header and host for common definitions for LS handling 2020-05-09 16:18:33 -06:00
hwmon.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
ioctl.c nvme: re-fix error-handling for io_uring nvme-passthrough 2024-10-30 07:19:18 -07:00
Kconfig nvme-tcp: fix link failure for TCP auth 2024-09-10 07:41:07 -07:00
Makefile nvme: rework NVME_AUTH Kconfig selection 2023-10-12 08:04:49 -07:00
multipath.c nvme/multipath: Fix RCU list traversal to use SRCU primitive 2024-12-05 14:03:05 +01:00
nvme.h nvme-pci: 512 byte aligned dma pool segment quirk 2025-01-09 13:33:34 +01:00
pci.c nvme-pci: 512 byte aligned dma pool segment quirk 2025-01-09 13:33:34 +01:00
pr.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
rdma.c nvme-rdma: unquiesce admin_q before destroy it 2024-12-14 20:03:17 +01:00
sysfs.c nvme: null terminate nvme_tls_attrs 2024-09-24 23:34:13 -07:00
tcp.c nvme-tcp: fix the memleak while create new ctrl failed 2024-12-14 20:03:17 +01:00
trace.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
trace.h nvme: fix async event trace event 2023-04-13 08:59:04 +02:00
zns.c block: Remove REQ_OP_ZONE_RESET_ALL emulation 2024-07-05 00:42:04 -06:00