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>
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e3fc333..c8e516d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3519,7 +3519,8 @@
int ret, i, retry;
/* attempt to pin all of the buffers into the GTT */
- for (retry = 0; retry < 2; retry++) {
+ retry = 0;
+ do {
ret = 0;
for (i = 0; i < count; i++) {
struct drm_i915_gem_exec_object2 *entry = &exec_list[i];
@@ -3567,18 +3568,18 @@
while (i--)
i915_gem_object_unpin(object_list[i]);
- if (ret == 0)
- break;
-
- if (ret != -ENOSPC || retry)
+ if (ret != -ENOSPC || retry > 1)
return ret;
- ret = i915_gem_evict_everything(dev);
+ /* First attempt, just clear anything that is purgeable.
+ * Second attempt, clear the entire GTT.
+ */
+ ret = i915_gem_evict_everything(dev, retry == 0);
if (ret)
return ret;
- }
- return 0;
+ retry++;
+ } while (1);
}
/* Throttle our rendering by waiting until the ring has completed our requests
@@ -4484,7 +4485,7 @@
/* Under UMS, be paranoid and evict. */
if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
- ret = i915_gem_evict_inactive(dev);
+ ret = i915_gem_evict_inactive(dev, false);
if (ret) {
mutex_unlock(&dev->struct_mutex);
return ret;