Re: [PATCH] sparc64: Use relaxed ordering for DMA_FROM_DEVICE mappings on sun4v

From: Tony Rodriguez

Date: Wed Oct 21 2026 - 17:25:54 EST



On 10/21/26 1:49 PM, John Paul Adrian Glaubitz wrote:
Hi Tony,

On Wed, 2026-10-21 at 13:30 -0700, Tony Rodriguez wrote:
On 10/13/26 6:37 AM, Stian Halseth wrote:

sun4v IOMMU and ATU mappings carry a relaxed ordering attribute, but
dma_4v_map_phys() and dma_4v_map_sg() set it only when the caller
passes DMA_ATTR_WEAK_ORDERING. Some network drivers do, storage drivers
do not. Without it every device write into memory is strictly ordered,
which on a T7-1 (M7) caps DMA reads at about 280 MiB/s per PCIe device
while writes run at full speed.

Set the attribute for every DMA_FROM_DEVICE streaming mapping. Devices
report completion through coherent memory or an interrupt, which stay
strictly ordered, and a strictly ordered write does not pass the writes
before it.

T7-1, fio 1M sequential read, QD32:

before after
NVMe (PM1725, x4) 281 MiB/s 3169 MiB/s
SATA SSD (mpt3sas) 278 MiB/s 502 MiB/s

Closes: https://github.com/sparclinux/issues/issues/114
Signed-off-by: Stian Halseth <stian@xxxxxx>
---
Tested on a T7-1 (M7) and a T4-1:

- T7: fresh RAID1 on two NVMe drives, 192 GB fio crc32c write+verify
and md check: no errors, mismatch_cnt 0.
- T7 and T4: file checksums on the SAS boot mirrors identical to a
strictly ordered kernel; no new messages in dmesg.
- 4k random read and sequential writes unchanged.

arch/sparc/kernel/pci_sun4v.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 61f14b4c8f90d..4dd17b65dd6cc 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -403,7 +403,7 @@ static dma_addr_t dma_4v_map_phys(struct device *dev, phys_addr_t phys,
if (direction != DMA_TO_DEVICE)
prot |= HV_PCI_MAP_ATTR_WRITE;
- if (attrs & DMA_ATTR_WEAK_ORDERING)
+ if (direction == DMA_FROM_DEVICE || (attrs & DMA_ATTR_WEAK_ORDERING))
prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER;
local_irq_save(flags);
@@ -503,7 +503,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
if (direction != DMA_TO_DEVICE)
prot |= HV_PCI_MAP_ATTR_WRITE;
- if (attrs & DMA_ATTR_WEAK_ORDERING)
+ if (direction == DMA_FROM_DEVICE || (attrs & DMA_ATTR_WEAK_ORDERING))
prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER;
outs = s = segstart = &sglist[0];
Tested-by: Tony Rodriguez <unixpro1970@xxxxxxxxx>

Tested on a Sparc S7-2 with a Samsung 2TB EVO SATA SSD.
No functional issues or major regressions were observed.
Did you also see the vast improvement that Stian has reported?

Adrian

Yes, with certain fio tests.  IOPS have improved:

Note(s):

1) The following output does not include Stian's AES patch (needed to test against luks).   Reached out to him about a question regarding applying that patch.  In other words, this is a non luks tests.

2)  I also don't have NVMe installed within my Sparc S7-2.

3) Sata SSD will not reach NVMe performance (due to Sata SSD design limitation).  However, improvements were noticed with Sata SSD.

-------------------------------------------------------------------------------------
A = Before Patch                  B = After Patch
-------------------------------------------------------------------------------------

A1) Jobs: 1 (f=1): [R(1)][100.0%][r=314MiB/s][r=314 IOPS]
read: IOPS=314, BW=314MiB/s (329MB/s)(18.4GiB/60101msec)

B1) Jobs: 1 (f=1): [R(1)][100.0%][r=544MiB/s][r=544 IOPS]
read: IOPS=543, BW=543MiB/s (570MB/s)(31.9GiB/60058msec)

A2) Jobs: 4 (f=4): [R(4)][100.0%][r=456MiB/s][r=456 IOPS]
read: IOPS=456, BW=456MiB/s (478MB/s)(26.8GiB/60273msec)

B2) Jobs: 4 (f=4): [R(4)][100.0%][r=544MiB/s][r=544 IOPS]
read: IOPS=544, BW=544MiB/s (570MB/s)(32.0GiB/60232msec)

A4) Jobs: 1 (f=1): [r(1)][100.0%][r=36.5MiB/s][r=9346 IOPS]
read: IOPS=9824, BW=38.4MiB/s (40.2MB/s)(2303MiB/60001msec)

B4) Jobs: 1 (f=1): [r(1)][100.0%][r=44.7MiB/s][r=11.4k IOPS]
read: IOPS=11.4k, BW=44.6MiB/s (46.8MB/s)(2676MiB/60001msec)