summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_breadcrumbs.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-07-01 17:23:23 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2016-07-01 21:00:54 +0100
commit3d5564e91025bd17d93d0a23ebf8e22309652591 (patch)
treecc05b709edc9aa5dee158b2a28631de5f8c35ae2 /drivers/gpu/drm/i915/intel_breadcrumbs.c
parent7ec2c73b1dbe1cd83c52e4a386b2070331c5414c (diff)
drm/i915: Only apply one barrier after a breadcrumb interrupt is posted
If we flag the seqno as potentially stale upon receiving an interrupt, we can use that information to reduce the frequency that we apply the heavyweight coherent seqno read (i.e. if we wake up a chain of waiters). v2: Use cmpxchg to replace READ_ONCE/WRITE_ONCE for more explicit control of the ordering wrt to interrupt generation and interrupt checking in the bottom-half. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-14-git-send-email-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/intel_breadcrumbs.c')
-rw-r--r--drivers/gpu/drm/i915/intel_breadcrumbs.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 7cdb02d18c1f..85ef6c0e2913 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -43,12 +43,18 @@ static void intel_breadcrumbs_fake_irq(unsigned long data)
static void irq_enable(struct intel_engine_cs *engine)
{
+ /* Enabling the IRQ may miss the generation of the interrupt, but
+ * we still need to force the barrier before reading the seqno,
+ * just in case.
+ */
+ engine->irq_posted = true;
WARN_ON(!engine->irq_get(engine));
}
static void irq_disable(struct intel_engine_cs *engine)
{
engine->irq_put(engine);
+ engine->irq_posted = false;
}
static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b)
@@ -56,7 +62,6 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b)
struct intel_engine_cs *engine =
container_of(b, struct intel_engine_cs, breadcrumbs);
struct drm_i915_private *i915 = engine->i915;
- bool irq_posted = false;
assert_spin_locked(&b->lock);
if (b->rpm_wakelock)
@@ -72,10 +77,8 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b)
/* No interrupts? Kick the waiter every jiffie! */
if (intel_irqs_enabled(i915)) {
- if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) {
+ if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings))
irq_enable(engine);
- irq_posted = true;
- }
b->irq_enabled = true;
}
@@ -83,7 +86,7 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b)
test_bit(engine->id, &i915->gpu_error.missed_irq_rings))
mod_timer(&b->fake_irq, jiffies + 1);
- return irq_posted;
+ return engine->irq_posted;
}
static void __intel_breadcrumbs_disable_irq(struct intel_breadcrumbs *b)
@@ -207,7 +210,8 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine,
* in case the seqno passed.
*/
__intel_breadcrumbs_enable_irq(b);
- wake_up_process(to_wait(next)->tsk);
+ if (READ_ONCE(engine->irq_posted))
+ wake_up_process(to_wait(next)->tsk);
}
do {