summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_drv.h
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/i915_drv.h
parent7ec2c73b1dbe1cd83c52e4a386b2070331c5414c (diff)
downloadlwn-3d5564e91025bd17d93d0a23ebf8e22309652591.tar.gz
lwn-3d5564e91025bd17d93d0a23ebf8e22309652591.zip
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/i915_drv.h')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ee04bd40a41a..21181a6ec0b0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -4005,7 +4005,20 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req)
* but it is easier and safer to do it every time the waiter
* is woken.
*/
- if (engine->irq_seqno_barrier) {
+ if (engine->irq_seqno_barrier &&
+ cmpxchg_relaxed(&engine->irq_posted, 1, 0)) {
+ /* The ordering of irq_posted versus applying the barrier
+ * is crucial. The clearing of the current irq_posted must
+ * be visible before we perform the barrier operation,
+ * such that if a subsequent interrupt arrives, irq_posted
+ * is reasserted and our task rewoken (which causes us to
+ * do another __i915_request_irq_complete() immediately
+ * and reapply the barrier). Conversely, if the clear
+ * occurs after the barrier, then an interrupt that arrived
+ * whilst we waited on the barrier would not trigger a
+ * barrier on the next pass, and the read may not see the
+ * seqno update.
+ */
engine->irq_seqno_barrier(engine);
if (i915_gem_request_completed(req))
return true;