Re: [PATCH] perf jevents: Add dynamic IIO PCIe bandwidth metrics for Intel

From: Chun-Tse Shao

Date: Thu Jul 09 2026 - 17:34:16 EST


+ Perry for reviewing the metric.


On Thu, Jul 9, 2026 at 11:39 AM Chun-Tse Shao <ctshao@xxxxxxxxxx> wrote:
>
> Generate per-IIO-device PCIe read and write bandwidth metrics
> (iio_bandwidth_read_per_device_0, etc.) grouped under
> iio_bandwidth_per_device for Sapphire Rapids and newer architectures
> in intel_metrics.py.
>
> By using has_event() checks across up to 24 possible IIO stack indices,
> runtime perf automatically monitors only the IIO root complexes present
> on the system without failing on missing instances.
>
> Signed-off-by: Chun-Tse Shao <ctshao@xxxxxxxxxx>
> Assisted-by: Gemini:gemini-3.1-pro-preview
> ---
> tools/perf/pmu-events/intel_metrics.py | 52 ++++++++++++++++++++++++++
> 1 file changed, 52 insertions(+)
>
> diff --git a/tools/perf/pmu-events/intel_metrics.py b/tools/perf/pmu-events/intel_metrics.py
> index bc2b920d3a0d..4f8a123a375d 100755
> --- a/tools/perf/pmu-events/intel_metrics.py
> +++ b/tools/perf/pmu-events/intel_metrics.py
> @@ -1132,6 +1132,57 @@ def UncoreUpiBw() -> Optional[MetricGroup]:
> ], description="UPI Bandwidth")
>
>
> +def UncoreIioBw() -> Optional[MetricGroup]:
> + if _args.model not in [
> + "sapphirerapids",
> + "emeraldrapids",
> + "graniterapids",
> + "sierraforest",
> + "clearwaterforest",
> + ]:
> + return None
> +
> + # On multi-socket x86 servers, there can be multiple IIO stacks per socket.
> + # We generate metrics up to index 23 with has_event check so runtime perf
> + # only measures the IIO instances present on the system.
> + max_iios = 24
> + metrics = []
> + scale = 4 / 1_000_000
> + for i in range(max_iios):
> + rd_event = Event(
> + f"uncore_iio_{i}/UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.ALL_PARTS/"
> + )
> + wr_event = Event(
> + f"uncore_iio_{i}/UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.ALL_PARTS/"
> + )
> + rd_bw = Select(d_ratio(rd_event, interval_sec), has_event(rd_event), 0)
> + wr_bw = Select(d_ratio(wr_event, interval_sec), has_event(wr_event), 0)
> + metrics.append(
> + MetricGroup(
> + f"iio_bandwidth_per_device_iio{i}",
> + [
> + Metric(
> + f"iio_bandwidth_read_per_device_{i}",
> + f"IIO {i} read bandwidth",
> + rd_bw,
> + f"{scale}MB/s",
> + ),
> + Metric(
> + f"iio_bandwidth_write_per_device_{i}",
> + f"IIO {i} write bandwidth",
> + wr_bw,
> + f"{scale}MB/s",
> + ),
> + ],
> + )
> + )
> + return MetricGroup(
> + "iio_bandwidth_per_device",
> + metrics,
> + description="IIO Read/Write Bandwidth per root complex",
> + )
> +
> +
> def main() -> None:
> global _args
>
> @@ -1179,6 +1230,7 @@ def main() -> None:
> UncoreMemBw(),
> UncoreMemSat(),
> UncoreUpiBw(),
> + UncoreIioBw(),
> ])
>
> if _args.metricgroups:
> --
> 2.55.0.795.g602f6c329a-goog
>