]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf jevents: Add IOMMU metrics for Intel
authorChun-Tse Shao <ctshao@google.com>
Thu, 28 May 2026 23:44:55 +0000 (16:44 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Sat, 30 May 2026 00:12:53 +0000 (21:12 -0300)
Add IOMMU Translation Lookaside Buffer (TLB) and interrupt cache metrics
to perf jevents for Intel platforms. This enhances I/O performance
observability, allowing fleet-wide monitoring of IOMMU overhead.

These metrics are supported on platforms that expose the required uncore
IIO IOMMU events (such as Emerald Rapids and Granite Rapids).

The Intel implementation dynamically detects event availability at
generation time.

It requires at least the TLB events to expose the metric group, while
the interrupt cache events are optional. This allows platforms like
Emerald Rapids, which lack IOMMU interrupt cache events, to still expose
the IOMMU TLB metrics.

The following metrics are added:

- iotlb_total_hit: Total IOTLB hits (4K, 2M, 1G pages).
- iotlb_total_miss: Total IOTLB misses.
- iotlb_miss_rate: IOTLB miss rate.
- iotlb_interrupt_cache_hit: Interrupt cache hits.
- iotlb_interrupt_cache_miss: Interrupt cache misses (calculated as
  lookup - hit, clamped to zero).
- iotlb_interrupt_cache_lookup: Interrupt cache lookups.
- iotlb_interrupt_cache_miss_rate: Interrupt cache miss rate.

Tested:
  # perf stat -M \
    iotlb_total_hit,iotlb_total_miss,iotlb_miss_rate \
    --per-socket --metric-only -a -j -- sleep 10
  {"socket" : "S0", "counters" : 10,
   "hits  iotlb_total_hit" : "3579249.0",
   "%  iotlb_miss_rate" : "0.0",
   "misses  iotlb_total_miss" : "3.0"}
  {"socket" : "S1", "counters" : 10,
   "hits  iotlb_total_hit" : "0.0",
   "%  iotlb_miss_rate" : "0.0",
   "misses  iotlb_total_miss" : "0.0"}

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Chun-Tse Shao <ctshao@google.com>
Assisted-by: Gemini:gemini-3.1-pro-preview
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Dapeng Mi <dapeng1.mi@intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sandipan Das <sandipan.das@amd.com>
Link: https://lore.kernel.org/r/20260528234455.434027-3-ctshao@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/pmu-events/intel_metrics.py

index 52035433b50546a49964163104592129153c068d..c3a5c2965f743f51f517d225dcff4e1409387bce 100755 (executable)
@@ -457,6 +457,67 @@ def IntelIlp() -> MetricGroup:
     ])
 
 
+def IntelIotlb() -> Optional[MetricGroup]:
+  try:
+    total_hit = (
+        Event("UNC_IIO_IOMMU0.4K_HITS")
+        + Event("UNC_IIO_IOMMU0.2M_HITS")
+        + Event("UNC_IIO_IOMMU0.1G_HITS")
+    )
+    total_miss = Event("UNC_IIO_IOMMU0.MISSES")
+  except:
+    return None
+
+  miss_rate = d_ratio(total_miss, total_miss + total_hit)
+  metrics = [
+      Metric("iotlb_total_hit", "IOTLB total hit", total_hit, "hits"),
+      Metric("iotlb_total_miss", "IOTLB total miss", total_miss, "misses"),
+      Metric("iotlb_miss_rate", "IOTLB miss rate", miss_rate, "100%"),
+  ]
+
+  try:
+    interrupt_cache_hit = Event("UNC_IIO_IOMMU3.INT_CACHE_HITS")
+    interrupt_cache_lookup = Event("UNC_IIO_IOMMU3.INT_CACHE_LOOKUPS")
+    interrupt_cache_miss = max(interrupt_cache_lookup - interrupt_cache_hit, 0)
+    interrupt_cache_miss_rate = d_ratio(
+        interrupt_cache_miss, interrupt_cache_miss + interrupt_cache_hit
+    )
+    metrics += [
+        Metric(
+            "iotlb_interrupt_cache_hit",
+            "IOTLB interrupt cache hit",
+            interrupt_cache_hit,
+            "hits",
+        ),
+        Metric(
+            "iotlb_interrupt_cache_miss",
+            "IOTLB interrupt cache miss",
+            interrupt_cache_miss,
+            "misses",
+        ),
+        Metric(
+            "iotlb_interrupt_cache_lookup",
+            "IOTLB interrupt cache lookup",
+            interrupt_cache_lookup,
+            "lookups",
+        ),
+        Metric(
+            "iotlb_interrupt_cache_miss_rate",
+            "IOTLB interrupt cache miss rate",
+            interrupt_cache_miss_rate,
+            "100%",
+        ),
+    ]
+  except:
+    pass
+
+  return MetricGroup(
+      "iotlb",
+      metrics,
+      description="IOMMU TLB metrics",
+  )
+
+
 def IntelL2() -> Optional[MetricGroup]:
     try:
         DC_HIT = Event("L2_RQSTS.DEMAND_DATA_RD_HIT")
@@ -1105,6 +1166,7 @@ def main() -> None:
         IntelCtxSw(),
         IntelFpu(),
         IntelIlp(),
+        IntelIotlb(),
         IntelL2(),
         IntelLdSt(),
         IntelMissLat(),