drm/i915: Ignore most failures during evict-vm
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 5 Dec 2019 11:37:24 +0000 (11:37 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 5 Dec 2019 13:50:39 +0000 (13:50 +0000)
Removing all vma from the VM is best effort -- we only remove all those
ready to be removed, so forgive and VMA that becomes pinned. While
forgiving those that become pinned, also take a second look for any that
became unpinned as we waited.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191205113726.413351-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem_evict.c

index 7e62c310290f397c2e26fce532979346304c49bf..0697bedebeef2e52f5e6195d98d1ceff5ef51ea3 100644 (file)
@@ -359,9 +359,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
  */
 int i915_gem_evict_vm(struct i915_address_space *vm)
 {
-       struct list_head eviction_list;
-       struct i915_vma *vma, *next;
-       int ret;
+       int ret = 0;
 
        lockdep_assert_held(&vm->mutex);
        trace_i915_gem_evict_vm(vm);
@@ -377,21 +375,30 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
                        return ret;
        }
 
-       INIT_LIST_HEAD(&eviction_list);
-       list_for_each_entry(vma, &vm->bound_list, vm_link) {
-               if (i915_vma_is_pinned(vma))
-                       continue;
+       do {
+               struct i915_vma *vma, *vn;
+               LIST_HEAD(eviction_list);
 
-               __i915_vma_pin(vma);
-               list_add(&vma->evict_link, &eviction_list);
-       }
+               list_for_each_entry(vma, &vm->bound_list, vm_link) {
+                       if (i915_vma_is_pinned(vma))
+                               continue;
+
+                       __i915_vma_pin(vma);
+                       list_add(&vma->evict_link, &eviction_list);
+               }
+               if (list_empty(&eviction_list))
+                       break;
+
+               ret = 0;
+               list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
+                       __i915_vma_unpin(vma);
+                       if (ret == 0)
+                               ret = __i915_vma_unbind(vma);
+                       if (ret != -EINTR) /* "Get me out of here!" */
+                               ret = 0;
+               }
+       } while (ret == 0);
 
-       ret = 0;
-       list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
-               __i915_vma_unpin(vma);
-               if (ret == 0)
-                       ret = __i915_vma_unbind(vma);
-       }
        return ret;
 }