From: John Harrison <John.C.Harrison@xxxxxxxxx> Added trace points to the scheduler to track all the various events, node state transitions and other interesting things that occur. v2: Updated for new request completion tracking implementation. Change-Id: I9886390cfc7897bc1faf50a104bc651d8baed8a5 For: VIZ-1587 Signed-off-by: John Harrison <John.C.Harrison@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 + drivers/gpu/drm/i915/i915_scheduler.c | 24 ++++ drivers/gpu/drm/i915/i915_trace.h | 190 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.c | 2 + 4 files changed, 218 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index a247d50..e748fd3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1226,6 +1226,8 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, i915_gem_execbuffer_move_to_active(vmas, params->request); + trace_i915_gem_ring_queue(ring, params); + qe = container_of(params, typeof(*qe), params); ret = i915_scheduler_queue_execbuffer(qe); if (ret) diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index ddd21b2..098f69a 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -97,6 +97,8 @@ int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe) if (i915.scheduler_override & i915_so_direct_submit) { int ret; + trace_i915_scheduler_queue(qe->params.ring, qe); + WARN_ON(qe->params.fence_wait && (!sync_fence_is_signaled(qe->params.fence_wait))); @@ -248,6 +250,9 @@ int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe) not_flying = i915_scheduler_count_flying(scheduler, ring) < scheduler->min_flying; + trace_i915_scheduler_queue(ring, node); + trace_i915_scheduler_node_state_change(ring, node); + spin_unlock_irqrestore(&scheduler->lock, flags); if (not_flying) @@ -275,6 +280,9 @@ static int i915_scheduler_fly_node(struct i915_scheduler_queue_entry *node) node->status = i915_sqs_flying; + trace_i915_scheduler_fly(ring, node); + trace_i915_scheduler_node_state_change(ring, node); + if (!(scheduler->flags[ring->id] & i915_sf_interrupts_enabled)) { bool success = true; @@ -340,6 +348,8 @@ static void i915_scheduler_node_requeue(struct i915_scheduler_queue_entry *node) node->status = i915_sqs_queued; node->params.request->seqno = 0; + trace_i915_scheduler_unfly(node->params.ring, node); + trace_i915_scheduler_node_state_change(node->params.ring, node); } /* Give up on a popped node completely. For example, because it is causing the @@ -350,6 +360,8 @@ static void i915_scheduler_node_kill(struct i915_scheduler_queue_entry *node) BUG_ON(!I915_SQS_IS_FLYING(node)); node->status = i915_sqs_dead; + trace_i915_scheduler_unfly(node->params.ring, node); + trace_i915_scheduler_node_state_change(node->params.ring, node); } /* @@ -369,6 +381,8 @@ bool i915_scheduler_notify_request(struct drm_i915_gem_request *req) struct i915_scheduler_queue_entry *node = req->scheduler_qe; unsigned long flags; + trace_i915_scheduler_landing(req); + if (!node) return false; @@ -382,6 +396,8 @@ bool i915_scheduler_notify_request(struct drm_i915_gem_request *req) else node->status = i915_sqs_complete; + trace_i915_scheduler_node_state_change(req->ring, node); + spin_unlock_irqrestore(&scheduler->lock, flags); return true; @@ -524,6 +540,8 @@ static int i915_scheduler_remove(struct intel_engine_cs *ring) /* Launch more packets now? */ do_submit = (queued > 0) && (flying < scheduler->min_flying); + trace_i915_scheduler_remove(ring, min_seqno, do_submit); + spin_unlock_irqrestore(&scheduler->lock, flags); if (!do_submit && list_empty(&remove)) @@ -538,6 +556,8 @@ static int i915_scheduler_remove(struct intel_engine_cs *ring) node = list_first_entry(&remove, typeof(*node), link); list_del(&node->link); + trace_i915_scheduler_destroy(ring, node); + if (node->params.fence_wait) sync_fence_put(node->params.fence_wait); @@ -952,6 +972,8 @@ static int i915_scheduler_pop_from_queue_locked(struct intel_engine_cs *ring, INIT_LIST_HEAD(&best->link); best->status = i915_sqs_popped; + trace_i915_scheduler_node_state_change(ring, best); + ret = 0; } else { /* Can only get here if: @@ -1005,6 +1027,8 @@ static int i915_scheduler_pop_from_queue_locked(struct intel_engine_cs *ring, spin_lock_irqsave(&scheduler->lock, *flags); } + trace_i915_scheduler_pop_from_queue(ring, best); + *pop_node = best; return ret; } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 76b08fa..73b0ee9 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -9,6 +9,7 @@ #include "i915_drv.h" #include "intel_drv.h" #include "intel_ringbuffer.h" +#include "i915_scheduler.h" #undef TRACE_SYSTEM #define TRACE_SYSTEM i915 @@ -822,6 +823,195 @@ TRACE_EVENT(switch_mm, __entry->dev, __entry->ring, __entry->to, __entry->vm) ); +TRACE_EVENT(i915_scheduler_queue, + TP_PROTO(struct intel_engine_cs *ring, + struct i915_scheduler_queue_entry *node), + TP_ARGS(ring, node), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, uniq) + __field(u32, seqno) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->uniq = node ? node->params.request->uniq : 0; + __entry->seqno = node ? node->params.request->seqno : 0; + ), + + TP_printk("ring=%d, uniq=%d, seqno=%d", + __entry->ring, __entry->uniq, __entry->seqno) +); + +TRACE_EVENT(i915_scheduler_fly, + TP_PROTO(struct intel_engine_cs *ring, + struct i915_scheduler_queue_entry *node), + TP_ARGS(ring, node), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, uniq) + __field(u32, seqno) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->uniq = node ? node->params.request->uniq : 0; + __entry->seqno = node ? node->params.request->seqno : 0; + ), + + TP_printk("ring=%d, uniq=%d, seqno=%d", + __entry->ring, __entry->uniq, __entry->seqno) +); + +TRACE_EVENT(i915_scheduler_unfly, + TP_PROTO(struct intel_engine_cs *ring, + struct i915_scheduler_queue_entry *node), + TP_ARGS(ring, node), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, uniq) + __field(u32, seqno) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->uniq = node ? node->params.request->uniq : 0; + __entry->seqno = node ? node->params.request->seqno : 0; + ), + + TP_printk("ring=%d, uniq=%d, seqno=%d", + __entry->ring, __entry->uniq, __entry->seqno) +); + +TRACE_EVENT(i915_scheduler_landing, + TP_PROTO(struct drm_i915_gem_request *req), + TP_ARGS(req), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, uniq) + __field(u32, seqno) + __field(u32, status) + ), + + TP_fast_assign( + __entry->ring = req->ring->id; + __entry->uniq = req->uniq; + __entry->seqno = req->seqno; + __entry->status = req->scheduler_qe ? req->scheduler_qe->status : ~0U; + ), + + TP_printk("ring=%d, uniq=%d, seqno=%d, status=%d", + __entry->ring, __entry->uniq, __entry->seqno, __entry->status) +); + +TRACE_EVENT(i915_scheduler_remove, + TP_PROTO(struct intel_engine_cs *ring, + u32 min_seqno, bool do_submit), + TP_ARGS(ring, min_seqno, do_submit), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, min_seqno) + __field(bool, do_submit) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->min_seqno = min_seqno; + __entry->do_submit = do_submit; + ), + + TP_printk("ring=%d, min_seqno = %d, do_submit=%d", + __entry->ring, __entry->min_seqno, __entry->do_submit) +); + +TRACE_EVENT(i915_scheduler_destroy, + TP_PROTO(struct intel_engine_cs *ring, + struct i915_scheduler_queue_entry *node), + TP_ARGS(ring, node), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, uniq) + __field(u32, seqno) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->uniq = node ? node->params.request->uniq : 0; + __entry->seqno = node ? node->params.request->seqno : 0; + ), + + TP_printk("ring=%d, uniq=%d, seqno=%d", + __entry->ring, __entry->uniq, __entry->seqno) +); + +TRACE_EVENT(i915_scheduler_pop_from_queue, + TP_PROTO(struct intel_engine_cs *ring, + struct i915_scheduler_queue_entry *node), + TP_ARGS(ring, node), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, uniq) + __field(u32, seqno) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->uniq = node ? node->params.request->uniq : 0; + __entry->seqno = node ? node->params.request->seqno : 0; + ), + + TP_printk("ring=%d, uniq=%d, seqno=%d", + __entry->ring, __entry->uniq, __entry->seqno) +); + +TRACE_EVENT(i915_scheduler_node_state_change, + TP_PROTO(struct intel_engine_cs *ring, + struct i915_scheduler_queue_entry *node), + TP_ARGS(ring, node), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, uniq) + __field(u32, seqno) + __field(u32, status) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->uniq = node ? node->params.request->uniq : 0; + __entry->seqno = node->params.request->seqno; + __entry->status = node->status; + ), + + TP_printk("ring=%d, uniq=%d, seqno=%d, status=%d", + __entry->ring, __entry->uniq, __entry->seqno, __entry->status) +); + +TRACE_EVENT(i915_gem_ring_queue, + TP_PROTO(struct intel_engine_cs *ring, + struct i915_execbuffer_params *params), + TP_ARGS(ring, params), + + TP_STRUCT__entry( + __field(u32, ring) + __field(u32, seqno) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->seqno = params->request->seqno; + ), + + TP_printk("ring=%d, seqno=%d", __entry->ring, __entry->seqno) +); + #endif /* _I915_TRACE_H_ */ /* This part must be outside protection */ diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 41e20ba..6c01f6c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -910,6 +910,8 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, i915_gem_execbuffer_move_to_active(vmas, params->request); + trace_i915_gem_ring_queue(ring, params); + qe = container_of(params, typeof(*qe), params); ret = i915_scheduler_queue_execbuffer(qe); if (ret) -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx