summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0029-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0029-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch')
-rw-r--r--debian/patches-rt/0029-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch95
1 files changed, 95 insertions, 0 deletions
diff --git a/debian/patches-rt/0029-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch b/debian/patches-rt/0029-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch
new file mode 100644
index 000000000..d7696f54a
--- /dev/null
+++ b/debian/patches-rt/0029-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch
@@ -0,0 +1,95 @@
+From 6ca6d59038e0a61a7bb4904310525b1df57a2867 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 8 Sep 2021 19:03:41 +0200
+Subject: [PATCH 29/62] drm/i915/gt: Use spin_lock_irq() instead of
+ local_irq_disable() + spin_lock()
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.1/older/patches-6.1.69-rt21.tar.xz
+
+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>
+---
+ .../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 f903ee1ce06e..f54059b63ea9 100644
+--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
++++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+@@ -1302,7 +1302,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
+@@ -1402,7 +1402,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;
+ }
+ }
+@@ -1428,7 +1428,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 */
+ }
+
+@@ -1590,7 +1590,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
+@@ -1616,13 +1616,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);
+@@ -2476,7 +2469,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.43.0
+