From: Emil Velikov <emil.velikov@xxxxxxxxxxxxx> v4l2_m2m_stream_on/off are essentially the start/end points in between which jobs can be scheduled. Userspace can easily request a stream_off, while the last job is being processed - we might want to indicate that in the traces. Signed-off-by: Emil Velikov <emil.velikov@xxxxxxxxxxxxx> --- drivers/media/v4l2-core/v4l2-mem2mem.c | 2 ++ drivers/media/v4l2-core/v4l2-trace.c | 2 ++ include/trace/events/v4l2.h | 34 ++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index a83d3e4e7a85..6aa4ecafac6b 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -852,6 +852,7 @@ int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, int ret; vq = v4l2_m2m_get_vq(m2m_ctx, type); + trace_v4l2_m2m_stream_on(m2m_ctx, vq); ret = vb2_streamon(vq, type); if (!ret) v4l2_m2m_try_schedule(m2m_ctx); @@ -895,6 +896,7 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, wake_up(&m2m_ctx->finished); } spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); + trace_v4l2_m2m_stream_off(m2m_ctx, &q_ctx->q); return 0; } diff --git a/drivers/media/v4l2-core/v4l2-trace.c b/drivers/media/v4l2-core/v4l2-trace.c index b70208101f3c..ce9d393eb69e 100644 --- a/drivers/media/v4l2-core/v4l2-trace.c +++ b/drivers/media/v4l2-core/v4l2-trace.c @@ -19,3 +19,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(v4l2_m2m_run_job); EXPORT_TRACEPOINT_SYMBOL_GPL(v4l2_m2m_cancel_job_wait); EXPORT_TRACEPOINT_SYMBOL_GPL(v4l2_m2m_cancel_job); EXPORT_TRACEPOINT_SYMBOL_GPL(v4l2_m2m_finish_job); +EXPORT_TRACEPOINT_SYMBOL_GPL(v4l2_m2m_stream_on); +EXPORT_TRACEPOINT_SYMBOL_GPL(v4l2_m2m_stream_off); diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h index a545f6a13d0a..a48a8859a4ef 100644 --- a/include/trace/events/v4l2.h +++ b/include/trace/events/v4l2.h @@ -326,6 +326,7 @@ TRACE_EVENT(v4l2_m2m_buf_done, /* * v4l_m2m job tracing * expected order of events: + * v4l2_m2m_stream_on <= userspace request to start stream processing * v4l2_m2m_schedule <= start of a job trace * [v4l2_m2m_schedule_failed*] * v4l2_m2m_queue_job <= job queued on list of ready jobs @@ -333,6 +334,7 @@ TRACE_EVENT(v4l2_m2m_buf_done, * [v4l2_m2m_cancel_job_wait] <= job cancelled, but waiting for completion as it is already running * [v4l2_m2m_cancel_job*] <= job cancelled * v4l2_m2m_finish_job <= job finished, end of trace + * v4l2_m2m_stream_off <= userspace request to stop stream processing * * events in [] indicate optional events, that may appear, but usually would not be expected * events with * indicate terminal events that end a trace early @@ -435,6 +437,38 @@ DEFINE_EVENT(v4l2_m2m_event_class, v4l2_m2m_finish_job, TP_ARGS(ctx) ); +DECLARE_EVENT_CLASS(v4l2_m2m_streaming_class, + TP_PROTO(struct v4l2_m2m_ctx *ctx, struct vb2_queue *queue), + TP_ARGS(ctx, queue), + + TP_STRUCT__entry( + __field(int, minor) + __field(struct v4l2_fh *, fh) + __field(u32, type) + ), + + TP_fast_assign( + struct v4l2_fh *owner = ctx->cap_q_ctx.q.owner; + + __entry->minor = owner ? owner->vdev->minor : -1; + __entry->fh = owner; + __entry->type = queue->type; + + ), + TP_printk("minor = %d, fh = %p, type = %p", + __entry->minor, __entry->fh, show_type(__entry->type)) +) + +DEFINE_EVENT(v4l2_m2m_streaming_class, v4l2_m2m_stream_on, + TP_PROTO(struct v4l2_m2m_ctx *ctx, struct vb2_queue *queue), + TP_ARGS(ctx, queue) +); + +DEFINE_EVENT(v4l2_m2m_streaming_class, v4l2_m2m_stream_off, + TP_PROTO(struct v4l2_m2m_ctx *ctx, struct vb2_queue *queue), + TP_ARGS(ctx, queue) +); + #ifdef CREATE_TRACE_POINTS #define __trace_array_name(a, arr, num) (((unsigned)(a)) < num ? arr[a] : "unknown") static inline void __trace_sprint_v4l2_format(char *str, size_t size, struct v4l2_format *p) -- 2.31.1