Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/gt: Remove direct invocation of breadcrumb signaling

Only signal the breadcrumbs from inside the irq_work, simplifying our
interface and calling conventions. The micro-optimisation here is that
by always using the irq_work interface, we know we are always inside an
irq-off critical section for the breadcrumb signaling and can ellide
save/restore of the irq flags.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191217095642.3124521-7-chris@chris-wilson.co.uk

+27 -38
+9 -18
drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
··· 130 130 } 131 131 } 132 132 133 - void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) 133 + static void signal_irq_work(struct irq_work *work) 134 134 { 135 - struct intel_breadcrumbs *b = &engine->breadcrumbs; 135 + struct intel_breadcrumbs *b = container_of(work, typeof(*b), irq_work); 136 136 const ktime_t timestamp = ktime_get(); 137 137 struct intel_context *ce, *cn; 138 138 struct list_head *pos, *next; 139 - unsigned long flags; 140 139 LIST_HEAD(signal); 141 140 142 - spin_lock_irqsave(&b->irq_lock, flags); 141 + spin_lock(&b->irq_lock); 143 142 144 143 if (b->irq_armed && list_empty(&b->signalers)) 145 144 __intel_breadcrumbs_disarm_irq(b); ··· 184 185 } 185 186 } 186 187 187 - spin_unlock_irqrestore(&b->irq_lock, flags); 188 + spin_unlock(&b->irq_lock); 188 189 189 190 list_for_each_safe(pos, next, &signal) { 190 191 struct i915_request *rq = 191 192 list_entry(pos, typeof(*rq), signal_link); 192 193 struct list_head cb_list; 193 194 194 - spin_lock_irqsave(&rq->lock, flags); 195 + spin_lock(&rq->lock); 195 196 list_replace(&rq->fence.cb_list, &cb_list); 196 197 __dma_fence_signal__timestamp(&rq->fence, timestamp); 197 198 __dma_fence_signal__notify(&rq->fence, &cb_list); 198 - spin_unlock_irqrestore(&rq->lock, flags); 199 + spin_unlock(&rq->lock); 199 200 200 201 i915_request_put(rq); 201 202 } 202 - } 203 - 204 - static void signal_irq_work(struct irq_work *work) 205 - { 206 - struct intel_engine_cs *engine = 207 - container_of(work, typeof(*engine), breadcrumbs.irq_work); 208 - 209 - intel_engine_breadcrumbs_irq(engine); 210 203 } 211 204 212 205 static bool __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) ··· 281 290 282 291 /* 283 292 * We keep the seqno in retirement order, so we can break 284 - * inside intel_engine_breadcrumbs_irq as soon as we've passed 285 - * the last completed request (or seen a request that hasn't 286 - * event started). We could iterate the timeline->requests list, 293 + * inside intel_engine_signal_breadcrumbs as soon as we've 294 + * passed the last completed request (or seen a request that 295 + * hasn't event started). We could walk the timeline->requests, 287 296 * but keeping a separate signalers_list has the advantage of 288 297 * hopefully being much smaller than the full list and so 289 298 * provides faster iteration and detection when there are no
+1 -3
drivers/gpu/drm/i915/gt/intel_engine.h
··· 213 213 void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); 214 214 215 215 static inline void 216 - intel_engine_queue_breadcrumbs(struct intel_engine_cs *engine) 216 + intel_engine_signal_breadcrumbs(struct intel_engine_cs *engine) 217 217 { 218 218 irq_work_queue(&engine->breadcrumbs.irq_work); 219 219 } 220 - 221 - void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine); 222 220 223 221 void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine); 224 222 void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine);
+6 -6
drivers/gpu/drm/i915/gt/intel_gt_irq.c
··· 28 28 tasklet = true; 29 29 30 30 if (iir & GT_RENDER_USER_INTERRUPT) { 31 - intel_engine_queue_breadcrumbs(engine); 31 + intel_engine_signal_breadcrumbs(engine); 32 32 tasklet |= intel_engine_needs_breadcrumb_tasklet(engine); 33 33 } 34 34 ··· 245 245 void gen5_gt_irq_handler(struct intel_gt *gt, u32 gt_iir) 246 246 { 247 247 if (gt_iir & GT_RENDER_USER_INTERRUPT) 248 - intel_engine_breadcrumbs_irq(gt->engine_class[RENDER_CLASS][0]); 248 + intel_engine_signal_breadcrumbs(gt->engine_class[RENDER_CLASS][0]); 249 249 if (gt_iir & ILK_BSD_USER_INTERRUPT) 250 - intel_engine_breadcrumbs_irq(gt->engine_class[VIDEO_DECODE_CLASS][0]); 250 + intel_engine_signal_breadcrumbs(gt->engine_class[VIDEO_DECODE_CLASS][0]); 251 251 } 252 252 253 253 static void gen7_parity_error_irq_handler(struct intel_gt *gt, u32 iir) ··· 271 271 void gen6_gt_irq_handler(struct intel_gt *gt, u32 gt_iir) 272 272 { 273 273 if (gt_iir & GT_RENDER_USER_INTERRUPT) 274 - intel_engine_breadcrumbs_irq(gt->engine_class[RENDER_CLASS][0]); 274 + intel_engine_signal_breadcrumbs(gt->engine_class[RENDER_CLASS][0]); 275 275 if (gt_iir & GT_BSD_USER_INTERRUPT) 276 - intel_engine_breadcrumbs_irq(gt->engine_class[VIDEO_DECODE_CLASS][0]); 276 + intel_engine_signal_breadcrumbs(gt->engine_class[VIDEO_DECODE_CLASS][0]); 277 277 if (gt_iir & GT_BLT_USER_INTERRUPT) 278 - intel_engine_breadcrumbs_irq(gt->engine_class[COPY_ENGINE_CLASS][0]); 278 + intel_engine_signal_breadcrumbs(gt->engine_class[COPY_ENGINE_CLASS][0]); 279 279 280 280 if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | 281 281 GT_BSD_CS_ERROR_INTERRUPT |
+1 -1
drivers/gpu/drm/i915/gt/intel_lrc.c
··· 1483 1483 if (!list_empty(&ve->context.signal_link)) { 1484 1484 list_move_tail(&ve->context.signal_link, 1485 1485 &engine->breadcrumbs.signalers); 1486 - intel_engine_queue_breadcrumbs(engine); 1486 + intel_engine_signal_breadcrumbs(engine); 1487 1487 } 1488 1488 spin_unlock(&old->breadcrumbs.irq_lock); 1489 1489 }
+2 -2
drivers/gpu/drm/i915/gt/intel_reset.c
··· 742 742 engine->reset.finish(engine); 743 743 intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL); 744 744 745 - intel_engine_breadcrumbs_irq(engine); 745 + intel_engine_signal_breadcrumbs(engine); 746 746 } 747 747 748 748 static void reset_finish(struct intel_gt *gt, intel_engine_mask_t awake) ··· 771 771 i915_request_mark_complete(request); 772 772 spin_unlock_irqrestore(&engine->active.lock, flags); 773 773 774 - intel_engine_queue_breadcrumbs(engine); 774 + intel_engine_signal_breadcrumbs(engine); 775 775 } 776 776 777 777 static void __intel_gt_set_wedged(struct intel_gt *gt)
+1 -1
drivers/gpu/drm/i915/gt/intel_ring_submission.c
··· 719 719 } 720 720 721 721 /* Papering over lost _interrupts_ immediately following the restart */ 722 - intel_engine_queue_breadcrumbs(engine); 722 + intel_engine_signal_breadcrumbs(engine); 723 723 out: 724 724 intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL); 725 725
+1 -1
drivers/gpu/drm/i915/gt/intel_rps.c
··· 1566 1566 return; 1567 1567 1568 1568 if (pm_iir & PM_VEBOX_USER_INTERRUPT) 1569 - intel_engine_breadcrumbs_irq(gt->engine[VECS0]); 1569 + intel_engine_signal_breadcrumbs(gt->engine[VECS0]); 1570 1570 1571 1571 if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) 1572 1572 DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir);
+1 -1
drivers/gpu/drm/i915/gt/mock_engine.c
··· 77 77 i915_request_mark_complete(request); 78 78 GEM_BUG_ON(!i915_request_completed(request)); 79 79 80 - intel_engine_queue_breadcrumbs(request->engine); 80 + intel_engine_signal_breadcrumbs(request->engine); 81 81 } 82 82 83 83 static void hw_delay_complete(struct timer_list *t)
+4 -4
drivers/gpu/drm/i915/i915_irq.c
··· 3619 3619 intel_uncore_write16(&dev_priv->uncore, GEN2_IIR, iir); 3620 3620 3621 3621 if (iir & I915_USER_INTERRUPT) 3622 - intel_engine_breadcrumbs_irq(dev_priv->engine[RCS0]); 3622 + intel_engine_signal_breadcrumbs(dev_priv->engine[RCS0]); 3623 3623 3624 3624 if (iir & I915_MASTER_ERROR_INTERRUPT) 3625 3625 i8xx_error_irq_handler(dev_priv, eir, eir_stuck); ··· 3724 3724 I915_WRITE(GEN2_IIR, iir); 3725 3725 3726 3726 if (iir & I915_USER_INTERRUPT) 3727 - intel_engine_breadcrumbs_irq(dev_priv->engine[RCS0]); 3727 + intel_engine_signal_breadcrumbs(dev_priv->engine[RCS0]); 3728 3728 3729 3729 if (iir & I915_MASTER_ERROR_INTERRUPT) 3730 3730 i9xx_error_irq_handler(dev_priv, eir, eir_stuck); ··· 3866 3866 I915_WRITE(GEN2_IIR, iir); 3867 3867 3868 3868 if (iir & I915_USER_INTERRUPT) 3869 - intel_engine_breadcrumbs_irq(dev_priv->engine[RCS0]); 3869 + intel_engine_signal_breadcrumbs(dev_priv->engine[RCS0]); 3870 3870 3871 3871 if (iir & I915_BSD_USER_INTERRUPT) 3872 - intel_engine_breadcrumbs_irq(dev_priv->engine[VCS0]); 3872 + intel_engine_signal_breadcrumbs(dev_priv->engine[VCS0]); 3873 3873 3874 3874 if (iir & I915_MASTER_ERROR_INTERRUPT) 3875 3875 i9xx_error_irq_handler(dev_priv, eir, eir_stuck);
+1 -1
drivers/gpu/drm/i915/i915_request.c
··· 408 408 if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) && 409 409 !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags) && 410 410 !i915_request_enable_breadcrumb(request)) 411 - intel_engine_queue_breadcrumbs(engine); 411 + intel_engine_signal_breadcrumbs(engine); 412 412 413 413 __notify_execute_cb(request); 414 414