* [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT.
@ 2026-07-02 8:09 Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 1/7] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock() Maarten Lankhorst
` (7 more replies)
0 siblings, 8 replies; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst
All fixes to make the core i915 module (without display) working correctly on
PREEMPT_RT.
Some fixes are still needed, as the selftests still fail. But otherwise the
test results were looking good on PREEMPT_RT.
Maarten Lankhorst (3):
drm/i915/gt: Fix selftests on PREEMPT_RT
drm/i915/gt: Set stop_timeout() correctly on PREEMPT-RT
drm/i915: Use sleeping selftests for igt_atomic on PREEMPT_RT
Sebastian Andrzej Siewior (4):
drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() +
spin_lock()
drm/i915: Drop the irqs_disabled() check
drm/i915/guc: Consider also RCU depth in busy loop.
drm/i915/gt: Add a spinlock to prevent starvation of irq_work.
drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 8 +++++++-
.../gpu/drm/i915/gt/intel_breadcrumbs_types.h | 1 +
drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 +-
.../drm/i915/gt/intel_execlists_submission.c | 17 +++++------------
drivers/gpu/drm/i915/gt/selftest_engine_pm.c | 8 ++++----
drivers/gpu/drm/i915/gt/uc/intel_guc.h | 2 +-
drivers/gpu/drm/i915/i915_request.c | 2 --
drivers/gpu/drm/i915/selftests/igt_atomic.c | 7 +++++++
8 files changed, 26 insertions(+), 21 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/7] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock()
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
@ 2026-07-02 8:09 ` Maarten Lankhorst
2026-07-02 8:27 ` sashiko-bot
2026-07-02 8:09 ` [PATCH 2/7] drm/i915: Drop the irqs_disabled() check Maarten Lankhorst
` (6 subsequent siblings)
7 siblings, 1 reply; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx
Cc: dri-devel, Sebastian Andrzej Siewior, Clark Williams,
Maarten Lankhorst, Maarten Lankhorst
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
execlists_dequeue() is invoked from a function which uses
local_irq_disable() to disable interrupts so the spin_lock() behaves
like spin_lock_irq().
This breaks PREEMPT_RT because local_irq_disable() + spin_lock() is not
the same as spin_lock_irq().
execlists_dequeue_irq() and execlists_dequeue() has each one caller
only. If intel_engine_cs::active::lock is acquired and released with the
_irq suffix then it behaves almost as if execlists_dequeue() would be
invoked with disabled interrupts. The difference is the last part of the
function which is then invoked with enabled interrupts.
I can't tell if this makes a difference. From looking at it, it might
work to move the last unlock at the end of the function as I didn't find
anything that would acquire the lock again.
Reported-by: Clark Williams <williams@redhat.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
.../drm/i915/gt/intel_execlists_submission.c | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 1359fc9cb88ef..e11db81dca9c5 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -1300,7 +1300,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
* and context switches) submission.
*/
- spin_lock(&sched_engine->lock);
+ spin_lock_irq(&sched_engine->lock);
/*
* If the queue is higher priority than the last
@@ -1400,7 +1400,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
* Even if ELSP[1] is occupied and not worthy
* of timeslices, our queue might be.
*/
- spin_unlock(&sched_engine->lock);
+ spin_unlock_irq(&sched_engine->lock);
return;
}
}
@@ -1426,7 +1426,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
if (last && !can_merge_rq(last, rq)) {
spin_unlock(&ve->base.sched_engine->lock);
- spin_unlock(&engine->sched_engine->lock);
+ spin_unlock_irq(&engine->sched_engine->lock);
return; /* leave this for another sibling */
}
@@ -1588,7 +1588,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
*/
sched_engine->queue_priority_hint = queue_prio(sched_engine);
i915_sched_engine_reset_on_empty(sched_engine);
- spin_unlock(&sched_engine->lock);
+ spin_unlock_irq(&sched_engine->lock);
/*
* We can skip poking the HW if we ended up with exactly the same set
@@ -1614,13 +1614,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
}
}
-static void execlists_dequeue_irq(struct intel_engine_cs *engine)
-{
- local_irq_disable(); /* Suspend interrupts across request submission */
- execlists_dequeue(engine);
- local_irq_enable(); /* flush irq_work (e.g. breadcrumb enabling) */
-}
-
static void clear_ports(struct i915_request **ports, int count)
{
memset_p((void **)ports, NULL, count);
@@ -2475,7 +2468,7 @@ static void execlists_submission_tasklet(struct tasklet_struct *t)
}
if (!engine->execlists.pending[0]) {
- execlists_dequeue_irq(engine);
+ execlists_dequeue(engine);
start_timeslice(engine);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/7] drm/i915: Drop the irqs_disabled() check
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 1/7] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock() Maarten Lankhorst
@ 2026-07-02 8:09 ` Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 3/7] drm/i915/guc: Consider also RCU depth in busy loop Maarten Lankhorst
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx
Cc: dri-devel, Sebastian Andrzej Siewior, Maarten Lankhorst,
Tvrtko Ursulin, Maarten Lankhorst
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
The !irqs_disabled() check triggers on PREEMPT_RT even with
i915_sched_engine::lock acquired. The reason is the lock is transformed
into a sleeping lock on PREEMPT_RT and does not disable interrupts.
There is no need to check for disabled interrupts. The lockdep
annotation below already check if the lock has been acquired by the
caller and will yell if the interrupts are not disabled.
Remove the !irqs_disabled() check.
Reported-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
drivers/gpu/drm/i915/i915_request.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index d2c7b1090df08..f66f8efc70629 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -610,7 +610,6 @@ bool __i915_request_submit(struct i915_request *request)
RQ_TRACE(request, "\n");
- GEM_BUG_ON(!irqs_disabled());
lockdep_assert_held(&engine->sched_engine->lock);
/*
@@ -719,7 +718,6 @@ void __i915_request_unsubmit(struct i915_request *request)
*/
RQ_TRACE(request, "\n");
- GEM_BUG_ON(!irqs_disabled());
lockdep_assert_held(&engine->sched_engine->lock);
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/7] drm/i915/guc: Consider also RCU depth in busy loop.
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 1/7] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock() Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 2/7] drm/i915: Drop the irqs_disabled() check Maarten Lankhorst
@ 2026-07-02 8:09 ` Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 4/7] drm/i915/gt: Fix selftests on PREEMPT_RT Maarten Lankhorst
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx
Cc: dri-devel, Sebastian Andrzej Siewior, John B. Wyatt IV,
Rodrigo Vivi, Maarten Lankhorst
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
intel_guc_send_busy_loop() looks at in_atomic() and irqs_disabled() to
decide if it should busy-spin while waiting or if it may sleep.
Both checks will report false on PREEMPT_RT if sleeping spinlocks are
acquired leading to RCU splats while the function sleeps.
Check also if RCU has been disabled.
Reported-by: "John B. Wyatt IV" <jwyatt@redhat.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
drivers/gpu/drm/i915/gt/uc/intel_guc.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 053780f562c1a..b25fa8f4dc4bd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -362,7 +362,7 @@ static inline int intel_guc_send_busy_loop(struct intel_guc *guc,
{
int err;
unsigned int sleep_period_ms = 1;
- bool not_atomic = !in_atomic() && !irqs_disabled();
+ bool not_atomic = !in_atomic() && !irqs_disabled() && !rcu_preempt_depth();
/*
* FIXME: Have caller pass in if we are in an atomic context to avoid
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/7] drm/i915/gt: Fix selftests on PREEMPT_RT
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
` (2 preceding siblings ...)
2026-07-02 8:09 ` [PATCH 3/7] drm/i915/guc: Consider also RCU depth in busy loop Maarten Lankhorst
@ 2026-07-02 8:09 ` Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 5/7] drm/i915/gt: Set stop_timeout() correctly on PREEMPT-RT Maarten Lankhorst
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
drivers/gpu/drm/i915/gt/selftest_engine_pm.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
index 10e556a7eac45..c1eff9edd8a5e 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
@@ -277,11 +277,11 @@ static int live_engine_busy_stats(void *arg)
st_engine_heartbeat_disable(engine);
ENGINE_TRACE(engine, "measuring idle time\n");
- preempt_disable();
+ migrate_disable();
de = intel_engine_get_busy_time(engine, &t[0]);
udelay(100);
de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
- preempt_enable();
+ migrate_enable();
dt = ktime_sub(t[1], t[0]);
if (de < 0 || de > 10) {
pr_err("%s: reported %lldns [%d%%] busyness while sleeping [for %lldns]\n",
@@ -316,11 +316,11 @@ static int live_engine_busy_stats(void *arg)
}
ENGINE_TRACE(engine, "measuring busy time\n");
- preempt_disable();
+ migrate_disable();
de = intel_engine_get_busy_time(engine, &t[0]);
mdelay(100);
de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
- preempt_enable();
+ migrate_enable();
dt = ktime_sub(t[1], t[0]);
if (100 * de < 95 * dt || 95 * de > 100 * dt) {
pr_err("%s: reported %lldns [%d%%] busyness while spinning [for %lldns]\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/7] drm/i915/gt: Set stop_timeout() correctly on PREEMPT-RT
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
` (3 preceding siblings ...)
2026-07-02 8:09 ` [PATCH 4/7] drm/i915/gt: Fix selftests on PREEMPT_RT Maarten Lankhorst
@ 2026-07-02 8:09 ` Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 6/7] drm/i915: Use sleeping selftests for igt_atomic on PREEMPT_RT Maarten Lankhorst
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst
Also check if RCU is disabled for PREEMPT-RT, which is the case when
local_bh_disable() is called.
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index c0fd349a4600c..9dd9665128caa 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -1607,7 +1607,7 @@ u64 intel_engine_get_last_batch_head(const struct intel_engine_cs *engine)
static unsigned long stop_timeout(const struct intel_engine_cs *engine)
{
- if (in_atomic() || irqs_disabled()) /* inside atomic preempt-reset? */
+ if (in_atomic() || irqs_disabled() || rcu_preempt_depth()) /* inside atomic preempt-reset? */
return 0;
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/7] drm/i915: Use sleeping selftests for igt_atomic on PREEMPT_RT
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
` (4 preceding siblings ...)
2026-07-02 8:09 ` [PATCH 5/7] drm/i915/gt: Set stop_timeout() correctly on PREEMPT-RT Maarten Lankhorst
@ 2026-07-02 8:09 ` Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 7/7] drm/i915/gt: Add a spinlock to prevent starvation of irq_work Maarten Lankhorst
2026-07-02 12:42 ` ✗ i915.CI.BAT: failure for drm/i915: All fixes to make i915 work well with PREEMPT_RT Patchwork
7 siblings, 0 replies; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst
This makes the i915 selftests slightly happier, especially
related to GPU reset.
I believe this may be a better approach than trying to convert
uncore->lock to raw_spinlock
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
drivers/gpu/drm/i915/selftests/igt_atomic.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/i915/selftests/igt_atomic.c b/drivers/gpu/drm/i915/selftests/igt_atomic.c
index fb506b6990956..8ae39cf570b76 100644
--- a/drivers/gpu/drm/i915/selftests/igt_atomic.c
+++ b/drivers/gpu/drm/i915/selftests/igt_atomic.c
@@ -39,7 +39,14 @@ static void __hardirq_end(void)
local_irq_enable();
}
+static void __maybe_unused __nop(void)
+{}
+
const struct igt_atomic_section igt_atomic_phases[] = {
+#if IS_ENABLED(CONFIG_PREEMPT_RT)
+ { "sleeping", __nop, __nop },
+ { },
+#endif
{ "preempt", __preempt_begin, __preempt_end },
{ "softirq", __softirq_begin, __softirq_end },
{ "hardirq", __hardirq_begin, __hardirq_end },
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 7/7] drm/i915/gt: Add a spinlock to prevent starvation of irq_work.
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
` (5 preceding siblings ...)
2026-07-02 8:09 ` [PATCH 6/7] drm/i915: Use sleeping selftests for igt_atomic on PREEMPT_RT Maarten Lankhorst
@ 2026-07-02 8:09 ` Maarten Lankhorst
2026-07-02 8:24 ` sashiko-bot
2026-07-02 12:42 ` ✗ i915.CI.BAT: failure for drm/i915: All fixes to make i915 work well with PREEMPT_RT Patchwork
7 siblings, 1 reply; 11+ messages in thread
From: Maarten Lankhorst @ 2026-07-02 8:09 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel, Sebastian Andrzej Siewior, Maarten Lankhorst
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
IRQ-Work (FIFO-1) will be preempted by the threaded-interrupt (FIFO-50)
and the interrupt will poll on signaler_active while the irq-work can't
make progress.
Solve this by adding a spinlock to prevent starvation and force
completion.
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 8 +++++++-
drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index c10ac0ab3bfa8..c2b174bfa1418 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -209,6 +209,7 @@ static void signal_irq_work(struct irq_work *work)
intel_breadcrumbs_disarm_irq(b);
rcu_read_lock();
+ spin_lock(&b->signaler_active_sync);
atomic_inc(&b->signaler_active);
list_for_each_entry_rcu(ce, &b->signalers, signal_link) {
struct i915_request *rq;
@@ -246,6 +247,7 @@ static void signal_irq_work(struct irq_work *work)
}
}
atomic_dec(&b->signaler_active);
+ spin_unlock(&b->signaler_active_sync);
rcu_read_unlock();
llist_for_each_safe(signal, sn, signal) {
@@ -290,6 +292,7 @@ intel_breadcrumbs_create(struct intel_engine_cs *irq_engine)
init_llist_head(&b->signaled_requests);
spin_lock_init(&b->irq_lock);
+ spin_lock_init(&b->signaler_active_sync);
init_irq_work(&b->irq_work, signal_irq_work);
b->irq_engine = irq_engine;
@@ -487,8 +490,11 @@ void intel_context_remove_breadcrumbs(struct intel_context *ce,
if (release)
intel_context_put(ce);
- while (atomic_read(&b->signaler_active))
+ while (atomic_read(&b->signaler_active)) {
+ spin_lock(&b->signaler_active_sync);
+ spin_unlock(&b->signaler_active_sync);
cpu_relax();
+ }
}
static void print_signals(struct intel_breadcrumbs *b, struct drm_printer *p)
diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h
index bdf09fd67b6e7..28dae32628aab 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h
@@ -40,6 +40,7 @@ struct intel_breadcrumbs {
struct list_head signalers;
struct llist_head signaled_requests;
atomic_t signaler_active;
+ spinlock_t signaler_active_sync;
spinlock_t irq_lock; /* protects the interrupt from hardirq context */
struct irq_work irq_work; /* for use from inside irq_lock */
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 7/7] drm/i915/gt: Add a spinlock to prevent starvation of irq_work.
2026-07-02 8:09 ` [PATCH 7/7] drm/i915/gt: Add a spinlock to prevent starvation of irq_work Maarten Lankhorst
@ 2026-07-02 8:24 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-02 8:24 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Acquiring `b->signaler_active_sync` with `spin_lock()` in `intel_context_remove_breadcrumbs()` without disabling interrupts creates a deadlock vulnerability and Lockdep splat on non-RT kernels.
--
commit b2f8f390d7421e899486c8f32c2c91c29a783338
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
drm/i915/gt: Add a spinlock to prevent starvation of irq_work.
This commit introduces a new spinlock, signaler_active_sync, to prevent
starvation of irq-work. It acquires this lock in both signal_irq_work()
and intel_context_remove_breadcrumbs() to force completion and synchronize
signaler state.
> diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> @@ -209,6 +209,7 @@ static void signal_irq_work(struct irq_work *work)
> intel_breadcrumbs_disarm_irq(b);
>
> rcu_read_lock();
> + spin_lock(&b->signaler_active_sync);
> atomic_inc(&b->signaler_active);
> list_for_each_entry_rcu(ce, &b->signalers, signal_link) {
[ ... ]
> @@ -487,8 +490,11 @@ void intel_context_remove_breadcrumbs(struct intel_context *ce,
> if (release)
> intel_context_put(ce);
>
> - while (atomic_read(&b->signaler_active))
> + while (atomic_read(&b->signaler_active)) {
> + spin_lock(&b->signaler_active_sync);
> + spin_unlock(&b->signaler_active_sync);
[Severity: High]
Can this cause a deadlock on non-RT kernels?
Because signal_irq_work() runs in hardirq context as an irq_work callback,
acquiring signaler_active_sync here in intel_context_remove_breadcrumbs()
without disabling interrupts creates a window for a self-deadlock.
If a hardware interrupt occurs on the same CPU while this spinlock is
momentarily held, the local irq_work will trigger and signal_irq_work()
will try to acquire the already-held lock. Lockdep will also flag this as
an inconsistent lock state (HARDIRQ-ON-W vs IN-HARDIRQ-W) on its first
execution.
Does this need to use spin_lock_irq() or spin_lock_irqsave() to safely
synchronize against the irq_work?
> cpu_relax();
> + }
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702080913.434121-1-dev@lankhorst.se?part=7
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/7] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock()
2026-07-02 8:09 ` [PATCH 1/7] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock() Maarten Lankhorst
@ 2026-07-02 8:27 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-02 8:27 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Request submission to the ELSP hardware is executed with interrupts enabled, violating hardware constraints for tightly packed MMIO sequences and risking GPU hangs.
--
commit 03bdcff0829362b8c38fdcf058920884f728b511
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock()
This commit replaces the local_irq_disable() wrapper around
execlists_dequeue() with spin_lock_irq() inside the function, to resolve a
PREEMPT_RT incompatibility.
> diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> index 1359fc9cb88ef..e11db81dca9c5 100644
> --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
[ ... ]
> @@ -1588,7 +1588,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> */
> sched_engine->queue_priority_hint = queue_prio(sched_engine);
> i915_sched_engine_reset_on_empty(sched_engine);
> - spin_unlock(&sched_engine->lock);
> + spin_unlock_irq(&sched_engine->lock);
>
> /*
> * We can skip poking the HW if we ended up with exactly the same set
> @@ -1614,13 +1614,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> }
> }
>
> -static void execlists_dequeue_irq(struct intel_engine_cs *engine)
> -{
> - local_irq_disable(); /* Suspend interrupts across request submission */
> - execlists_dequeue(engine);
> - local_irq_enable(); /* flush irq_work (e.g. breadcrumb enabling) */
> -}
[Severity: High]
Does removing the local_irq_disable() wrapper leave the hardware submission
sequence exposed to interruptions?
In the original code, local_irq_disable() inside execlists_dequeue_irq()
protected the entire execlists_dequeue() function. Now that
spin_unlock_irq() is used instead, interrupts are re-enabled before the
function finishes:
spin_unlock_irq(&sched_engine->lock);
/* ... */
if (submit && ...) {
/* ... */
execlists_submit_ports(engine);
}
Because interrupts are now enabled prior to calling execlists_submit_ports(),
an interrupt or thread preemption event could occur during the ELSP MMIO
writes. Since the ELSP hardware requires tightly packed writes without
excessive delays, could this interruption cause a hardware state machine
timeout and result in a GPU hang?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702080913.434121-1-dev@lankhorst.se?part=1
^ permalink raw reply [flat|nested] 11+ messages in thread
* ✗ i915.CI.BAT: failure for drm/i915: All fixes to make i915 work well with PREEMPT_RT.
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
` (6 preceding siblings ...)
2026-07-02 8:09 ` [PATCH 7/7] drm/i915/gt: Add a spinlock to prevent starvation of irq_work Maarten Lankhorst
@ 2026-07-02 12:42 ` Patchwork
7 siblings, 0 replies; 11+ messages in thread
From: Patchwork @ 2026-07-02 12:42 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
[-- Attachment #1: Type: text/plain, Size: 3694 bytes --]
== Series Details ==
Series: drm/i915: All fixes to make i915 work well with PREEMPT_RT.
URL : https://patchwork.freedesktop.org/series/169677/
State : failure
== Summary ==
CI Bug Log - changes from CI_DRM_18751 -> Patchwork_169677v1
====================================================
Summary
-------
**FAILURE**
Serious unknown changes coming with Patchwork_169677v1 absolutely need to be
verified manually.
If you think the reported changes have nothing to do with the changes
introduced in Patchwork_169677v1, please notify your bug team (I915-ci-infra@lists.freedesktop.org) to allow them
to document this new failure mode, which will reduce false positives in CI.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/index.html
Participating hosts (42 -> 39)
------------------------------
Missing (3): bat-dg2-13 fi-bsw-nick fi-snb-2520m
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in Patchwork_169677v1:
### IGT changes ###
#### Possible regressions ####
* igt@i915_selftest@live:
- bat-adls-6: [PASS][1] -> [ABORT][2] +1 other test abort
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18751/bat-adls-6/igt@i915_selftest@live.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/bat-adls-6/igt@i915_selftest@live.html
- fi-kbl-7567u: [PASS][3] -> [ABORT][4] +1 other test abort
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18751/fi-kbl-7567u/igt@i915_selftest@live.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/fi-kbl-7567u/igt@i915_selftest@live.html
- fi-cfl-8109u: [PASS][5] -> [ABORT][6] +1 other test abort
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18751/fi-cfl-8109u/igt@i915_selftest@live.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/fi-cfl-8109u/igt@i915_selftest@live.html
* igt@i915_selftest@live@execlists:
- bat-kbl-2: [PASS][7] -> [ABORT][8] +1 other test abort
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18751/bat-kbl-2/igt@i915_selftest@live@execlists.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/bat-kbl-2/igt@i915_selftest@live@execlists.html
Known issues
------------
Here are the changes found in Patchwork_169677v1 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@dmabuf@all-tests:
- bat-arlh-2: NOTRUN -> [SKIP][9] ([i915#11346] / [i915#15931])
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/bat-arlh-2/igt@dmabuf@all-tests.html
#### Possible fixes ####
* igt@i915_selftest@live@perf:
- bat-arlh-2: [INCOMPLETE][10] -> [PASS][11] +1 other test pass
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_18751/bat-arlh-2/igt@i915_selftest@live@perf.html
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/bat-arlh-2/igt@i915_selftest@live@perf.html
[i915#11346]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/11346
[i915#15931]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15931
Build changes
-------------
* Linux: CI_DRM_18751 -> Patchwork_169677v1
CI-20190529: 20190529
CI_DRM_18751: 4343c63c6acc14ed4d48dddaa56057663651d9e3 @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_8989: a8e2cbd2854d7980a9eccecc6e0c801d0824b88f @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
Patchwork_169677v1: 4343c63c6acc14ed4d48dddaa56057663651d9e3 @ git://anongit.freedesktop.org/gfx-ci/linux
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_169677v1/index.html
[-- Attachment #2: Type: text/html, Size: 4397 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-07-02 12:42 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02 8:09 [PATCH 0/7] drm/i915: All fixes to make i915 work well with PREEMPT_RT Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 1/7] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock() Maarten Lankhorst
2026-07-02 8:27 ` sashiko-bot
2026-07-02 8:09 ` [PATCH 2/7] drm/i915: Drop the irqs_disabled() check Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 3/7] drm/i915/guc: Consider also RCU depth in busy loop Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 4/7] drm/i915/gt: Fix selftests on PREEMPT_RT Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 5/7] drm/i915/gt: Set stop_timeout() correctly on PREEMPT-RT Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 6/7] drm/i915: Use sleeping selftests for igt_atomic on PREEMPT_RT Maarten Lankhorst
2026-07-02 8:09 ` [PATCH 7/7] drm/i915/gt: Add a spinlock to prevent starvation of irq_work Maarten Lankhorst
2026-07-02 8:24 ` sashiko-bot
2026-07-02 12:42 ` ✗ i915.CI.BAT: failure for drm/i915: All fixes to make i915 work well with PREEMPT_RT Patchwork
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.