summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_drv.h
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-04-27 13:41:16 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-05-20 11:25:46 +0200
commitb2cfe0ab63ad2de90a72ae6e5c05d05600f8c144 (patch)
tree7b47121a58fefbee057016d2f739445b9899b412 /drivers/gpu/drm/i915/i915_drv.h
parentd94b5030d26b4f45510a092262bc2b542a00bd7c (diff)
downloadlwn-b2cfe0ab63ad2de90a72ae6e5c05d05600f8c144.tar.gz
lwn-b2cfe0ab63ad2de90a72ae6e5c05d05600f8c144.zip
drm/i915: Fix race on unreferencing the wrong mmio-flip-request
As we perform the mmio-flip without any locking and then try to acquire the struct_mutex prior to dereferencing the request, it is possible for userspace to queue a new pageflip before the worker can finish clearing the old state - and then it will clear the new flip request. The result is that the new flip could be completed before the GPU has finished rendering. The bugs stems from removing the seqno checking in commit 536f5b5e86b225dab94c7ff8061ae482b6077387 Author: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Date: Thu Nov 6 11:03:40 2014 +0200 drm/i915: Make mmio flip wait for seqno in the work function Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.h')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1b539057b264..6a66d6b7d33b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2161,10 +2161,12 @@ i915_gem_request_get_ring(struct drm_i915_gem_request *req)
return req ? req->ring : NULL;
}
-static inline void
+static inline struct drm_i915_gem_request *
i915_gem_request_reference(struct drm_i915_gem_request *req)
{
- kref_get(&req->ref);
+ if (req)
+ kref_get(&req->ref);
+ return req;
}
static inline void