diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_evict.c | 42 |
3 files changed, 25 insertions, 40 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ec582b6d2113..54e5b2fa5fd4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1073,8 +1073,8 @@ void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); | |||
1073 | /* i915_gem_evict.c */ | 1073 | /* i915_gem_evict.c */ |
1074 | int i915_gem_evict_something(struct drm_device *dev, int min_size, | 1074 | int i915_gem_evict_something(struct drm_device *dev, int min_size, |
1075 | unsigned alignment, bool mappable); | 1075 | unsigned alignment, bool mappable); |
1076 | int i915_gem_evict_everything(struct drm_device *dev); | 1076 | int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only); |
1077 | int i915_gem_evict_inactive(struct drm_device *dev); | 1077 | int i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only); |
1078 | 1078 | ||
1079 | /* i915_gem_tiling.c */ | 1079 | /* i915_gem_tiling.c */ |
1080 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 1080 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e3fc333e2e57..c8e516d3f8bc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3519,7 +3519,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, | |||
3519 | int ret, i, retry; | 3519 | int ret, i, retry; |
3520 | 3520 | ||
3521 | /* attempt to pin all of the buffers into the GTT */ | 3521 | /* attempt to pin all of the buffers into the GTT */ |
3522 | for (retry = 0; retry < 2; retry++) { | 3522 | retry = 0; |
3523 | do { | ||
3523 | ret = 0; | 3524 | ret = 0; |
3524 | for (i = 0; i < count; i++) { | 3525 | for (i = 0; i < count; i++) { |
3525 | struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; | 3526 | struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; |
@@ -3567,18 +3568,18 @@ i915_gem_execbuffer_pin(struct drm_device *dev, | |||
3567 | while (i--) | 3568 | while (i--) |
3568 | i915_gem_object_unpin(object_list[i]); | 3569 | i915_gem_object_unpin(object_list[i]); |
3569 | 3570 | ||
3570 | if (ret == 0) | 3571 | if (ret != -ENOSPC || retry > 1) |
3571 | break; | ||
3572 | |||
3573 | if (ret != -ENOSPC || retry) | ||
3574 | return ret; | 3572 | return ret; |
3575 | 3573 | ||
3576 | ret = i915_gem_evict_everything(dev); | 3574 | /* First attempt, just clear anything that is purgeable. |
3575 | * Second attempt, clear the entire GTT. | ||
3576 | */ | ||
3577 | ret = i915_gem_evict_everything(dev, retry == 0); | ||
3577 | if (ret) | 3578 | if (ret) |
3578 | return ret; | 3579 | return ret; |
3579 | } | ||
3580 | 3580 | ||
3581 | return 0; | 3581 | retry++; |
3582 | } while (1); | ||
3582 | } | 3583 | } |
3583 | 3584 | ||
3584 | /* Throttle our rendering by waiting until the ring has completed our requests | 3585 | /* Throttle our rendering by waiting until the ring has completed our requests |
@@ -4484,7 +4485,7 @@ i915_gem_idle(struct drm_device *dev) | |||
4484 | 4485 | ||
4485 | /* Under UMS, be paranoid and evict. */ | 4486 | /* Under UMS, be paranoid and evict. */ |
4486 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 4487 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
4487 | ret = i915_gem_evict_inactive(dev); | 4488 | ret = i915_gem_evict_inactive(dev, false); |
4488 | if (ret) { | 4489 | if (ret) { |
4489 | mutex_unlock(&dev->struct_mutex); | 4490 | mutex_unlock(&dev->struct_mutex); |
4490 | return ret; | 4491 | return ret; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 3a4215f31652..a2609c5542fd 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -42,7 +42,7 @@ mark_free(struct drm_i915_gem_object *obj_priv, | |||
42 | 42 | ||
43 | int | 43 | int |
44 | i915_gem_evict_something(struct drm_device *dev, int min_size, | 44 | i915_gem_evict_something(struct drm_device *dev, int min_size, |
45 | unsigned alignment, bool mappable) | 45 | unsigned alignment, bool mappable) |
46 | { | 46 | { |
47 | drm_i915_private_t *dev_priv = dev->dev_private; | 47 | drm_i915_private_t *dev_priv = dev->dev_private; |
48 | struct list_head eviction_list, unwind_list; | 48 | struct list_head eviction_list, unwind_list; |
@@ -54,7 +54,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, | |||
54 | /* Re-check for free space after retiring requests */ | 54 | /* Re-check for free space after retiring requests */ |
55 | if (mappable) { | 55 | if (mappable) { |
56 | if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, | 56 | if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, |
57 | min_size, alignment, 0, | 57 | min_size, alignment, 0, |
58 | dev_priv->mm.gtt_mappable_end, | 58 | dev_priv->mm.gtt_mappable_end, |
59 | 0)) | 59 | 0)) |
60 | return 0; | 60 | return 0; |
@@ -171,7 +171,7 @@ found: | |||
171 | } | 171 | } |
172 | 172 | ||
173 | int | 173 | int |
174 | i915_gem_evict_everything(struct drm_device *dev) | 174 | i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) |
175 | { | 175 | { |
176 | drm_i915_private_t *dev_priv = dev->dev_private; | 176 | drm_i915_private_t *dev_priv = dev->dev_private; |
177 | int ret; | 177 | int ret; |
@@ -192,38 +192,22 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
192 | 192 | ||
193 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 193 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); |
194 | 194 | ||
195 | ret = i915_gem_evict_inactive(dev); | 195 | return i915_gem_evict_inactive(dev, purgeable_only); |
196 | if (ret) | ||
197 | return ret; | ||
198 | |||
199 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
200 | list_empty(&dev_priv->mm.flushing_list) && | ||
201 | list_empty(&dev_priv->render_ring.active_list) && | ||
202 | list_empty(&dev_priv->bsd_ring.active_list) && | ||
203 | list_empty(&dev_priv->blt_ring.active_list)); | ||
204 | BUG_ON(!lists_empty); | ||
205 | |||
206 | return 0; | ||
207 | } | 196 | } |
208 | 197 | ||
209 | /** Unbinds all inactive objects. */ | 198 | /** Unbinds all inactive objects. */ |
210 | int | 199 | int |
211 | i915_gem_evict_inactive(struct drm_device *dev) | 200 | i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only) |
212 | { | 201 | { |
213 | drm_i915_private_t *dev_priv = dev->dev_private; | 202 | drm_i915_private_t *dev_priv = dev->dev_private; |
214 | 203 | struct drm_i915_gem_object *obj, *next; | |
215 | while (!list_empty(&dev_priv->mm.inactive_list)) { | 204 | |
216 | struct drm_gem_object *obj; | 205 | list_for_each_entry_safe(obj, next, |
217 | int ret; | 206 | &dev_priv->mm.inactive_list, mm_list) { |
218 | 207 | if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) { | |
219 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | 208 | int ret = i915_gem_object_unbind(&obj->base); |
220 | struct drm_i915_gem_object, | 209 | if (ret) |
221 | mm_list)->base; | 210 | return ret; |
222 | |||
223 | ret = i915_gem_object_unbind(obj); | ||
224 | if (ret != 0) { | ||
225 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
226 | return ret; | ||
227 | } | 211 | } |
228 | } | 212 | } |
229 | 213 | ||