If we convert the tracing over from direct use of ring->irq_get() and over to the breadcrumb infrastructure, we only have a single user of the ring->irq_get and so we will be able to simplify the driver routines (eliminating the redundant validation and irq refcounting). Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 8 ------- drivers/gpu/drm/i915/i915_gem.c | 6 ----- drivers/gpu/drm/i915/i915_trace.h | 2 +- drivers/gpu/drm/i915/intel_breadcrumbs.c | 39 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +++- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 37f4ef59fb4a..dabfb043362f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3625,12 +3625,4 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms) schedule_timeout_uninterruptible(remaining_jiffies); } } - -static inline void i915_trace_irq_get(struct intel_engine_cs *ring, - struct drm_i915_gem_request *req) -{ - if (ring->trace_irq_req == NULL && ring->irq_get(ring)) - i915_gem_request_assign(&ring->trace_irq_req, req); -} - #endif diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 78bcd231b100..fdd9dd5296e9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2907,12 +2907,6 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) i915_gem_object_retire__read(obj, ring->id); } - if (unlikely(ring->trace_irq_req && - i915_gem_request_completed(ring->trace_irq_req))) { - ring->irq_put(ring); - i915_gem_request_assign(&ring->trace_irq_req, NULL); - } - WARN_ON(i915_verify_lists(ring->dev)); } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index efca75bcace3..628008e6c24f 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -503,7 +503,7 @@ TRACE_EVENT(i915_gem_ring_dispatch, __entry->ring = ring->id; __entry->seqno = i915_gem_request_get_seqno(req); __entry->flags = flags; - i915_trace_irq_get(ring, req); + intel_breadcrumbs_enable_trace(req); ), TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x", diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 69b966b4f71b..ea5ee3f7fe01 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -258,17 +258,56 @@ void intel_engine_remove_breadcrumb(struct intel_engine_cs *engine, spin_unlock(&b->lock); } +static void intel_breadcrumbs_tracer(struct work_struct *work) +{ + struct intel_breadcrumbs *b = + container_of(work, struct intel_breadcrumbs, trace); + struct intel_rps_client rps; + + INIT_LIST_HEAD(&rps.link); + + do { + struct drm_i915_gem_request *request; + + spin_lock(&b->lock); + request = b->trace_request; + b->trace_request = NULL; + spin_unlock(&b->lock); + if (request == NULL) + return; + + __i915_wait_request(request, true, NULL, &rps); + i915_gem_request_unreference__unlocked(request); + } while (1); +} + +void intel_breadcrumbs_enable_trace(struct drm_i915_gem_request *request) +{ + struct intel_breadcrumbs *b = &request->ring->breadcrumbs; + + spin_lock(&b->lock); + if (b->trace_request == NULL) { + b->trace_request = i915_gem_request_reference(request); + queue_work(system_long_wq, &b->trace); + } + spin_unlock(&b->lock); +} + void intel_engine_init_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; spin_lock_init(&b->lock); setup_timer(&b->fake_irq, intel_breadcrumbs_fake_irq, (unsigned long)b); + INIT_WORK(&b->trace, intel_breadcrumbs_tracer); } void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; + cancel_work_sync(&b->trace); + i915_gem_request_unreference(b->trace_request); + del_timer_sync(&b->fake_irq); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index a35c17106f4b..0fd6395f1a1b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -182,6 +182,8 @@ struct intel_engine_cs { struct rb_root requests; /* sorted by retirement */ struct task_struct *first_waiter; /* bh for user interrupts */ struct timer_list fake_irq; /* used after a missed interrupt */ + struct work_struct trace; + struct drm_i915_gem_request *trace_request; bool irq_enabled; bool rpm_wakelock; } breadcrumbs; @@ -198,7 +200,6 @@ struct intel_engine_cs { unsigned irq_refcount; /* protected by dev_priv->irq_lock */ u32 irq_enable_mask; /* bitmask to enable ring interrupt */ - struct drm_i915_gem_request *trace_irq_req; bool __must_check (*irq_get)(struct intel_engine_cs *ring); void (*irq_put)(struct intel_engine_cs *ring); @@ -555,6 +556,7 @@ bool intel_engine_add_breadcrumb(struct intel_engine_cs *engine, struct intel_breadcrumb *wait); void intel_engine_remove_breadcrumb(struct intel_engine_cs *engine, struct intel_breadcrumb *wait); +void intel_breadcrumbs_enable_trace(struct drm_i915_gem_request *request); static inline bool intel_engine_has_waiter(struct intel_engine_cs *engine) { return READ_ONCE(engine->breadcrumbs.first_waiter); -- 2.6.3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx