mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 22:30:12 +01:00
common/utrace: Refactor and combine all envvars into GPU_TRACES
All environment variables involved in utrace usage were very fragmented and convoluted to decode the meaning of, this commit has simplified them down into easier to understand flags which directly indicate the resulting behavior (such as `perfetto` enabling queued logs rather than needing to set a `queued` flag) while combining them into a single envvar `GPU_TRACES` and updating existing terminology in utrace to match up with the new options. Signed-off-by: Mark Collins <mark@igalia.com> Reviewed-by: Danylo Piliaiev <dpiliaiev@igalia.com> Reviewed-by: Yonggang Luo <luoyonggang@gmail.com> Ack-by: Chia-I Wu <olvaffe@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18271>
This commit is contained in:
parent
044d3e53d2
commit
18e820009d
9 changed files with 133 additions and 75 deletions
|
|
@ -21,27 +21,26 @@ Usage
|
||||||
|
|
||||||
u_trace is controlled by environment variables:
|
u_trace is controlled by environment variables:
|
||||||
|
|
||||||
:envvar:`GPU_TRACE`
|
:envvar:`GPU_TRACES`
|
||||||
if set to ``1`` enables tracing and outputs the data into ``stdout``
|
controls whether u_trace is enabled and trace output
|
||||||
|
|
||||||
|
``print``
|
||||||
|
prints in a human readable text format. It should be noted that this
|
||||||
|
is mutually exclusive with ``print_json`` and both cannot be enabled
|
||||||
|
at the same time.
|
||||||
|
``print_json``
|
||||||
|
prints in JSON format, suitable for parsing. Application should
|
||||||
|
appropriately finish its rendering in order for trace's json to be
|
||||||
|
valid. For the Vulkan API, it is expected to destroy the device,
|
||||||
|
for GL it's expected to destroy the context.
|
||||||
|
``perfetto``
|
||||||
|
enables perfetto instrumentation prior to connecting, perfetto
|
||||||
|
traces can be collected without setting this but it may miss some
|
||||||
|
events prior to the tracing session being started.
|
||||||
|
|
||||||
:envvar:`GPU_TRACEFILE`
|
:envvar:`GPU_TRACEFILE`
|
||||||
specifies a file where to write the output instead of ``stdout``
|
specifies a file where to write the output instead of ``stdout``
|
||||||
|
|
||||||
:envvar:`GPU_TRACE_FORMAT`
|
|
||||||
controls a format of the output
|
|
||||||
|
|
||||||
``txt``
|
|
||||||
human readable text format
|
|
||||||
``json``
|
|
||||||
json format, suitable for parsing. Application should appropriately
|
|
||||||
finish its rendering in order for trace's json to be valid.
|
|
||||||
For Vulkan API it is expected to destroy the device, for GL it is
|
|
||||||
expected to destroy the context.
|
|
||||||
|
|
||||||
:envvar:`GPU_TRACE_INSTRUMENT`
|
|
||||||
Meaningful only for Perfetto tracing. If set to ``1`` enables
|
|
||||||
instrumentation of GPU commands before the tracing is enabled.
|
|
||||||
|
|
||||||
:envvar:`*_GPU_TRACEPOINT`
|
:envvar:`*_GPU_TRACEPOINT`
|
||||||
tracepoints can be enabled or disabled using driver specific environment
|
tracepoints can be enabled or disabled using driver specific environment
|
||||||
variable. Most tracepoints are enabled by default. For instance
|
variable. Most tracepoints are enabled by default. For instance
|
||||||
|
|
|
||||||
|
|
@ -1670,6 +1670,12 @@ tu_device_ticks_to_ns(struct tu_device *dev, uint64_t ts)
|
||||||
return ts * (1000000000 / 19200000);
|
return ts * (1000000000 / 19200000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct u_trace_context *
|
||||||
|
tu_device_get_u_trace(struct tu_device *device)
|
||||||
|
{
|
||||||
|
return &device->trace_context;
|
||||||
|
}
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
tu_trace_create_ts_buffer(struct u_trace_context *utctx, uint32_t size)
|
tu_trace_create_ts_buffer(struct u_trace_context *utctx, uint32_t size)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -445,6 +445,9 @@ tu_device_lookup_bo(struct tu_device *device, uint32_t handle)
|
||||||
return (struct tu_bo *) util_sparse_array_get(&device->bo_map, handle);
|
return (struct tu_bo *) util_sparse_array_get(&device->bo_map, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct u_trace_context *
|
||||||
|
tu_device_get_u_trace(struct tu_device *device);
|
||||||
|
|
||||||
/* Get a scratch bo for use inside a command buffer. This will always return
|
/* Get a scratch bo for use inside a command buffer. This will always return
|
||||||
* the same bo given the same size or similar sizes, so only one scratch bo
|
* the same bo given the same size or similar sizes, so only one scratch bo
|
||||||
* can be used at the same time. It's meant for short-lived things where we
|
* can be used at the same time. It's meant for short-lived things where we
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ tu_device_get_suspend_count(struct tu_device *dev,
|
||||||
uint64_t
|
uint64_t
|
||||||
tu_device_ticks_to_ns(struct tu_device *dev, uint64_t ts);
|
tu_device_ticks_to_ns(struct tu_device *dev, uint64_t ts);
|
||||||
|
|
||||||
|
struct u_trace_context *
|
||||||
|
tu_device_get_u_trace(struct tu_device *device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -410,7 +412,7 @@ void
|
||||||
tu_perfetto_submit(struct tu_device *dev, uint32_t submission_id)
|
tu_perfetto_submit(struct tu_device *dev, uint32_t submission_id)
|
||||||
{
|
{
|
||||||
/* sync_timestamp isn't free */
|
/* sync_timestamp isn't free */
|
||||||
if (!ut_perfetto_enabled)
|
if (!u_trace_perfetto_active(tu_device_get_u_trace(dev)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sync_timestamp(dev);
|
sync_timestamp(dev);
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ u_trace_pipe_context_init(struct u_trace_context *utctx,
|
||||||
inline void
|
inline void
|
||||||
trace_framebuffer_state(struct u_trace *ut, void *cs, const struct pipe_framebuffer_state *pfb)
|
trace_framebuffer_state(struct u_trace *ut, void *cs, const struct pipe_framebuffer_state *pfb)
|
||||||
{
|
{
|
||||||
if (likely(!u_trace_instrument()))
|
if (likely(!u_trace_enabled(ut->utctx)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
trace_framebuffer(ut, cs, pfb);
|
trace_framebuffer(ut, cs, pfb);
|
||||||
|
|
|
||||||
|
|
@ -38,20 +38,16 @@
|
||||||
#define TIMESTAMP_BUF_SIZE 0x1000
|
#define TIMESTAMP_BUF_SIZE 0x1000
|
||||||
#define TRACES_PER_CHUNK (TIMESTAMP_BUF_SIZE / sizeof(uint64_t))
|
#define TRACES_PER_CHUNK (TIMESTAMP_BUF_SIZE / sizeof(uint64_t))
|
||||||
|
|
||||||
int _u_trace_instrument;
|
|
||||||
|
|
||||||
struct u_trace_state {
|
struct u_trace_state {
|
||||||
util_once_flag once;
|
util_once_flag once;
|
||||||
FILE *trace_file;
|
FILE *trace_file;
|
||||||
bool trace_format_json;
|
enum u_trace_type enabled_traces;
|
||||||
};
|
};
|
||||||
static struct u_trace_state u_trace_state = {
|
static struct u_trace_state u_trace_state = {
|
||||||
.once = UTIL_ONCE_FLAG_INIT
|
.once = UTIL_ONCE_FLAG_INIT
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_PERFETTO
|
#ifdef HAVE_PERFETTO
|
||||||
int ut_perfetto_enabled;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global list of contexts, so we can defer starting the queue until
|
* Global list of contexts, so we can defer starting the queue until
|
||||||
* perfetto tracing is started.
|
* perfetto tracing is started.
|
||||||
|
|
@ -59,6 +55,8 @@ int ut_perfetto_enabled;
|
||||||
static struct list_head ctx_list = { &ctx_list, &ctx_list };
|
static struct list_head ctx_list = { &ctx_list, &ctx_list };
|
||||||
|
|
||||||
static simple_mtx_t ctx_list_mutex = SIMPLE_MTX_INITIALIZER;
|
static simple_mtx_t ctx_list_mutex = SIMPLE_MTX_INITIALIZER;
|
||||||
|
/* The amount of Perfetto tracers connected */
|
||||||
|
int _u_trace_perfetto_count;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct u_trace_payload_buf {
|
struct u_trace_payload_buf {
|
||||||
|
|
@ -361,10 +359,16 @@ get_chunk(struct u_trace *ut, size_t payload_size)
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_GET_ONCE_BOOL_OPTION(trace_instrument, "GPU_TRACE_INSTRUMENT", false)
|
static const struct debug_named_value config_control[] = {
|
||||||
DEBUG_GET_ONCE_BOOL_OPTION(trace, "GPU_TRACE", false)
|
{ "print", U_TRACE_TYPE_PRINT, "Enable print"},
|
||||||
|
{ "print_json", U_TRACE_TYPE_PRINT_JSON, "Enable print in JSON"},
|
||||||
|
#ifdef HAVE_PERFETTO
|
||||||
|
{ "perfetto", U_TRACE_TYPE_PERFETTO_ENV, "Enable perfetto" },
|
||||||
|
#endif
|
||||||
|
DEBUG_NAMED_VALUE_END
|
||||||
|
};
|
||||||
|
|
||||||
DEBUG_GET_ONCE_OPTION(trace_file, "GPU_TRACEFILE", NULL)
|
DEBUG_GET_ONCE_OPTION(trace_file, "GPU_TRACEFILE", NULL)
|
||||||
DEBUG_GET_ONCE_OPTION(trace_format, "GPU_TRACE_FORMAT", "txt")
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
trace_file_fini(void)
|
trace_file_fini(void)
|
||||||
|
|
@ -376,6 +380,8 @@ trace_file_fini(void)
|
||||||
static void
|
static void
|
||||||
u_trace_state_init_once(void)
|
u_trace_state_init_once(void)
|
||||||
{
|
{
|
||||||
|
u_trace_state.enabled_traces =
|
||||||
|
debug_get_flags_option("GPU_TRACES", config_control, 0);
|
||||||
const char *tracefile_name = debug_get_option_trace_file();
|
const char *tracefile_name = debug_get_option_trace_file();
|
||||||
if (tracefile_name && !__check_suid()) {
|
if (tracefile_name && !__check_suid()) {
|
||||||
u_trace_state.trace_file = fopen(tracefile_name, "w");
|
u_trace_state.trace_file = fopen(tracefile_name, "w");
|
||||||
|
|
@ -383,15 +389,9 @@ u_trace_state_init_once(void)
|
||||||
atexit(trace_file_fini);
|
atexit(trace_file_fini);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!u_trace_state.trace_file && debug_get_option_trace()) {
|
if (!u_trace_state.trace_file) {
|
||||||
u_trace_state.trace_file = stdout;
|
u_trace_state.trace_file = stdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u_trace_state.trace_file || debug_get_option_trace_instrument())
|
|
||||||
p_atomic_inc(&_u_trace_instrument);
|
|
||||||
|
|
||||||
const char *trace_format = debug_get_option_trace_format();
|
|
||||||
u_trace_state.trace_format_json = !strcmp(trace_format, "json");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -426,6 +426,7 @@ u_trace_context_init(struct u_trace_context *utctx,
|
||||||
{
|
{
|
||||||
u_trace_state_init();
|
u_trace_state_init();
|
||||||
|
|
||||||
|
utctx->enabled_traces = u_trace_state.enabled_traces;
|
||||||
utctx->pctx = pctx;
|
utctx->pctx = pctx;
|
||||||
utctx->create_timestamp_buffer = create_timestamp_buffer;
|
utctx->create_timestamp_buffer = create_timestamp_buffer;
|
||||||
utctx->delete_timestamp_buffer = delete_timestamp_buffer;
|
utctx->delete_timestamp_buffer = delete_timestamp_buffer;
|
||||||
|
|
@ -442,31 +443,35 @@ u_trace_context_init(struct u_trace_context *utctx,
|
||||||
|
|
||||||
list_inithead(&utctx->flushed_trace_chunks);
|
list_inithead(&utctx->flushed_trace_chunks);
|
||||||
|
|
||||||
|
if (utctx->enabled_traces & U_TRACE_TYPE_PRINT) {
|
||||||
utctx->out = u_trace_state.trace_file;
|
utctx->out = u_trace_state.trace_file;
|
||||||
|
|
||||||
if (u_trace_state.trace_format_json) {
|
if (utctx->enabled_traces & U_TRACE_TYPE_JSON) {
|
||||||
utctx->out_printer = &json_printer;
|
utctx->out_printer = &json_printer;
|
||||||
} else {
|
} else {
|
||||||
utctx->out_printer = &txt_printer;
|
utctx->out_printer = &txt_printer;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
utctx->out = NULL;
|
||||||
|
utctx->out_printer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PERFETTO
|
#ifdef HAVE_PERFETTO
|
||||||
simple_mtx_lock(&ctx_list_mutex);
|
simple_mtx_lock(&ctx_list_mutex);
|
||||||
list_add(&utctx->node, &ctx_list);
|
list_add(&utctx->node, &ctx_list);
|
||||||
simple_mtx_unlock(&ctx_list_mutex);
|
if (_u_trace_perfetto_count > 0)
|
||||||
#endif
|
utctx->enabled_traces |= U_TRACE_TYPE_PERFETTO_ACTIVE;
|
||||||
|
|
||||||
if (!u_trace_context_actively_tracing(utctx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef HAVE_PERFETTO
|
|
||||||
simple_mtx_lock(&ctx_list_mutex);
|
|
||||||
#endif
|
|
||||||
queue_init(utctx);
|
queue_init(utctx);
|
||||||
#ifdef HAVE_PERFETTO
|
|
||||||
simple_mtx_unlock(&ctx_list_mutex);
|
simple_mtx_unlock(&ctx_list_mutex);
|
||||||
|
#else
|
||||||
|
queue_init(utctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!(p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_REQUIRE_QUEUING))
|
||||||
|
return;
|
||||||
|
|
||||||
if (utctx->out) {
|
if (utctx->out) {
|
||||||
utctx->out_printer->start(utctx);
|
utctx->out_printer->start(utctx);
|
||||||
}
|
}
|
||||||
|
|
@ -498,20 +503,33 @@ void
|
||||||
u_trace_perfetto_start(void)
|
u_trace_perfetto_start(void)
|
||||||
{
|
{
|
||||||
simple_mtx_lock(&ctx_list_mutex);
|
simple_mtx_lock(&ctx_list_mutex);
|
||||||
list_for_each_entry (struct u_trace_context, utctx, &ctx_list, node)
|
|
||||||
queue_init(utctx);
|
|
||||||
simple_mtx_unlock(&ctx_list_mutex);
|
|
||||||
|
|
||||||
if (p_atomic_inc_return(&ut_perfetto_enabled) == 1)
|
list_for_each_entry(struct u_trace_context, utctx, &ctx_list, node) {
|
||||||
p_atomic_inc(&_u_trace_instrument);
|
queue_init(utctx);
|
||||||
|
p_atomic_set(&utctx->enabled_traces,
|
||||||
|
utctx->enabled_traces | U_TRACE_TYPE_PERFETTO_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
_u_trace_perfetto_count++;
|
||||||
|
|
||||||
|
simple_mtx_unlock(&ctx_list_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
u_trace_perfetto_stop(void)
|
u_trace_perfetto_stop(void)
|
||||||
{
|
{
|
||||||
assert(ut_perfetto_enabled > 0);
|
simple_mtx_lock(&ctx_list_mutex);
|
||||||
if (p_atomic_dec_return(&ut_perfetto_enabled) == 0)
|
|
||||||
p_atomic_dec(&_u_trace_instrument);
|
assert(_u_trace_perfetto_count > 0);
|
||||||
|
_u_trace_perfetto_count--;
|
||||||
|
if (_u_trace_perfetto_count == 0) {
|
||||||
|
list_for_each_entry(struct u_trace_context, utctx, &ctx_list, node) {
|
||||||
|
p_atomic_set(&utctx->enabled_traces,
|
||||||
|
utctx->enabled_traces & ~U_TRACE_TYPE_PERFETTO_ACTIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_mtx_unlock(&ctx_list_mutex);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -564,7 +582,8 @@ process_chunk(void *job, void *gdata, int thread_index)
|
||||||
utctx->out_printer->event(utctx, chunk, evt, ns, delta);
|
utctx->out_printer->event(utctx, chunk, evt, ns, delta);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_PERFETTO
|
#ifdef HAVE_PERFETTO
|
||||||
if (evt->tp->perfetto) {
|
if (evt->tp->perfetto &&
|
||||||
|
(p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_PERFETTO_ACTIVE)) {
|
||||||
evt->tp->perfetto(utctx->pctx, ns, chunk->flush_data, evt->payload);
|
evt->tp->perfetto(utctx->pctx, ns, chunk->flush_data, evt->payload);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -132,11 +132,33 @@ typedef uint64_t (*u_trace_read_ts)(struct u_trace_context *utctx,
|
||||||
typedef void (*u_trace_delete_flush_data)(struct u_trace_context *utctx,
|
typedef void (*u_trace_delete_flush_data)(struct u_trace_context *utctx,
|
||||||
void *flush_data);
|
void *flush_data);
|
||||||
|
|
||||||
|
enum u_trace_type {
|
||||||
|
U_TRACE_TYPE_PRINT = 1u << 0,
|
||||||
|
U_TRACE_TYPE_JSON = 1u << 1,
|
||||||
|
U_TRACE_TYPE_PERFETTO_ACTIVE = 1u << 2,
|
||||||
|
U_TRACE_TYPE_PERFETTO_ENV = 1u << 3,
|
||||||
|
|
||||||
|
U_TRACE_TYPE_PRINT_JSON = U_TRACE_TYPE_PRINT | U_TRACE_TYPE_JSON,
|
||||||
|
U_TRACE_TYPE_PERFETTO = U_TRACE_TYPE_PERFETTO_ACTIVE | U_TRACE_TYPE_PERFETTO_ENV,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A mask of traces that require appending to the tracepoint chunk list.
|
||||||
|
*/
|
||||||
|
U_TRACE_TYPE_REQUIRE_QUEUING = U_TRACE_TYPE_PRINT | U_TRACE_TYPE_PERFETTO,
|
||||||
|
/*
|
||||||
|
* A mask of traces that require processing the tracepoint chunk list.
|
||||||
|
*/
|
||||||
|
U_TRACE_TYPE_REQUIRE_PROCESSING = U_TRACE_TYPE_PRINT | U_TRACE_TYPE_PERFETTO_ACTIVE,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The trace context provides tracking for "in-flight" traces, once the
|
* The trace context provides tracking for "in-flight" traces, once the
|
||||||
* cmdstream that records timestamps has been flushed.
|
* cmdstream that records timestamps has been flushed.
|
||||||
*/
|
*/
|
||||||
struct u_trace_context {
|
struct u_trace_context {
|
||||||
|
/* All traces enabled in this context */
|
||||||
|
enum u_trace_type enabled_traces;
|
||||||
|
|
||||||
void *pctx;
|
void *pctx;
|
||||||
|
|
||||||
u_trace_create_ts_buffer create_timestamp_buffer;
|
u_trace_create_ts_buffer create_timestamp_buffer;
|
||||||
|
|
@ -273,29 +295,32 @@ void u_trace_disable_event_range(struct u_trace_iterator begin_it,
|
||||||
void u_trace_flush(struct u_trace *ut, void *flush_data, bool free_data);
|
void u_trace_flush(struct u_trace *ut, void *flush_data, bool free_data);
|
||||||
|
|
||||||
#ifdef HAVE_PERFETTO
|
#ifdef HAVE_PERFETTO
|
||||||
extern int ut_perfetto_enabled;
|
static ALWAYS_INLINE bool
|
||||||
|
u_trace_perfetto_active(struct u_trace_context* utctx) {
|
||||||
|
return p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_PERFETTO_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
void u_trace_perfetto_start(void);
|
void u_trace_perfetto_start(void);
|
||||||
void u_trace_perfetto_stop(void);
|
void u_trace_perfetto_stop(void);
|
||||||
#else
|
#else
|
||||||
# define ut_perfetto_enabled 0
|
static ALWAYS_INLINE bool
|
||||||
|
u_trace_perfetto_active(UNUSED struct u_trace_context* utctx) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether instrumentations should be enabled or not. This is called
|
* Return whether utrace is enabled at all or not, this can be used to
|
||||||
* from tracepoints.
|
* gate any expensive traces.
|
||||||
*/
|
*/
|
||||||
static ALWAYS_INLINE bool
|
static ALWAYS_INLINE bool
|
||||||
u_trace_instrument(void)
|
u_trace_enabled(struct u_trace_context *utctx) {
|
||||||
{
|
return p_atomic_read_relaxed(&utctx->enabled_traces) != 0;
|
||||||
extern int _u_trace_instrument;
|
|
||||||
return p_atomic_read_relaxed(&_u_trace_instrument);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static ALWAYS_INLINE bool
|
||||||
u_trace_context_actively_tracing(struct u_trace_context *utctx)
|
u_trace_context_actively_tracing(struct u_trace_context *utctx) {
|
||||||
{
|
return p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_REQUIRE_PROCESSING;
|
||||||
return !!utctx->out || (ut_perfetto_enabled > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@ void ${trace.tp_perfetto}(
|
||||||
% endif
|
% endif
|
||||||
void __trace_${trace_name}(
|
void __trace_${trace_name}(
|
||||||
struct u_trace *ut
|
struct u_trace *ut
|
||||||
|
, enum u_trace_type enabled_traces
|
||||||
% if need_cs_param:
|
% if need_cs_param:
|
||||||
, void *cs
|
, void *cs
|
||||||
% endif
|
% endif
|
||||||
|
|
@ -252,11 +253,13 @@ static ALWAYS_INLINE void trace_${trace_name}(
|
||||||
, ${arg.type} ${arg.var}
|
, ${arg.type} ${arg.var}
|
||||||
% endfor
|
% endfor
|
||||||
) {
|
) {
|
||||||
if (!unlikely(u_trace_instrument() &&
|
enum u_trace_type enabled_traces = p_atomic_read_relaxed(&ut->utctx->enabled_traces);
|
||||||
|
if (!unlikely(enabled_traces != 0 &&
|
||||||
${trace.enabled_expr(trace_toggle_name)}))
|
${trace.enabled_expr(trace_toggle_name)}))
|
||||||
return;
|
return;
|
||||||
__trace_${trace_name}(
|
__trace_${trace_name}(
|
||||||
ut
|
ut
|
||||||
|
, enabled_traces
|
||||||
% if need_cs_param:
|
% if need_cs_param:
|
||||||
, cs
|
, cs
|
||||||
% endif
|
% endif
|
||||||
|
|
@ -416,6 +419,7 @@ static const struct u_tracepoint __tp_${trace_name} = {
|
||||||
};
|
};
|
||||||
void __trace_${trace_name}(
|
void __trace_${trace_name}(
|
||||||
struct u_trace *ut
|
struct u_trace *ut
|
||||||
|
, enum u_trace_type enabled_traces
|
||||||
% if need_cs_param:
|
% if need_cs_param:
|
||||||
, void *cs
|
, void *cs
|
||||||
% endif
|
% endif
|
||||||
|
|
@ -423,11 +427,11 @@ void __trace_${trace_name}(
|
||||||
, ${arg.type} ${arg.var}
|
, ${arg.type} ${arg.var}
|
||||||
% endfor
|
% endfor
|
||||||
) {
|
) {
|
||||||
struct trace_${trace_name} *__entry =
|
struct trace_${trace_name} entry;
|
||||||
(struct trace_${trace_name} *)u_trace_append(ut, ${cs_param_value + ","} &__tp_${trace_name});
|
UNUSED struct trace_${trace_name} *__entry =
|
||||||
% if len(trace.tp_struct) == 0:
|
enabled_traces & U_TRACE_TYPE_REQUIRE_QUEUING ?
|
||||||
(void)__entry;
|
(struct trace_${trace_name} *)u_trace_append(ut, ${cs_param_value + ","} &__tp_${trace_name}) :
|
||||||
% endif
|
&entry;
|
||||||
% for arg in trace.tp_struct:
|
% for arg in trace.tp_struct:
|
||||||
__entry->${arg.name} = ${arg.var};
|
__entry->${arg.name} = ${arg.var};
|
||||||
% endfor
|
% endfor
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
static int
|
static int
|
||||||
test_thread(void *_state)
|
test_thread(void *_state)
|
||||||
{
|
{
|
||||||
struct u_trace_context ctx = { 0 };
|
struct u_trace_context ctx = {};
|
||||||
u_trace_context_init(&ctx, NULL, NULL, NULL, NULL, NULL, NULL);
|
u_trace_context_init(&ctx, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
u_trace_context_fini(&ctx);
|
u_trace_context_fini(&ctx);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue