Thanks to Tamas Petz for noticing that Arm CoreSight perf data can contain many PERF_RECORD_ITRACE_START records.
PERF_RECORD_ITRACE_START provides the decoder with the initial thread context when that information is absent from the trace stream. Once tracing has started, Arm SPE and CoreSight decoders track subsequent context changes using context packets or recorded sched_switch events.
Have both drivers call perf_event_itrace_started() after successfully starting event. This prevents perf core from emitting redundant PERF_RECORD_ITRACE_START records when an event is scheduled in again.
Since the Arm SPE and CoreSight drivers can be built as modules, export perf_event_itrace_started() before using it in those drivers.
This series was verified with Arm CoreSight using the commands below. The perf data contains 100 sched_switch events but only one PERF_RECORD_ITRACE_START record:
taskset -c 2 perf record -e cs_etm//u -e sched:sched_switch -- \ taskset -c 2 bash -c 'while true; do sleep 0.01; done' ^C
perf script -D 2>&1 | grep -c sched_switch 100
perf script -D 2>&1 | grep -c PERF_RECORD_ITRACE_START 1
Signed-off-by: Leo Yan leo.yan@arm.com --- Leo Yan (3): perf/core: Export perf_event_itrace_started() perf: arm_spe: Suppress redundant ITRACE start records coresight: perf: Suppress ITRACE start records
drivers/hwtracing/coresight/coresight-etm-perf.c | 2 ++ drivers/perf/arm_spe_pmu.c | 2 ++ kernel/events/core.c | 1 + 3 files changed, 5 insertions(+) --- base-commit: 786262be6048deab760f68c8acc2c85607165894 change-id: 20260901-perf_suppress_itrace_start_records-42faf45e9ce9
Best regards,
Since Arm SPE and CoreSight drivers can be built as modules, export perf_event_itrace_started() so that it can be used by these modules.
Signed-off-by: Leo Yan leo.yan@arm.com --- kernel/events/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/kernel/events/core.c b/kernel/events/core.c index a6c8e38a311042afab6b65814a84c67b87ba929b..8afe89179a62127eebae0f38f29cde045ba56251 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -10560,6 +10560,7 @@ void perf_event_itrace_started(struct perf_event *event) { WRITE_ONCE(event->attach_state, event->attach_state | PERF_ATTACH_ITRACE); } +EXPORT_SYMBOL_GPL(perf_event_itrace_started);
static void perf_log_itrace_start(struct perf_event *event) {
PERF_RECORD_ITRACE_START establishes the initial thread context at the beginning of a trace. Afterwards, decoders track the thread context using context packets or recorded sched_switch events.
Call perf_event_itrace_started() when event starts to prevent perf core from emitting redundant PERF_RECORD_ITRACE_START records on later schedule-ins.
Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/perf/arm_spe_pmu.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index b70f3fedf0282baba1395ce1116272ec5f961ea8..40314ef8b731e1272e02783a9e6dc7d92ec47139 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -890,6 +890,8 @@ static void arm_spe_pmu_start(struct perf_event *event, int flags) return; }
+ perf_event_itrace_started(event); + reg = arm_spe_event_to_pmsfcr(event); write_sysreg_s(reg, SYS_PMSFCR_EL1);
PERF_RECORD_ITRACE_START establishes the initial thread context at the beginning of a trace. Afterwards, decoders track the thread context using context packets.
Call perf_event_itrace_started() after successfully starting the event to prevent perf core from emitting redundant PERF_RECORD_ITRACE_START records when the event is scheduled in again.
When per-thread mode traces multiple child threads, tooling should enable context ID tracing instead to identify each thread.
Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-etm-perf.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 09b21a711a8764ea429d712890265c84648e889e..80502e8b084074980000a039e73e1a164940011d 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -613,6 +613,8 @@ static void etm_event_start(struct perf_event *event, int flags) perf_report_aux_output_id(event, hw_id); }
+ perf_event_itrace_started(event); + out: /* Tell the perf core the event is alive */ event->hw.state = 0;