summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_breadcrumbs.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-11-11 09:25:32 +1000
committerDave Airlie <airlied@redhat.com>2016-11-11 09:25:32 +1000
commitdb8feb6979e91c2e916631a75dbfe9f10f6b05e5 (patch)
treeb4aa5965f207c18d908a794e5f4e647604d77553 /drivers/gpu/drm/i915/intel_breadcrumbs.c
parentafdd548f742ca454fc343696de472f3aaa5dc488 (diff)
parent58e197d631d44f9f4817b8198b43132a40de1164 (diff)
Merge tag 'drm-intel-next-2016-11-08' of git://anongit.freedesktop.org/git/drm-intel into drm-next
- gpu idling rework for s/r (Imre) - vlv mappable scanout fix - speed up probing in resume (Lyude) - dp audio workarounds for gen9 (Dhinakaran) - more conversion to using dev_priv internally (Ville) - more gen9+ wm fixes and cleanups (Maarten) - shrinker cleanup&fixes (Chris) - reorg plane init code (Ville) - implement support for multiple timelines (prep work for scheduler) from Chris and all - untangle dev->struct_mutex locking as prep for multiple timelines (Chris) - refactor bxt phy code and collect it all in intel_dpio_phy.c (Ander) - another gvt with bugfixes all over from Zhenyu - piles of lspcon fixes from Imre - 90/270 rotation fixes (Ville) - guc log buffer support (Akash+Sagar) - fbc fixes from Paulo - untangle rpm vs. tiling-fences/mmaps (Chris) - fix atomic commit to wait on the right fences (Daniel Stone) * tag 'drm-intel-next-2016-11-08' of git://anongit.freedesktop.org/git/drm-intel: (181 commits) drm/i915: Update DRIVER_DATE to 20161108 drm/i915: Mark CPU cache as dirty when used for rendering drm/i915: Add assert for no pending GPU requests during suspend/resume in LR mode drm/i915: Make sure engines are idle during GPU idling in LR mode drm/i915: Avoid early GPU idling due to race with new request drm/i915: Avoid early GPU idling due to already pending idle work drm/i915: Limit Valleyview and earlier to only using mappable scanout drm/i915: Round tile chunks up for constructing partial VMAs drm/i915: Remove the vma from the object list upon close drm/i915: Reinit polling before hpd when resuming drm/i915: Remove redundant reprobe in i915_drm_resume drm/i915/dp: Extend BDW DP audio workaround to GEN9 platforms drm/i915/dp: BDW cdclk fix for DP audio drm/i915: Fix pages pin counting around swizzle quirk drm/i915: Fix test on inputs for vma_compare() drm/i915/guc: Cache the client mapping drm/i915: Tidy slab cache allocations drm/i915: Introduce HAS_64BIT_RELOC drm/i915: Show the execlist queue in debugfs/i915_engine_info drm/i915: Unify global_list into global_link ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_breadcrumbs.c')
-rw-r--r--drivers/gpu/drm/i915/intel_breadcrumbs.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 56efcc507ea2..c410d3d6465f 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -83,16 +83,18 @@ static void irq_enable(struct intel_engine_cs *engine)
*/
engine->breadcrumbs.irq_posted = true;
- spin_lock_irq(&engine->i915->irq_lock);
+ /* Caller disables interrupts */
+ spin_lock(&engine->i915->irq_lock);
engine->irq_enable(engine);
- spin_unlock_irq(&engine->i915->irq_lock);
+ spin_unlock(&engine->i915->irq_lock);
}
static void irq_disable(struct intel_engine_cs *engine)
{
- spin_lock_irq(&engine->i915->irq_lock);
+ /* Caller disables interrupts */
+ spin_lock(&engine->i915->irq_lock);
engine->irq_disable(engine);
- spin_unlock_irq(&engine->i915->irq_lock);
+ spin_unlock(&engine->i915->irq_lock);
engine->breadcrumbs.irq_posted = false;
}
@@ -293,9 +295,9 @@ bool intel_engine_add_wait(struct intel_engine_cs *engine,
struct intel_breadcrumbs *b = &engine->breadcrumbs;
bool first;
- spin_lock(&b->lock);
+ spin_lock_irq(&b->lock);
first = __intel_engine_add_wait(engine, wait);
- spin_unlock(&b->lock);
+ spin_unlock_irq(&b->lock);
return first;
}
@@ -326,7 +328,7 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine,
if (RB_EMPTY_NODE(&wait->node))
return;
- spin_lock(&b->lock);
+ spin_lock_irq(&b->lock);
if (RB_EMPTY_NODE(&wait->node))
goto out_unlock;
@@ -400,7 +402,7 @@ out_unlock:
GEM_BUG_ON(rb_first(&b->waiters) !=
(b->first_wait ? &b->first_wait->node : NULL));
GEM_BUG_ON(!rcu_access_pointer(b->irq_seqno_bh) ^ RB_EMPTY_ROOT(&b->waiters));
- spin_unlock(&b->lock);
+ spin_unlock_irq(&b->lock);
}
static bool signal_complete(struct drm_i915_gem_request *request)
@@ -473,14 +475,14 @@ static int intel_breadcrumbs_signaler(void *arg)
* we just completed - so double check we are still
* the oldest before picking the next one.
*/
- spin_lock(&b->lock);
+ spin_lock_irq(&b->lock);
if (request == b->first_signal) {
struct rb_node *rb =
rb_next(&request->signaling.node);
b->first_signal = rb ? to_signaler(rb) : NULL;
}
rb_erase(&request->signaling.node, &b->signals);
- spin_unlock(&b->lock);
+ spin_unlock_irq(&b->lock);
i915_gem_request_put(request);
} else {
@@ -502,11 +504,20 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
struct rb_node *parent, **p;
bool first, wakeup;
- /* locked by dma_fence_enable_sw_signaling() */
+ /* Note that we may be called from an interrupt handler on another
+ * device (e.g. nouveau signaling a fence completion causing us
+ * to submit a request, and so enable signaling). As such,
+ * we need to make sure that all other users of b->lock protect
+ * against interrupts, i.e. use spin_lock_irqsave.
+ */
+
+ /* locked by dma_fence_enable_sw_signaling() (irqsafe fence->lock) */
assert_spin_locked(&request->lock);
+ if (!request->global_seqno)
+ return;
request->signaling.wait.tsk = b->signaler;
- request->signaling.wait.seqno = request->fence.seqno;
+ request->signaling.wait.seqno = request->global_seqno;
i915_gem_request_get(request);
spin_lock(&b->lock);
@@ -530,8 +541,8 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
p = &b->signals.rb_node;
while (*p) {
parent = *p;
- if (i915_seqno_passed(request->fence.seqno,
- to_signaler(parent)->fence.seqno)) {
+ if (i915_seqno_passed(request->global_seqno,
+ to_signaler(parent)->global_seqno)) {
p = &parent->rb_right;
first = false;
} else {
@@ -592,7 +603,7 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
struct intel_breadcrumbs *b = &engine->breadcrumbs;
cancel_fake_irq(engine);
- spin_lock(&b->lock);
+ spin_lock_irq(&b->lock);
__intel_breadcrumbs_disable_irq(b);
if (intel_engine_has_waiter(engine)) {
@@ -605,7 +616,7 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
irq_disable(engine);
}
- spin_unlock(&b->lock);
+ spin_unlock_irq(&b->lock);
}
void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)