Skip to content

[FROM-ML] IOMMU Performance Optimization support - #14

Merged
NeroReflex merged 2 commits into
OpenGamingCollective:masterfrom
superm1:superm1/ogc-unstable-iommu-perfopt
Aug 31, 2026
Merged

[FROM-ML] IOMMU Performance Optimization support#14
NeroReflex merged 2 commits into
OpenGamingCollective:masterfrom
superm1:superm1/ogc-unstable-iommu-perfopt

Conversation

@superm1

@superm1 superm1 commented Aug 31, 2026

Copy link
Copy Markdown

Add support for the AMD IOMMU Performance Optimization (PerfOpt)
feature as defined in the AMD I/O Virtualization Technology (IOMMU)
Specification, Section 3.4.9 (MMIO Offset 016Ch).

This feature allows privileged integrated I/O devices (GPUs) to bypass
the IOMMU when directly accessing system memory. The IOMMU only
enforces the IR/IW permission bits without GPA->SPA translations.

Drivers will opt into this behavior, and enable amdgpu to turn this
feature on when an integrated GPU is already in identity mode.
If a user prefers to keep it always off (even with identity mode)
there is also a module parameter to force it off.

This comes from this series: https://lore.kernel.org/linux-iommu/20260831055108.1893285-1-mario.limonciello@amd.com/

@superm1 superm1 changed the title IOMMU Performance Optimization support [FROM-ML] IOMMU Performance Optimization support Aug 31, 2026
Add support for the AMD IOMMU Performance Optimization (PerfOpt)
feature as defined in the AMD I/O Virtualization Technology (IOMMU)
Specification, Section 3.4.9 (MMIO Offset 016Ch).

This feature allows privileged integrated I/O devices (GPUs) to bypass
the IOMMU when directly accessing system memory.  The IOMMU only
enforces the IR/IW permission bits without GPA->SPA translations.

amd_iommu_enable_perfopt() performs a detach/reattach cycle to rehome
devices already on the identity domain with ATS/PRI/PASID/GCR3
disabled (skip_caps path).  amd_iommu_disable_perfopt() restores those
capabilities.  The per-device dev_data->perfopt flag tracks state.

PERF_OPT_EN is a single control bit per IOMMU, shared by every device
behind that IOMMU, while enablement is requested per device.  It is
therefore reference counted (amd_iommu->perfopt_refcount): armed on the
first requesting device and cleared on the last, so one device's
teardown never clears the bit while a peer behind the same IOMMU still
needs it.

The per-device flag is cleared on every teardown path
(blocked_domain_attach, release_device, and amd_iommu_disable_perfopt),
dropping the reference with it, so a reused dev_data never carries stale
PerfOpt state onto its next bind.

On suspend/resume the hardware is reprogrammed from scratch:
amd_iommu_perfopt_clear() forces the bit off without touching the
reference count, and amd_iommu_perfopt_restore() re-asserts it from the
count after early_enable_iommu(), so armed devices keep the optimization
across resume without relying on each consumer driver to re-arm.

The exported amd_iommu_enable_perfopt()/amd_iommu_disable_perfopt() run
only from a consumer driver's bind/unbind path.  group->mutex is not
exposed to drivers, but a device bound to its native driver cannot have
its IOMMU domain changed concurrently by the core, which serializes the
detach/attach pair against core-driven attach.

PerfOpt is opt-in -- only enabled when explicitly requested by a driver.

Co-developed-by: Jatin Kataria <jkataria@netflix.com>
Signed-off-by: Jatin Kataria <jkataria@netflix.com>
Link: https://patch.msgid.link/20260831055108.1893285-2-mario.limonciello@amd.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
… in identity domain

Enable PerfOpt via amd_iommu_enable_perfopt() when the GPU's
iommu_perfopt module parameter is enabled (default 1) and the GPU
resides in the identity domain. The identity domain means the GPU is
already performing direct DMA with the IOMMU only enforcing IR/IW
permission bits -- no GPA->SPA translations.

amd_iommu_enable_perfopt() clears ATS, PRI, PASID and SVA for the
device. This is safe in identity domain because DTE[I]=0 means the
IOMMU already returns target abort for ATS requests from this
peripheral and the GPU manages its own TLB.

PerfOpt is a soft, optional latency optimization: failing to arm it (for
example on an IOMMU that does not implement the feature, which returns
-ENODEV) must not be fatal, so probe and resume warn and continue rather
than aborting.

PERF_OPT_EN is a per-IOMMU control shared by all devices behind that
IOMMU; the IOMMU driver reference counts it so that on systems where
multiple devices share one IOMMU, one GPU's teardown does not clear the
bit while a peer still requires it.

Arming PerfOpt trades IOMMU DMA containment for lower DMA latency. This
is enabled by default for GPUs in the identity domain as a deliberate,
documented policy and can be disabled with iommu_perfopt=0.

The AMD IOMMU spec indicates this is only supported on integrated GPUs
so check explicitly for AMD_IS_APU (which is set by
amdgpu_device_ip_early_init()).

PerfOpt is disabled during GPU init teardown and restored on resume.

Link: https://patch.msgid.link/20260831055108.1893285-3-mario.limonciello@amd.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
@superm1
superm1 force-pushed the superm1/ogc-unstable-iommu-perfopt branch from af3d165 to 78a6313 Compare August 31, 2026 18:54
@NeroReflex

Copy link
Copy Markdown
Collaborator

We have come up with a rule that in order to leave time for people to review we wait one week. Dunno if it's useful in this case, but unless there is a need I will leave this one sitting

@pastaq

pastaq commented Aug 31, 2026

Copy link
Copy Markdown
Member

We have come up with a rule that in order to leave time for people to review we wait one week. Dunno if it's useful in this case, but unless there is a need I will leave this one sitting

I think we can bypass it. I've already tested the patch and it's already on the ML.
Given that every PR since we came up with the rule needs an exception, lets discuss again separately what the rule should be.

@NeroReflex
NeroReflex merged commit 2a559b2 into OpenGamingCollective:master Aug 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants