aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem_evict.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-10-31 04:49:47 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-31 08:31:30 -0400
commit5eac3ab45955b32f3a9d89e633918c4d6f133dfa (patch)
tree302cc30dde39e47dc238bc440bef87a267e9b656 /drivers/gpu/drm/i915/i915_gem_evict.c
parentff75b9bc489710ff223bc0d805bf3b862dc347ea (diff)
drm/i915: Evict just the purgeable GTT entries on the first pass
Take two passes to evict everything whilst searching for sufficient free space to bind the batchbuffer. After searching for sufficient free space using LRU eviction, evict everything that is purgeable and try again. Only then if there is insufficient free space (or the GTT is too badly fragmented) evict everything from the aperture and try one last time. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_evict.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c42
1 files changed, 13 insertions, 29 deletions
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