On 02/18/2016 06:27 AM, john.c.harri...@intel.com wrote:
> From: John Harrison <john.c.harri...@intel.com>
> 
> 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.
> 
> v3: Updated for changes to node kill code.
> 
> v4: Wrapped some long lines to keep the style checker happy.
> 
> For: VIZ-1587
> Signed-off-by: John Harrison <john.c.harri...@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c |   2 +
>  drivers/gpu/drm/i915/i915_scheduler.c      |  26 ++++
>  drivers/gpu/drm/i915/i915_trace.h          | 196 
> +++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_lrc.c           |   2 +
>  4 files changed, 226 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
> b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index b9ad0fd..d4de8c7 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1272,6 +1272,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 47d7de4..e56ce08 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler.c
> +++ b/drivers/gpu/drm/i915/i915_scheduler.c
> @@ -88,6 +88,8 @@ static void i915_scheduler_node_requeue(struct 
> i915_scheduler_queue_entry *node)
>       /* Seqno will be reassigned on relaunch */
>       node->params.request->seqno = 0;
>       node->status = i915_sqs_queued;
> +     trace_i915_scheduler_unfly(node->params.ring, node);
> +     trace_i915_scheduler_node_state_change(node->params.ring, node);
>  }
>  
>  /*
> @@ -99,7 +101,11 @@ static void i915_scheduler_node_kill(struct 
> i915_scheduler_queue_entry *node)
>       WARN_ON(!node);
>       WARN_ON(I915_SQS_IS_COMPLETE(node));
>  
> +     if (I915_SQS_IS_FLYING(node))
> +             trace_i915_scheduler_unfly(node->params.ring, node);
> +
>       node->status = i915_sqs_dead;
> +     trace_i915_scheduler_node_state_change(node->params.ring, node);
>  }
>  
>  /* Mark a node as in flight on the hardware. */
> @@ -124,6 +130,9 @@ static int i915_scheduler_node_fly(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;
>  
> @@ -280,6 +289,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:
> @@ -297,6 +308,8 @@ static int i915_scheduler_pop_from_queue_locked(struct 
> intel_engine_cs *ring,
>               }
>       }
>  
> +     trace_i915_scheduler_pop_from_queue(ring, best);
> +
>       *pop_node = best;
>       return ret;
>  }
> @@ -506,6 +519,8 @@ static int i915_scheduler_queue_execbuffer_bypass(struct 
> i915_scheduler_queue_en
>       struct i915_scheduler *scheduler = dev_priv->scheduler;
>       int ret;
>  
> +     trace_i915_scheduler_queue(qe->params.ring, qe);
> +
>       intel_ring_reserved_space_cancel(qe->params.request->ringbuf);
>  
>       scheduler->flags[qe->params.ring->id] |= i915_sf_submitting;
> @@ -628,6 +643,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_irq(&scheduler->lock);
>  
>       if (not_flying)
> @@ -657,6 +675,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;
>  
> @@ -670,6 +690,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;
> @@ -877,6 +899,8 @@ static bool i915_scheduler_remove(struct i915_scheduler 
> *scheduler,
>       /* Launch more packets now? */
>       do_submit = (queued > 0) && (flying < scheduler->min_flying);
>  
> +     trace_i915_scheduler_remove(ring, min_seqno, do_submit);
> +
>       spin_unlock_irq(&scheduler->lock);
>  
>       return do_submit;
> @@ -912,6 +936,8 @@ static void i915_scheduler_process_work(struct 
> intel_engine_cs *ring)
>               node = list_first_entry(&remove, typeof(*node), link);
>               list_del(&node->link);
>  
> +             trace_i915_scheduler_destroy(ring, node);
> +
>               /* Free up all the DRM references */
>               i915_scheduler_clean_node(node);
>  
> diff --git a/drivers/gpu/drm/i915/i915_trace.h 
> b/drivers/gpu/drm/i915/i915_trace.h
> index 455c215..c3c4e58 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
> @@ -826,6 +827,201 @@ 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, uniq)
> +                          __field(u32, seqno)
> +                          ),
> +
> +         TP_fast_assign(
> +                        __entry->ring  = ring->id;
> +                        __entry->uniq  = params->request->uniq;
> +                        __entry->seqno = params->request->seqno;
> +                        ),
> +
> +         TP_printk("ring=%d, uniq=%d, seqno=%d", __entry->ring,
> +                   __entry->uniq, __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 9c7a79a..2b9f49c 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -954,6 +954,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)
> 

Oops, forgot to ask if there are any tools for igt that make use of these, e.g. 
some kind of scheduler top util that looks for bubbles or starved batches or 
something.

Jesse
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to