Skip to content

Commit 0669a6e

Browse files
ickledanvet
authored andcommitted
drm/i915/gt: Move CS interrupt handler to the backend
The different submission backends each have their own preferred behaviour and interrupt setup. Let each handle their own interrupts. This becomes more useful later as we to extract the use of auxiliary state in the interrupt handler that is backend specific. Signed-off-by: Matthew Brost <[email protected]> Signed-off-by: Chris Wilson <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Reviewed-by: Matthew Brost <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent c92c36e commit 0669a6e

File tree

9 files changed

+124
-74
lines changed

9 files changed

+124
-74
lines changed

drivers/gpu/drm/i915/gt/intel_engine_cs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ static void intel_engine_sanitize_mmio(struct intel_engine_cs *engine)
255255
intel_engine_set_hwsp_writemask(engine, ~0u);
256256
}
257257

258+
static void nop_irq_handler(struct intel_engine_cs *engine, u16 iir)
259+
{
260+
GEM_DEBUG_WARN_ON(iir);
261+
}
262+
258263
static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
259264
{
260265
const struct engine_info *info = &intel_engines[id];
@@ -292,6 +297,8 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
292297
engine->hw_id = info->hw_id;
293298
engine->guc_id = MAKE_GUC_ID(info->class, info->instance);
294299

300+
engine->irq_handler = nop_irq_handler;
301+
295302
engine->class = info->class;
296303
engine->instance = info->instance;
297304
__sprint_engine_name(engine);

drivers/gpu/drm/i915/gt/intel_engine_types.h

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ struct intel_engine_cs {
402402
u32 irq_enable_mask; /* bitmask to enable ring interrupt */
403403
void (*irq_enable)(struct intel_engine_cs *engine);
404404
void (*irq_disable)(struct intel_engine_cs *engine);
405+
void (*irq_handler)(struct intel_engine_cs *engine, u16 iir);
405406

406407
void (*sanitize)(struct intel_engine_cs *engine);
407408
int (*resume)(struct intel_engine_cs *engine);
@@ -481,10 +482,9 @@ struct intel_engine_cs {
481482
#define I915_ENGINE_HAS_PREEMPTION BIT(2)
482483
#define I915_ENGINE_HAS_SEMAPHORES BIT(3)
483484
#define I915_ENGINE_HAS_TIMESLICES BIT(4)
484-
#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(5)
485-
#define I915_ENGINE_IS_VIRTUAL BIT(6)
486-
#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(7)
487-
#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(8)
485+
#define I915_ENGINE_IS_VIRTUAL BIT(5)
486+
#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6)
487+
#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7)
488488
unsigned int flags;
489489

490490
/*
@@ -593,12 +593,6 @@ intel_engine_has_timeslices(const struct intel_engine_cs *engine)
593593
return engine->flags & I915_ENGINE_HAS_TIMESLICES;
594594
}
595595

596-
static inline bool
597-
intel_engine_needs_breadcrumb_tasklet(const struct intel_engine_cs *engine)
598-
{
599-
return engine->flags & I915_ENGINE_NEEDS_BREADCRUMB_TASKLET;
600-
}
601-
602596
static inline bool
603597
intel_engine_is_virtual(const struct intel_engine_cs *engine)
604598
{

drivers/gpu/drm/i915/gt/intel_execlists_submission.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
#include "intel_engine_stats.h"
119119
#include "intel_execlists_submission.h"
120120
#include "intel_gt.h"
121+
#include "intel_gt_irq.h"
121122
#include "intel_gt_pm.h"
122123
#include "intel_gt_requests.h"
123124
#include "intel_lrc.h"
@@ -2384,6 +2385,45 @@ static void execlists_submission_tasklet(struct tasklet_struct *t)
23842385
rcu_read_unlock();
23852386
}
23862387

2388+
static void execlists_irq_handler(struct intel_engine_cs *engine, u16 iir)
2389+
{
2390+
bool tasklet = false;
2391+
2392+
if (unlikely(iir & GT_CS_MASTER_ERROR_INTERRUPT)) {
2393+
u32 eir;
2394+
2395+
/* Upper 16b are the enabling mask, rsvd for internal errors */
2396+
eir = ENGINE_READ(engine, RING_EIR) & GENMASK(15, 0);
2397+
ENGINE_TRACE(engine, "CS error: %x\n", eir);
2398+
2399+
/* Disable the error interrupt until after the reset */
2400+
if (likely(eir)) {
2401+
ENGINE_WRITE(engine, RING_EMR, ~0u);
2402+
ENGINE_WRITE(engine, RING_EIR, eir);
2403+
WRITE_ONCE(engine->execlists.error_interrupt, eir);
2404+
tasklet = true;
2405+
}
2406+
}
2407+
2408+
if (iir & GT_WAIT_SEMAPHORE_INTERRUPT) {
2409+
WRITE_ONCE(engine->execlists.yield,
2410+
ENGINE_READ_FW(engine, RING_EXECLIST_STATUS_HI));
2411+
ENGINE_TRACE(engine, "semaphore yield: %08x\n",
2412+
engine->execlists.yield);
2413+
if (del_timer(&engine->execlists.timer))
2414+
tasklet = true;
2415+
}
2416+
2417+
if (iir & GT_CONTEXT_SWITCH_INTERRUPT)
2418+
tasklet = true;
2419+
2420+
if (iir & GT_RENDER_USER_INTERRUPT)
2421+
intel_engine_signal_breadcrumbs(engine);
2422+
2423+
if (tasklet)
2424+
tasklet_hi_schedule(&engine->execlists.tasklet);
2425+
}
2426+
23872427
static void __execlists_kick(struct intel_engine_execlists *execlists)
23882428
{
23892429
/* Kick the tasklet for some interrupt coalescing and reset handling */
@@ -3133,6 +3173,7 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
31333173
* until a more refined solution exists.
31343174
*/
31353175
}
3176+
intel_engine_set_irq_handler(engine, execlists_irq_handler);
31363177

31373178
engine->flags |= I915_ENGINE_SUPPORTS_STATS;
31383179
if (!intel_vgpu_active(engine->i915)) {

drivers/gpu/drm/i915/gt/intel_gt_irq.c

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -20,48 +20,6 @@ static void guc_irq_handler(struct intel_guc *guc, u16 iir)
2020
intel_guc_to_host_event_handler(guc);
2121
}
2222

23-
static void
24-
cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
25-
{
26-
bool tasklet = false;
27-
28-
if (unlikely(iir & GT_CS_MASTER_ERROR_INTERRUPT)) {
29-
u32 eir;
30-
31-
/* Upper 16b are the enabling mask, rsvd for internal errors */
32-
eir = ENGINE_READ(engine, RING_EIR) & GENMASK(15, 0);
33-
ENGINE_TRACE(engine, "CS error: %x\n", eir);
34-
35-
/* Disable the error interrupt until after the reset */
36-
if (likely(eir)) {
37-
ENGINE_WRITE(engine, RING_EMR, ~0u);
38-
ENGINE_WRITE(engine, RING_EIR, eir);
39-
WRITE_ONCE(engine->execlists.error_interrupt, eir);
40-
tasklet = true;
41-
}
42-
}
43-
44-
if (iir & GT_WAIT_SEMAPHORE_INTERRUPT) {
45-
WRITE_ONCE(engine->execlists.yield,
46-
ENGINE_READ_FW(engine, RING_EXECLIST_STATUS_HI));
47-
ENGINE_TRACE(engine, "semaphore yield: %08x\n",
48-
engine->execlists.yield);
49-
if (del_timer(&engine->execlists.timer))
50-
tasklet = true;
51-
}
52-
53-
if (iir & GT_CONTEXT_SWITCH_INTERRUPT)
54-
tasklet = true;
55-
56-
if (iir & GT_RENDER_USER_INTERRUPT) {
57-
intel_engine_signal_breadcrumbs(engine);
58-
tasklet |= intel_engine_needs_breadcrumb_tasklet(engine);
59-
}
60-
61-
if (tasklet)
62-
tasklet_hi_schedule(&engine->execlists.tasklet);
63-
}
64-
6523
static u32
6624
gen11_gt_engine_identity(struct intel_gt *gt,
6725
const unsigned int bank, const unsigned int bit)
@@ -122,7 +80,7 @@ gen11_engine_irq_handler(struct intel_gt *gt, const u8 class,
12280
engine = NULL;
12381

12482
if (likely(engine))
125-
return cs_irq_handler(engine, iir);
83+
return intel_engine_cs_irq(engine, iir);
12684

12785
WARN_ONCE(1, "unhandled engine interrupt class=0x%x, instance=0x%x\n",
12886
class, instance);
@@ -275,9 +233,12 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
275233
void gen5_gt_irq_handler(struct intel_gt *gt, u32 gt_iir)
276234
{
277235
if (gt_iir & GT_RENDER_USER_INTERRUPT)
278-
intel_engine_signal_breadcrumbs(gt->engine_class[RENDER_CLASS][0]);
236+
intel_engine_cs_irq(gt->engine_class[RENDER_CLASS][0],
237+
gt_iir);
238+
279239
if (gt_iir & ILK_BSD_USER_INTERRUPT)
280-
intel_engine_signal_breadcrumbs(gt->engine_class[VIDEO_DECODE_CLASS][0]);
240+
intel_engine_cs_irq(gt->engine_class[VIDEO_DECODE_CLASS][0],
241+
gt_iir);
281242
}
282243

283244
static void gen7_parity_error_irq_handler(struct intel_gt *gt, u32 iir)
@@ -301,11 +262,16 @@ static void gen7_parity_error_irq_handler(struct intel_gt *gt, u32 iir)
301262
void gen6_gt_irq_handler(struct intel_gt *gt, u32 gt_iir)
302263
{
303264
if (gt_iir & GT_RENDER_USER_INTERRUPT)
304-
intel_engine_signal_breadcrumbs(gt->engine_class[RENDER_CLASS][0]);
265+
intel_engine_cs_irq(gt->engine_class[RENDER_CLASS][0],
266+
gt_iir);
267+
305268
if (gt_iir & GT_BSD_USER_INTERRUPT)
306-
intel_engine_signal_breadcrumbs(gt->engine_class[VIDEO_DECODE_CLASS][0]);
269+
intel_engine_cs_irq(gt->engine_class[VIDEO_DECODE_CLASS][0],
270+
gt_iir >> 12);
271+
307272
if (gt_iir & GT_BLT_USER_INTERRUPT)
308-
intel_engine_signal_breadcrumbs(gt->engine_class[COPY_ENGINE_CLASS][0]);
273+
intel_engine_cs_irq(gt->engine_class[COPY_ENGINE_CLASS][0],
274+
gt_iir >> 22);
309275

310276
if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT |
311277
GT_BSD_CS_ERROR_INTERRUPT |
@@ -324,30 +290,30 @@ void gen8_gt_irq_handler(struct intel_gt *gt, u32 master_ctl)
324290
if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
325291
iir = raw_reg_read(regs, GEN8_GT_IIR(0));
326292
if (likely(iir)) {
327-
cs_irq_handler(gt->engine_class[RENDER_CLASS][0],
328-
iir >> GEN8_RCS_IRQ_SHIFT);
329-
cs_irq_handler(gt->engine_class[COPY_ENGINE_CLASS][0],
330-
iir >> GEN8_BCS_IRQ_SHIFT);
293+
intel_engine_cs_irq(gt->engine_class[RENDER_CLASS][0],
294+
iir >> GEN8_RCS_IRQ_SHIFT);
295+
intel_engine_cs_irq(gt->engine_class[COPY_ENGINE_CLASS][0],
296+
iir >> GEN8_BCS_IRQ_SHIFT);
331297
raw_reg_write(regs, GEN8_GT_IIR(0), iir);
332298
}
333299
}
334300

335301
if (master_ctl & (GEN8_GT_VCS0_IRQ | GEN8_GT_VCS1_IRQ)) {
336302
iir = raw_reg_read(regs, GEN8_GT_IIR(1));
337303
if (likely(iir)) {
338-
cs_irq_handler(gt->engine_class[VIDEO_DECODE_CLASS][0],
339-
iir >> GEN8_VCS0_IRQ_SHIFT);
340-
cs_irq_handler(gt->engine_class[VIDEO_DECODE_CLASS][1],
341-
iir >> GEN8_VCS1_IRQ_SHIFT);
304+
intel_engine_cs_irq(gt->engine_class[VIDEO_DECODE_CLASS][0],
305+
iir >> GEN8_VCS0_IRQ_SHIFT);
306+
intel_engine_cs_irq(gt->engine_class[VIDEO_DECODE_CLASS][1],
307+
iir >> GEN8_VCS1_IRQ_SHIFT);
342308
raw_reg_write(regs, GEN8_GT_IIR(1), iir);
343309
}
344310
}
345311

346312
if (master_ctl & GEN8_GT_VECS_IRQ) {
347313
iir = raw_reg_read(regs, GEN8_GT_IIR(3));
348314
if (likely(iir)) {
349-
cs_irq_handler(gt->engine_class[VIDEO_ENHANCEMENT_CLASS][0],
350-
iir >> GEN8_VECS_IRQ_SHIFT);
315+
intel_engine_cs_irq(gt->engine_class[VIDEO_ENHANCEMENT_CLASS][0],
316+
iir >> GEN8_VECS_IRQ_SHIFT);
351317
raw_reg_write(regs, GEN8_GT_IIR(3), iir);
352318
}
353319
}

drivers/gpu/drm/i915/gt/intel_gt_irq.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <linux/types.h>
1010

11+
#include "intel_engine_types.h"
12+
1113
struct intel_gt;
1214

1315
#define GEN8_GT_IRQS (GEN8_GT_RCS_IRQ | \
@@ -39,4 +41,25 @@ void gen8_gt_irq_handler(struct intel_gt *gt, u32 master_ctl);
3941
void gen8_gt_irq_reset(struct intel_gt *gt);
4042
void gen8_gt_irq_postinstall(struct intel_gt *gt);
4143

44+
static inline void intel_engine_cs_irq(struct intel_engine_cs *engine, u16 iir)
45+
{
46+
if (iir)
47+
engine->irq_handler(engine, iir);
48+
}
49+
50+
static inline void
51+
intel_engine_set_irq_handler(struct intel_engine_cs *engine,
52+
void (*fn)(struct intel_engine_cs *engine,
53+
u16 iir))
54+
{
55+
/*
56+
* As the interrupt is live as allocate and setup the engines,
57+
* err on the side of caution and apply barriers to updating
58+
* the irq handler callback. This assures that when we do use
59+
* the engine, we will receive interrupts only to ourselves,
60+
* and not lose any.
61+
*/
62+
smp_store_mb(engine->irq_handler, fn);
63+
}
64+
4265
#endif /* INTEL_GT_IRQ_H */

drivers/gpu/drm/i915/gt/intel_ring_submission.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "intel_breadcrumbs.h"
1313
#include "intel_context.h"
1414
#include "intel_gt.h"
15+
#include "intel_gt_irq.h"
1516
#include "intel_reset.h"
1617
#include "intel_ring.h"
1718
#include "shmem_utils.h"
@@ -1017,10 +1018,17 @@ static void ring_release(struct intel_engine_cs *engine)
10171018
intel_timeline_put(engine->legacy.timeline);
10181019
}
10191020

1021+
static void irq_handler(struct intel_engine_cs *engine, u16 iir)
1022+
{
1023+
intel_engine_signal_breadcrumbs(engine);
1024+
}
1025+
10201026
static void setup_irq(struct intel_engine_cs *engine)
10211027
{
10221028
struct drm_i915_private *i915 = engine->i915;
10231029

1030+
intel_engine_set_irq_handler(engine, irq_handler);
1031+
10241032
if (INTEL_GEN(i915) >= 6) {
10251033
engine->irq_enable = gen6_irq_enable;
10261034
engine->irq_disable = gen6_irq_disable;

drivers/gpu/drm/i915/gt/intel_rps.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1774,7 +1774,7 @@ void gen6_rps_irq_handler(struct intel_rps *rps, u32 pm_iir)
17741774
return;
17751775

17761776
if (pm_iir & PM_VEBOX_USER_INTERRUPT)
1777-
intel_engine_signal_breadcrumbs(gt->engine[VECS0]);
1777+
intel_engine_cs_irq(gt->engine[VECS0], pm_iir >> 10);
17781778

17791779
if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT)
17801780
DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir);

drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "gt/intel_context.h"
1212
#include "gt/intel_engine_pm.h"
1313
#include "gt/intel_gt.h"
14+
#include "gt/intel_gt_irq.h"
1415
#include "gt/intel_gt_pm.h"
1516
#include "gt/intel_lrc.h"
1617
#include "gt/intel_mocs.h"
@@ -264,6 +265,14 @@ static void guc_submission_tasklet(struct tasklet_struct *t)
264265
spin_unlock_irqrestore(&engine->active.lock, flags);
265266
}
266267

268+
static void cs_irq_handler(struct intel_engine_cs *engine, u16 iir)
269+
{
270+
if (iir & GT_RENDER_USER_INTERRUPT) {
271+
intel_engine_signal_breadcrumbs(engine);
272+
tasklet_hi_schedule(&engine->execlists.tasklet);
273+
}
274+
}
275+
267276
static void guc_reset_prepare(struct intel_engine_cs *engine)
268277
{
269278
struct intel_engine_execlists * const execlists = &engine->execlists;
@@ -645,7 +654,6 @@ static void guc_default_vfuncs(struct intel_engine_cs *engine)
645654
}
646655
engine->set_default_submission = guc_set_default_submission;
647656

648-
engine->flags |= I915_ENGINE_NEEDS_BREADCRUMB_TASKLET;
649657
engine->flags |= I915_ENGINE_HAS_PREEMPTION;
650658

651659
/*
@@ -681,6 +689,7 @@ static void rcs_submission_override(struct intel_engine_cs *engine)
681689
static inline void guc_default_irqs(struct intel_engine_cs *engine)
682690
{
683691
engine->irq_keep_mask = GT_RENDER_USER_INTERRUPT;
692+
intel_engine_set_irq_handler(engine, cs_irq_handler);
684693
}
685694

686695
int intel_guc_submission_setup(struct intel_engine_cs *engine)

drivers/gpu/drm/i915/i915_irq.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3988,7 +3988,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
39883988
intel_uncore_write16(&dev_priv->uncore, GEN2_IIR, iir);
39893989

39903990
if (iir & I915_USER_INTERRUPT)
3991-
intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]);
3991+
intel_engine_cs_irq(dev_priv->gt.engine[RCS0], iir);
39923992

39933993
if (iir & I915_MASTER_ERROR_INTERRUPT)
39943994
i8xx_error_irq_handler(dev_priv, eir, eir_stuck);
@@ -4096,7 +4096,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
40964096
intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir);
40974097

40984098
if (iir & I915_USER_INTERRUPT)
4099-
intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]);
4099+
intel_engine_cs_irq(dev_priv->gt.engine[RCS0], iir);
41004100

41014101
if (iir & I915_MASTER_ERROR_INTERRUPT)
41024102
i9xx_error_irq_handler(dev_priv, eir, eir_stuck);
@@ -4241,10 +4241,12 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
42414241
intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir);
42424242

42434243
if (iir & I915_USER_INTERRUPT)
4244-
intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]);
4244+
intel_engine_cs_irq(dev_priv->gt.engine[RCS0],
4245+
iir);
42454246

42464247
if (iir & I915_BSD_USER_INTERRUPT)
4247-
intel_engine_signal_breadcrumbs(dev_priv->gt.engine[VCS0]);
4248+
intel_engine_cs_irq(dev_priv->gt.engine[VCS0],
4249+
iir >> 25);
42484250

42494251
if (iir & I915_MASTER_ERROR_INTERRUPT)
42504252
i9xx_error_irq_handler(dev_priv, eir, eir_stuck);

0 commit comments

Comments
 (0)