[Intel-gfx] uABI / Removing DRM_I915_LOW_LEVEL_TRACEPOINTS Kconfig
Steven Rostedt
rostedt at goodmis.org
Wed Dec 19 19:22:57 UTC 2018
On Wed, 19 Dec 2018 12:08:18 +0200
Joonas Lahtinen <joonas.lahtinen at linux.intel.com> wrote:
> To me, it seems almost as if folks are too preoccupied with thinking if
> we somehow can do this through tracepoints, to stop and actually think
> if we should.
Regardless of whether it should or shouldn't, one solution to this is
to make the trace event in question record basically nothing but a
pointer.
DECLARE_EVENT_CLASS(i915_hw_request,
TP_PROTO(struct i915_request *rq),
TP_ARGS(rq),
TP_STRUCT__entry(
__field(void *, rq)
),
TP_fast_assign(
__entry->rq = rq;
),
TP_printk("rq=%p", __entry->rq)
);
Define the events from that:
DEFINE_EVENT(i915_hw_request, i915_request_submit,
TP_PROTO(struct i915_request *rq),
TP_ARGS(rq)
);
No tool can use that information. But for those that want to, you make a
separate module that you can load that has:
DECLARE_EVENT_CLASS(i915_specific_hw_request,
TP_PROTO(struct i915_request *rq),
TP_ARGS(rq),
TP_STRUCT__entry(
__field(u32, dev)
__field(u32, hw_id)
__field(u64, ctx)
__field(u16, class)
__field(u16, instance)
__field(u32, seqno)
__field(u32, global)
),
TP_fast_assign(
__entry->dev = rq->i915->drm.primary->index;
__entry->hw_id = rq->gem_context->hw_id;
__entry->class = rq->engine->uabi_class;
__entry->instance = rq->engine->instance;
__entry->ctx = rq->fence.context;
__entry->seqno = rq->fence.seqno;
__entry->global = rq->global_seqno;
),
TP_printk("dev=%u, engine=%u:%u, hw_id=%u, ctx=%llu, seqno=%u, global=%u",
__entry->dev, __entry->class, __entry->instance,
__entry->hw_id, __entry->ctx, __entry->seqno,
__entry->global)
);
DEFINE_EVENT_FN(i915_specific_hw_request, i915_specific_request_submit,
TP_PROTO(struct i915_request *rq),
TP_ARGS(rq),
start_i915_request, stop_i915_request)
);
In the module:
static void do_i915_hw_request(void *data, struct i915_request *rq)
{
trace_i915_specific_request_submit(rq);
}
static bool i915_trace_enabled;
static void enable_disable_tracepoints(struct work_struct *work)
{
if (i915_trace_enabled)
/* Can not enable tracepoints from a tracepoint callback */
register_trace_i915_hw_request(do_i915_hw_request, NULL);
else
unregister_trace_i915_hw_request(do_i915_hw_request, NULL);
}
int start_i915_request(void)
{
i915_trace_enabled = true;
schedule_work(work_call_enable_disable_tracepoints);
}
int stop_i915_request(void)
{
i915_trace_enabled = false;
schedule_work(work_call_enable_disable_tracepoints);
}
Note, the above can be racy, but I'm just trying to show a possible
solution. Which is to have the tracepoint there but exposing no useful
data (event the pointer shown will be mangled by the KASLR security).
But if someone wants a tool, they can create a new tracepoint that is
called by a handler of this tracepoint (yes its a double tracepoint).
The above work, handle would enable/disable the upstream tracepoint
when the other is enabled. Or that may not even be needed, just have
the tool enable both tracepoints when it wants the second one.
-- Steve
More information about the Intel-gfx
mailing list