From 1b4963e3820a568ac321122095c2fdf610d248ec Mon Sep 17 00:00:00 2001 From: Michael Cheng Date: Wed, 6 May 2026 16:59:54 -0700 Subject: [PATCH] intel/ds: Allow CREATE_DUAL_EVENT_CALLBACK to take optional name args Refactor CREATE_DUAL_EVENT_CALLBACK to accept optional variadic arguments for dynamic event-name formatting in follow-up patches. Add a small helper that formats event names only when a non-NULL format string is provided, and keep existing call sites unchanged so behavior is identical in this commit. Signed-off-by: Michael Cheng --- src/intel/ds/intel_driver_ds.cc | 38 +++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/intel/ds/intel_driver_ds.cc b/src/intel/ds/intel_driver_ds.cc index 75438d4d2f4..9bfa637baf0 100644 --- a/src/intel/ds/intel_driver_ds.cc +++ b/src/intel/ds/intel_driver_ds.cc @@ -23,6 +23,7 @@ #include #include +#include #include "common/intel_gem.h" #include "perf/intel_perf.h" @@ -264,6 +265,13 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns, struct intel_ds_stage *stage = &queue->stages[stage_id]; uint64_t start_ns = stage->start_ns[level]; + /* Deep copy app_event before the [=] lambda capture. The raw pointer + * points to a stack-local char buffer in the caller, which is invalid + * by the time the Trace() continuation executes. + */ + bool has_app_event = app_event != NULL; + std::string app_event_copy = has_app_event ? std::string(app_event) : std::string(); + if (!start_ns) return; @@ -278,8 +286,8 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns, * stage_iid if not already seen. Otherwise, it's a driver event and we * have use the internal stage_iid. */ - uint64_t stage_iid = app_event ? - tctx.GetDataSourceLocked()->debug_marker_stage(tctx, app_event) : + uint64_t stage_iid = has_app_event ? + tctx.GetDataSourceLocked()->debug_marker_stage(tctx, app_event_copy.c_str()) : device->tracepoint_iids[tracepoint_idx]; auto packet = tctx.NewTracePacket(); @@ -432,7 +440,24 @@ extern "C" { * collected. */ -#define CREATE_DUAL_EVENT_CALLBACK(event_name, stage) \ +static const char * +intel_ds_format_event_name(char *buf, size_t buf_size, const char *fmt, ...) +{ + if (fmt == NULL) + return NULL; + + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, buf_size, fmt, ap); + va_end(ap); + + return buf; +} + +#define CREATE_DUAL_EVENT_CALLBACK(event_name, stage, ...) \ + CREATE_DUAL_EVENT_CALLBACK_IMPL(event_name, stage, ##__VA_ARGS__, NULL) + +#define CREATE_DUAL_EVENT_CALLBACK_IMPL(event_name, stage, name_fmt, ...) \ void \ intel_ds_begin_##event_name(struct intel_ds_device *device, \ uint64_t ts_ns, \ @@ -456,8 +481,13 @@ extern "C" { { \ const struct intel_ds_flush_data *flush = \ (const struct intel_ds_flush_data *) flush_data; \ + char event_name[64]; \ + UNUSED const uint32_t *indirect = \ + (const uint32_t *) indirect_data; \ + const char *name = intel_ds_format_event_name( \ + event_name, sizeof(event_name), (name_fmt), ##__VA_ARGS__); \ end_event(flush->queue, ts_ns, stage, flush->submission_id, \ - tp_idx, NULL, payload, indirect_data, \ + tp_idx, name, payload, indirect_data, \ (trace_payload_as_extra_func) \ &trace_payload_as_extra_intel_end_##event_name); \ } \