diff options
| author | Jason Gunthorpe <jgg@nvidia.com> | 2026-10-02 22:23:23 -0300 |
|---|---|---|
| committer | Will Deacon <will@kernel.org> | 2026-10-04 15:57:40 +0000 |
| commit | 5a158b29766cc91c91e1d9df6aafda19e1924f7b (patch) | |
| tree | bdec08d53cdc8ea9933a5a858f4c420478455e8b /scripts/basic/split-include.c | |
| parent | a9573c2847e9a1c3c54df4ed0e14569d1d5ecbfc (diff) | |
| download | linux-5a158b29766cc91c91e1d9df6aafda19e1924f7b.tar.gz linux-5a158b29766cc91c91e1d9df6aafda19e1924f7b.zip | |
iommu/arm-smmu-v3: Optimize range invalidation for latency
The server IOMMU drivers focus on invalidation latency by default,
over-invalidating if necessary, to round the invalidation range up to a
single command. I think this represents a trade off for DMA non-FQ and SVA
where stalling the operation is overall worse than re-loading the IOTLB.
For instance AMD and VT-d both round the range up to the largest aligned
power of two and invalidate that. This causes over-invalidation but that
is preferred on real HW over trying to issue a number of smaller range
invalidations.
SMMUv3 on the other hand will try to do up to 512 single invalidations,
otherwise falls back to full invalidation, or it will try to issue an
string of range invalidations for every 5 bits of IOVA range to perfectly
cover it.
While the range-invalidation optimization is pretty good we can still do
better and reduce it to only 2 invalidations at maximum using the idea
Robin came up with to overlap two range invalidations in the middle. This
preserves the exact coverage of the current range invalidation and still
caps the number of range invalidations at 2.
This works because the range invalidation can start at any IOVA, so we can
place a range invalidation forwards from the start and backwards from the
end, overlapping in the middle if the scale isn't precise enough.
In the cases where this produces 2 range invalidations it continues to
produce range invalidations that don't overlap, but the exact split point
is different than the original algorithm due to the new calculation
method. In cases where the original algorithm would produce 3 or more
range invalidations this will produce 2 range invalidations with an
overlap.
The SVA under invalidation errata work around is maintained by "rounding
up" to generate a single range invalidation that over-covers the entire
range.
Since the normal path is now the only one with a loop, split them into two
functions and fold a simplified version of arm_smmu_inv_size_too_big()
directly into the normal flow in a way that directly limits the number of
single invalidation commands generated, again focusing on controlling
latency.
The end result is any gather is converted into either:
- One invalidate all
- One or two range invalidation operations
- At most 512 single invalidation ops
The current code switches at 511, but this turns every table removal
into a full invalidation. Change to 512 to try to minimize the amount
of full invalidation when using a 4k translation granule.
arm_smmu_domain_inv() is modified to always pass in the tgsz because the
new logic relies on it being valid.
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Pranjal Shrivastava <praan@google.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'scripts/basic/split-include.c')
0 files changed, 0 insertions, 0 deletions
