mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-23 18:24:13 +08:00
common/utrace: Add CS logging support
Viewing CS traces retrieved from the driver is common practice to determine driver bugs but there is no way to determine what function a certain part of the CS was emitted by. This is crucial information to determine what function is responsible for emitting broken CS packets and to help with navigation of the CS trace. 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
8370a0d6bf
commit
ac5a55ef11
@ -37,6 +37,9 @@ u_trace is controlled by environment variables:
|
||||
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.
|
||||
``markers``
|
||||
enables marker instrumentation, will print utrace markers into
|
||||
the CS which can then be viewed by dumping the CS from the driver.
|
||||
|
||||
:envvar:`MESA_GPU_TRACEFILE`
|
||||
specifies a file where to write the output instead of ``stdout``
|
||||
|
@ -365,6 +365,7 @@ static const struct debug_named_value config_control[] = {
|
||||
#ifdef HAVE_PERFETTO
|
||||
{ "perfetto", U_TRACE_TYPE_PERFETTO_ENV, "Enable perfetto" },
|
||||
#endif
|
||||
{ "markers", U_TRACE_TYPE_MARKERS, "Enable marker trace"},
|
||||
DEBUG_NAMED_VALUE_END
|
||||
};
|
||||
|
||||
|
@ -137,6 +137,7 @@ enum u_trace_type {
|
||||
U_TRACE_TYPE_JSON = 1u << 1,
|
||||
U_TRACE_TYPE_PERFETTO_ACTIVE = 1u << 2,
|
||||
U_TRACE_TYPE_PERFETTO_ENV = 1u << 3,
|
||||
U_TRACE_TYPE_MARKERS = 1u << 4,
|
||||
|
||||
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,
|
||||
@ -326,6 +327,15 @@ u_trace_should_process(struct u_trace_context *utctx) {
|
||||
return p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_REQUIRE_PROCESSING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to emit markers into the command stream even if the queue
|
||||
* isn't active.
|
||||
*/
|
||||
static ALWAYS_INLINE bool
|
||||
u_trace_markers_enabled(struct u_trace_context *utctx) {
|
||||
return p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_MARKERS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -34,7 +34,7 @@ class Tracepoint(object):
|
||||
"""
|
||||
def __init__(self, name, args=[], toggle_name=None,
|
||||
tp_struct=None, tp_print=None, tp_perfetto=None,
|
||||
end_of_pipe=False):
|
||||
tp_markers=None, end_of_pipe=False):
|
||||
"""Parameters:
|
||||
|
||||
- name: the tracepoint name, a tracepoint function with the given
|
||||
@ -45,6 +45,9 @@ class Tracepoint(object):
|
||||
- tp_print: (optional) array of format string followed by expressions
|
||||
- tp_perfetto: (optional) driver provided callback which can generate
|
||||
perfetto events
|
||||
- tp_markers: (optional) driver provided printf-style callback which can
|
||||
generate CS markers, this requires 'need_cs_param' as the first param
|
||||
is the CS that the label should be emitted into
|
||||
"""
|
||||
assert isinstance(name, str)
|
||||
assert isinstance(args, list)
|
||||
@ -57,6 +60,7 @@ class Tracepoint(object):
|
||||
self.tp_struct = tp_struct
|
||||
self.tp_print = tp_print
|
||||
self.tp_perfetto = tp_perfetto
|
||||
self.tp_markers = tp_markers
|
||||
self.end_of_pipe = end_of_pipe
|
||||
self.toggle_name = toggle_name
|
||||
|
||||
@ -405,6 +409,27 @@ static void __print_json_${trace_name}(FILE *out, const void *arg) {
|
||||
#define __print_${trace_name} NULL
|
||||
#define __print_json_${trace_name} NULL
|
||||
% endif
|
||||
% if trace.tp_markers is not None:
|
||||
|
||||
__attribute__((format(printf, 2, 3))) void ${trace.tp_markers}(void *, const char *, ...);
|
||||
|
||||
static void __emit_label_${trace_name}(void *cs, struct trace_${trace_name} *entry) {
|
||||
${trace.tp_markers}(cs, "${trace_name}("
|
||||
% for idx,arg in enumerate(trace.tp_struct):
|
||||
"${"," if idx != 0 else ""}${arg.name}=${arg.c_format}"
|
||||
% endfor
|
||||
")"
|
||||
% for arg in trace.tp_struct:
|
||||
% if arg.to_prim_type:
|
||||
,${arg.to_prim_type.format('entry->' + arg.name)}
|
||||
% else:
|
||||
,entry->${arg.name}
|
||||
% endif
|
||||
% endfor
|
||||
);
|
||||
}
|
||||
|
||||
% endif
|
||||
static const struct u_tracepoint __tp_${trace_name} = {
|
||||
ALIGN_POT(sizeof(struct trace_${trace_name}), 8), /* keep size 64b aligned */
|
||||
"${trace_name}",
|
||||
@ -435,6 +460,10 @@ void __trace_${trace_name}(
|
||||
% for arg in trace.tp_struct:
|
||||
__entry->${arg.name} = ${arg.var};
|
||||
% endfor
|
||||
% if trace.tp_markers is not None:
|
||||
if (enabled_traces & U_TRACE_TYPE_MARKERS)
|
||||
__emit_label_${trace_name}(cs, __entry);
|
||||
% endif
|
||||
}
|
||||
|
||||
% endfor
|
||||
|
Loading…
Reference in New Issue
Block a user