Re: [PATCH v2 1/1] iommu/vt-d: Remove caching mode check before device TLB flush

From: Yi Liu
Date: Wed Apr 10 2024 - 02:27:05 EST


On 2024/4/10 13:58, Lu Baolu wrote:
The Caching Mode (CM) of the Intel IOMMU indicates if the hardware
implementation caches not-present or erroneous translation-structure
entries except the first-stage translation. The caching mode is
irrelevant to the device TLB , therefore there is no need to check
it before a device TLB invalidation operation.

iommu_flush_iotlb_psi() is called in map and unmap paths. The caching
mode check before device TLB invalidation will cause device TLB
invalidation always issued if IOMMU is not running in caching mode.
This is wrong and causes unnecessary performance overhead.

I don't think the original code is wrong. As I replied before, if CM==0,
the iommu_flush_iotlb_psi() is only called in unmap path, in which the
@map is false. [1] The reason to make the change is to make the logic
simpler. :)

[1] https://lore.kernel.org/linux-iommu/ac7fdf0f-ecb9-415f-9c1b-600536b92ca5@xxxxxxxxx/

The removal of caching mode check in intel_flush_iotlb_all() doesn't
impact anything no matter the IOMMU is working in caching mode or not.
Commit <29b32839725f> ("iommu/vt-d: Do not use flush-queue when
caching-mode is on") has already disabled flush-queue for caching mode,
hence caching mode will never call intel_flush_iotlb_all().

Fixes: bf92df30df90 ("intel-iommu: Only avoid flushing device IOTLB for domain ID 0 in caching mode")
Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
---
drivers/iommu/intel/iommu.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

Change log:

v2:
- Squash two patches into a single one.
- No functionality changes.

v1: https://lore.kernel.org/linux-iommu/20240407144232.190355-1-baolu.lu@xxxxxxxxxxxxxxx/

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 50eb9aed47cc..681789b1258d 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1501,11 +1501,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
else
__iommu_flush_iotlb_psi(iommu, did, pfn, pages, ih);
- /*
- * In caching mode, changes of pages from non-present to present require
- * flush. However, device IOTLB doesn't need to be flushed in this case.
- */
- if (!cap_caching_mode(iommu->cap) || !map)
+ if (!map)
iommu_flush_dev_iotlb(domain, addr, mask);
}
@@ -1579,8 +1575,7 @@ static void intel_flush_iotlb_all(struct iommu_domain *domain)
iommu->flush.flush_iotlb(iommu, did, 0, 0,
DMA_TLB_DSI_FLUSH);
- if (!cap_caching_mode(iommu->cap))
- iommu_flush_dev_iotlb(dmar_domain, 0, MAX_AGAW_PFN_WIDTH);
+ iommu_flush_dev_iotlb(dmar_domain, 0, MAX_AGAW_PFN_WIDTH);

why not one more step to move it out of the iommu_array loop? There is
no more reason to keep it in the loop.

}
if (dmar_domain->nested_parent)

--
Regards,
Yi Liu