From: Jussi Maki <hidden> Date: 2021-05-28 08:34:54
Hi all,
While measuring the impact of a kernel patch on our lab machines I stumbled upon
a performance regression affecting the 100Gbit ICE nic and bisected it
from range v5.11.1..v5.13-rc3 to the commit:
a250c23f15c2 iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE
Both recent bpf-next (d6a6a55518) and linux-stable (c4681547bc) are
affected by the issue.
The regression shows as a significant drop in throughput as measured
with "super_netperf" [0],
with measured bandwidth of ~95Gbps before and ~35Gbps after:
commit 3189713a1b84 (a250c23^):
$ ./super_netperf 32 -H 172.18.0.2 -l 10
97379.8
commit a250c23f15c2:
$ ./super_netperf 32 -H 172.18.0.2 -l 10
34097.5
The pair of test machines have this hardware:
CPU: AMD Ryzen 9 3950X 16-Core Processor
MB: X570 AORUS MASTER
0a:00.0 Ethernet controller [0200]: Intel Corporation Ethernet
Controller E810-C for QSFP [8086:1592] (rev 02)
Kernel config: https://gist.github.com/joamaki/9ee11294c78a8dd2776041f67e5620e7
[0] https://github.com/borkmann/stuff/blob/master/super_netperf
From: Daniel Borkmann <daniel@iogearbox.net> Date: 2021-06-01 06:57:44
[ ping Robin / Joerg, +Cc Christoph ]
On 5/28/21 10:34 AM, Jussi Maki wrote:
Hi all,
While measuring the impact of a kernel patch on our lab machines I stumbled upon
a performance regression affecting the 100Gbit ICE nic and bisected it
from range v5.11.1..v5.13-rc3 to the commit:
a250c23f15c2 iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE
Both recent bpf-next (d6a6a55518) and linux-stable (c4681547bc) are
affected by the issue.
The regression shows as a significant drop in throughput as measured
with "super_netperf" [0],
with measured bandwidth of ~95Gbps before and ~35Gbps after:
commit 3189713a1b84 (a250c23^):
$ ./super_netperf 32 -H 172.18.0.2 -l 10
97379.8
commit a250c23f15c2:
$ ./super_netperf 32 -H 172.18.0.2 -l 10
34097.5
The pair of test machines have this hardware:
CPU: AMD Ryzen 9 3950X 16-Core Processor
MB: X570 AORUS MASTER
0a:00.0 Ethernet controller [0200]: Intel Corporation Ethernet
Controller E810-C for QSFP [8086:1592] (rev 02)
Kernel config: https://gist.github.com/joamaki/9ee11294c78a8dd2776041f67e5620e7
[0] https://github.com/borkmann/stuff/blob/master/super_netperf
From: Robin Murphy <robin.murphy@arm.com> Date: 2021-06-01 12:39:46
On 2021-06-01 07:57, Daniel Borkmann wrote:
[ ping Robin / Joerg, +Cc Christoph ]
Sorry, I was off on Friday on top of the Bank Holiday yesterday.
On 5/28/21 10:34 AM, Jussi Maki wrote:
quoted
Hi all,
While measuring the impact of a kernel patch on our lab machines I
stumbled upon
a performance regression affecting the 100Gbit ICE nic and bisected it
from range v5.11.1..v5.13-rc3 to the commit:
a250c23f15c2 iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE
Both recent bpf-next (d6a6a55518) and linux-stable (c4681547bc) are
affected by the issue.
The regression shows as a significant drop in throughput as measured
with "super_netperf" [0],
with measured bandwidth of ~95Gbps before and ~35Gbps after:
I guess that must be the difference between using the flush queue
vs. strict invalidation. On closer inspection, it seems to me that
there's a subtle pre-existing bug in the AMD IOMMU driver, in that
amd_iommu_init_dma_ops() actually runs *after* amd_iommu_init_api()
has called bus_set_iommu(). Does the patch below work?
Robin.
----->8-----
Subject: [PATCH] iommu/amd: Tidy up DMA ops init
Now that DMA ops are part of the core API via iommu-dma, fold the
vestigial remains of the IOMMU_DMA_OPS init state into the IOMMU API
phase, and clean up a few other leftovers. This should also close the
race window wherein bus_set_iommu() effectively makes the DMA ops state
visible before its nominal initialisation, which since commit
a250c23f15c2 ("iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE") can now
lead to the wrong flush queue policy being picked.
Reported-by: Jussi Maki <redacted>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
drivers/iommu/amd/amd_iommu.h | 2 --
drivers/iommu/amd/init.c | 5 -----
drivers/iommu/amd/iommu.c | 29 ++++++++++++-----------------
3 files changed, 12 insertions(+), 24 deletions(-)
From: Jussi Maki <hidden> Date: 2021-06-01 17:42:22
Hi Robin,
On Tue, Jun 1, 2021 at 2:39 PM Robin Murphy [off-list ref] wrote:
quoted
quoted
The regression shows as a significant drop in throughput as measured
with "super_netperf" [0],
with measured bandwidth of ~95Gbps before and ~35Gbps after:
I guess that must be the difference between using the flush queue
vs. strict invalidation. On closer inspection, it seems to me that
there's a subtle pre-existing bug in the AMD IOMMU driver, in that
amd_iommu_init_dma_ops() actually runs *after* amd_iommu_init_api()
has called bus_set_iommu(). Does the patch below work?
Thanks for the quick response & patch. I tried it out and indeed it
does solve the issue:
# uname -a
Linux zh-lab-node-3 5.13.0-rc3-amd-iommu+ #31 SMP Tue Jun 1 17:12:57
UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@zh-lab-node-3:~# ./super_netperf 32 -H 172.18.0.2
95341.2
root@zh-lab-node-3:~# uname -a
Linux zh-lab-node-3 5.13.0-rc3-amd-iommu-unpatched #32 SMP Tue Jun 1
17:29:34 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@zh-lab-node-3:~# ./super_netperf 32 -H 172.18.0.2
33989.5
From: Daniel Borkmann <daniel@iogearbox.net> Date: 2021-06-02 08:09:41
On 6/1/21 7:42 PM, Jussi Maki wrote:
Hi Robin,
On Tue, Jun 1, 2021 at 2:39 PM Robin Murphy [off-list ref] wrote:
quoted
quoted
quoted
The regression shows as a significant drop in throughput as measured
with "super_netperf" [0],
with measured bandwidth of ~95Gbps before and ~35Gbps after:
I guess that must be the difference between using the flush queue
vs. strict invalidation. On closer inspection, it seems to me that
there's a subtle pre-existing bug in the AMD IOMMU driver, in that
amd_iommu_init_dma_ops() actually runs *after* amd_iommu_init_api()
has called bus_set_iommu(). Does the patch below work?
Thanks for the quick response & patch. I tried it out and indeed it
does solve the issue:
# uname -a
Linux zh-lab-node-3 5.13.0-rc3-amd-iommu+ #31 SMP Tue Jun 1 17:12:57
UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@zh-lab-node-3:~# ./super_netperf 32 -H 172.18.0.2
95341.2
root@zh-lab-node-3:~# uname -a
Linux zh-lab-node-3 5.13.0-rc3-amd-iommu-unpatched #32 SMP Tue Jun 1
17:29:34 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@zh-lab-node-3:~# ./super_netperf 32 -H 172.18.0.2
33989.5
Robin, probably goes without saying, but please make sure to include ...
Fixes: a250c23f15c2 ("iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE")
... to your fix in [0], maybe along with another Fixes tag pointing to the original
commit adding this issue. But certainly a250c23f15c2 would be good given the regression
was uncovered on that one first, so that Greg et al have a chance to pick this fix up
for stable kernels.
Thanks everyone!
[0] https://lore.kernel.org/bpf/7f048c57-423b-68ba-eede-7e194c1fea4e@arm.com/
From: Robin Murphy <robin.murphy@arm.com> Date: 2021-06-02 12:49:04
On 2021-06-02 09:09, Daniel Borkmann wrote:
On 6/1/21 7:42 PM, Jussi Maki wrote:
quoted
Hi Robin,
On Tue, Jun 1, 2021 at 2:39 PM Robin Murphy [off-list ref] wrote:
quoted
quoted
quoted
The regression shows as a significant drop in throughput as measured
with "super_netperf" [0],
with measured bandwidth of ~95Gbps before and ~35Gbps after:
I guess that must be the difference between using the flush queue
vs. strict invalidation. On closer inspection, it seems to me that
there's a subtle pre-existing bug in the AMD IOMMU driver, in that
amd_iommu_init_dma_ops() actually runs *after* amd_iommu_init_api()
has called bus_set_iommu(). Does the patch below work?
Thanks for the quick response & patch. I tried it out and indeed it
does solve the issue:
Cool, thanks Jussi. May I infer a Tested-by tag from that?
quoted
# uname -a
Linux zh-lab-node-3 5.13.0-rc3-amd-iommu+ #31 SMP Tue Jun 1 17:12:57
UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@zh-lab-node-3:~# ./super_netperf 32 -H 172.18.0.2
95341.2
root@zh-lab-node-3:~# uname -a
Linux zh-lab-node-3 5.13.0-rc3-amd-iommu-unpatched #32 SMP Tue Jun 1
17:29:34 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@zh-lab-node-3:~# ./super_netperf 32 -H 172.18.0.2
33989.5
Robin, probably goes without saying, but please make sure to include ...
Fixes: a250c23f15c2 ("iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE")
... to your fix in [0], maybe along with another Fixes tag pointing to
the original
commit adding this issue. But certainly a250c23f15c2 would be good given
the regression
was uncovered on that one first, so that Greg et al have a chance to
pick this fix up
for stable kernels.
Given that the race looks to have been pretty theoretical until now, I'm
not convinced it's worth the bother of digging through the long history
of default domain and DMA ops movement to figure where it started, much
less attempt invasive backports. The flush queue change which made it
apparent only landed in 5.13-rc1, so as long as we can get this in as a
fix in the current cycle we should be golden - in the meantime, note
that booting with "iommu.strict=0" should also restore the expected
behaviour.
FWIW I do still plan to resend the patch "properly" soon (in all honesty
it wasn't even compile-tested!)
Cheers,
Robin.
From: Jussi Maki <hidden> Date: 2021-06-03 12:34:03
On Wed, Jun 2, 2021 at 2:49 PM Robin Murphy [off-list ref] wrote:
quoted
quoted
Thanks for the quick response & patch. I tried it out and indeed it
does solve the issue:
Cool, thanks Jussi. May I infer a Tested-by tag from that?
Of course!
Given that the race looks to have been pretty theoretical until now, I'm
not convinced it's worth the bother of digging through the long history
of default domain and DMA ops movement to figure where it started, much
less attempt invasive backports. The flush queue change which made it
apparent only landed in 5.13-rc1, so as long as we can get this in as a
fix in the current cycle we should be golden - in the meantime, note
that booting with "iommu.strict=0" should also restore the expected
behaviour.
FWIW I do still plan to resend the patch "properly" soon (in all honesty
it wasn't even compile-tested!)
BTW, even with the patch there's quite a bit of spin lock contention
coming from ice_xmit_xdp_ring->dma_map_page_attrs->...->alloc_iova.
CPU load drops from 85% to 20% (~80Mpps, 64b UDP) when iommu is
disabled. Is this type of overhead to be expected?
From: Robin Murphy <robin.murphy@arm.com> Date: 2021-06-03 13:09:56
On 2021-06-03 13:32, Jussi Maki wrote:
On Wed, Jun 2, 2021 at 2:49 PM Robin Murphy [off-list ref] wrote:
quoted
quoted
quoted
Thanks for the quick response & patch. I tried it out and indeed it
does solve the issue:
Cool, thanks Jussi. May I infer a Tested-by tag from that?
Of course!
quoted
Given that the race looks to have been pretty theoretical until now, I'm
not convinced it's worth the bother of digging through the long history
of default domain and DMA ops movement to figure where it started, much
less attempt invasive backports. The flush queue change which made it
apparent only landed in 5.13-rc1, so as long as we can get this in as a
fix in the current cycle we should be golden - in the meantime, note
that booting with "iommu.strict=0" should also restore the expected
behaviour.
FWIW I do still plan to resend the patch "properly" soon (in all honesty
it wasn't even compile-tested!)
BTW, even with the patch there's quite a bit of spin lock contention
coming from ice_xmit_xdp_ring->dma_map_page_attrs->...->alloc_iova.
CPU load drops from 85% to 20% (~80Mpps, 64b UDP) when iommu is
disabled. Is this type of overhead to be expected?
Yes, IOVA allocation can still be a bottleneck - the percpu caching
system mostly alleviates it, but certain workloads can still defeat
that, and if you're spending significant time in alloc_iova() rather
than alloc_iova_fast() then it sounds like yours is one of them.
If you're using small IOVA sizes which *should* be cached, then you
might be running into a pathological case of thrashing the global depot.
I've ranted before about the fixed MAX_GLOBAL_MAGS probably being too
small for systems with more than 16 CPUs, which on a modern AMD system I
imagine you may well have.
If on the other hand your workload is making larger mappings above the
IOVA caching threshold, then please take a look at John's series for
making that tuneable:
https://lore.kernel.org/linux-iommu/1622557781-211697-1-git-send-email-john.garry@huawei.com/
Cheers,
Robin.