diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-14 07:57:08 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-01-29 12:23:37 -0500 |
commit | 1690e1eb7a9021826853e181baa48dd77090da28 (patch) | |
tree | 397210ab6f278ca81b8108320768b39465db6d08 /drivers/gpu/drm/i915/intel_display.c | |
parent | 6a233c78878d8795517d716544d045d5675b3061 (diff) |
drm/i915: Separate fence pin counting from normal bind pin counting
In order to correctly account for reserving space in the GTT and fences
for a batch buffer, we need to independently track whether the fence is
pinned due to a fenced GPU access in the batch or whether the buffer is
pinned in the aperture. Currently we count the fenced as pinned if the
buffer has already been seen in the execbuffer. This leads to a false
accounting of available fence registers, causing frequent mass evictions.
Worse, if coupled with the change to make i915_gem_object_get_fence()
report EDADLK upon fence starvation, the batchbuffer can fail with only
one fence required...
Fixes intel-gpu-tools/tests/gem_fenced_exec_thrash
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38735
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Tested-by: Paul Neumann <paul104x@yahoo.de>
[danvet: Resolve the functional conflict with Jesse Barnes sprite
patches, acked by Chris Wilson on irc.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0770671fa8af..fc9bc19f6db9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2041,6 +2041,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
2041 | ret = i915_gem_object_get_fence(obj, pipelined); | 2041 | ret = i915_gem_object_get_fence(obj, pipelined); |
2042 | if (ret) | 2042 | if (ret) |
2043 | goto err_unpin; | 2043 | goto err_unpin; |
2044 | |||
2045 | i915_gem_object_pin_fence(obj); | ||
2044 | } | 2046 | } |
2045 | 2047 | ||
2046 | dev_priv->mm.interruptible = true; | 2048 | dev_priv->mm.interruptible = true; |
@@ -2053,6 +2055,12 @@ err_interruptible: | |||
2053 | return ret; | 2055 | return ret; |
2054 | } | 2056 | } |
2055 | 2057 | ||
2058 | void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) | ||
2059 | { | ||
2060 | i915_gem_object_unpin_fence(obj); | ||
2061 | i915_gem_object_unpin(obj); | ||
2062 | } | ||
2063 | |||
2056 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 2064 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
2057 | int x, int y) | 2065 | int x, int y) |
2058 | { | 2066 | { |
@@ -2284,7 +2292,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2284 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, | 2292 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, |
2285 | LEAVE_ATOMIC_MODE_SET); | 2293 | LEAVE_ATOMIC_MODE_SET); |
2286 | if (ret) { | 2294 | if (ret) { |
2287 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | 2295 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
2288 | mutex_unlock(&dev->struct_mutex); | 2296 | mutex_unlock(&dev->struct_mutex); |
2289 | DRM_ERROR("failed to update base address\n"); | 2297 | DRM_ERROR("failed to update base address\n"); |
2290 | return ret; | 2298 | return ret; |
@@ -2292,7 +2300,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2292 | 2300 | ||
2293 | if (old_fb) { | 2301 | if (old_fb) { |
2294 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 2302 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
2295 | i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); | 2303 | intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); |
2296 | } | 2304 | } |
2297 | 2305 | ||
2298 | mutex_unlock(&dev->struct_mutex); | 2306 | mutex_unlock(&dev->struct_mutex); |
@@ -3355,7 +3363,7 @@ static void intel_crtc_disable(struct drm_crtc *crtc) | |||
3355 | 3363 | ||
3356 | if (crtc->fb) { | 3364 | if (crtc->fb) { |
3357 | mutex_lock(&dev->struct_mutex); | 3365 | mutex_lock(&dev->struct_mutex); |
3358 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | 3366 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
3359 | mutex_unlock(&dev->struct_mutex); | 3367 | mutex_unlock(&dev->struct_mutex); |
3360 | } | 3368 | } |
3361 | } | 3369 | } |
@@ -7158,7 +7166,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) | |||
7158 | container_of(__work, struct intel_unpin_work, work); | 7166 | container_of(__work, struct intel_unpin_work, work); |
7159 | 7167 | ||
7160 | mutex_lock(&work->dev->struct_mutex); | 7168 | mutex_lock(&work->dev->struct_mutex); |
7161 | i915_gem_object_unpin(work->old_fb_obj); | 7169 | intel_unpin_fb_obj(work->old_fb_obj); |
7162 | drm_gem_object_unreference(&work->pending_flip_obj->base); | 7170 | drm_gem_object_unreference(&work->pending_flip_obj->base); |
7163 | drm_gem_object_unreference(&work->old_fb_obj->base); | 7171 | drm_gem_object_unreference(&work->old_fb_obj->base); |
7164 | 7172 | ||