aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c19
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c42
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 */
1074int i915_gem_evict_something(struct drm_device *dev, int min_size, 1074int i915_gem_evict_something(struct drm_device *dev, int min_size,
1075 unsigned alignment, bool mappable); 1075 unsigned alignment, bool mappable);
1076int i915_gem_evict_everything(struct drm_device *dev); 1076int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only);
1077int i915_gem_evict_inactive(struct drm_device *dev); 1077int i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only);
1078 1078
1079/* i915_gem_tiling.c */ 1079/* i915_gem_tiling.c */
1080void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); 1080void 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
43int 43int
44i915_gem_evict_something(struct drm_device *dev, int min_size, 44i915_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
173int 173int
174i915_gem_evict_everything(struct drm_device *dev) 174i915_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. */
210int 199int
211i915_gem_evict_inactive(struct drm_device *dev) 200i915_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