perf jevents: Add tsx metric group for Intel models

Allow duplicated metric to be dropped from JSON files. Detect when TSX
is supported by a model by using the JSON events, use sysfs events at
runtime as hypervisors, etc. may disable TSX.

Add CheckPmu to metric to determine if which PMUs have been associated
with the loaded events.

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Thomas Falcon <thomas.falcon@intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Benjamin Gray <bgray@linux.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Edward Baker <edward.baker@intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Leo Yan <leo.yan@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>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Xu Yang <xu.yang_2@nxp.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2026-01-27 10:44:48 -08:00 committed by Arnaldo Carvalho de Melo
parent 7eb9fa417c
commit 8c345f3500

View File

@ -3,6 +3,7 @@
import argparse
import math
import os
from typing import Optional
from metric import (d_ratio, has_event, max, CheckPmu, Event, JsonEncodeMetric,
JsonEncodeMetricGroupDescriptions, LoadEvents, Metric,
MetricGroup, MetricRef, Select)
@ -75,6 +76,54 @@ def Smi() -> MetricGroup:
], description='System Management Interrupt metrics')
def Tsx() -> Optional[MetricGroup]:
pmu = "cpu_core" if CheckPmu("cpu_core") else "cpu"
cycles = Event('cycles')
cycles_in_tx = Event(f'{pmu}/cycles\\-t/')
cycles_in_tx_cp = Event(f'{pmu}/cycles\\-ct/')
try:
# Test if the tsx event is present in the json, prefer the
# sysfs version so that we can detect its presence at runtime.
transaction_start = Event("RTM_RETIRED.START")
transaction_start = Event(f'{pmu}/tx\\-start/')
except:
return None
elision_start = None
try:
# Elision start isn't supported by all models, but we'll not
# generate the tsx_cycles_per_elision metric in that
# case. Again, prefer the sysfs encoding of the event.
elision_start = Event("HLE_RETIRED.START")
elision_start = Event(f'{pmu}/el\\-start/')
except:
pass
return MetricGroup('transaction', [
Metric('tsx_transactional_cycles',
'Percentage of cycles within a transaction region.',
Select(cycles_in_tx / cycles, has_event(cycles_in_tx), 0),
'100%'),
Metric('tsx_aborted_cycles', 'Percentage of cycles in aborted transactions.',
Select(max(cycles_in_tx - cycles_in_tx_cp, 0) / cycles,
has_event(cycles_in_tx),
0),
'100%'),
Metric('tsx_cycles_per_transaction',
'Number of cycles within a transaction divided by the number of transactions.',
Select(cycles_in_tx / transaction_start,
has_event(cycles_in_tx),
0),
"cycles / transaction"),
Metric('tsx_cycles_per_elision',
'Number of cycles within a transaction divided by the number of elisions.',
Select(cycles_in_tx / elision_start,
has_event(elision_start),
0),
"cycles / elision") if elision_start else None,
], description="Breakdown of transactional memory statistics")
def main() -> None:
global _args
@ -103,6 +152,7 @@ def main() -> None:
Idle(),
Rapl(),
Smi(),
Tsx(),
])
if _args.metricgroups: