@@ -128,18 +128,33 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
struct i915_vma,
obj_link))) {
struct i915_address_space *vm = vma->vm;
+ bool awake = false;
- ret = -EBUSY;
+ ret = -EAGAIN;
if (!i915_vm_tryopen(vm))
break;
+ /* Prevent vma being freed by i915_vma_parked as we unbind */
+ if (intel_gt_pm_get_if_awake(vm->gt)) {
+ awake = true;
+ } else {
+ if (i915_vma_is_closed(vma)) {
+ spin_unlock(&obj->vma.lock);
+ goto err_vm;
+ }
+ }
+
list_move_tail(&vma->obj_link, &still_in_list);
spin_unlock(&obj->vma.lock);
+ ret = -EBUSY;
if (flags & I915_GEM_OBJECT_UNBIND_ACTIVE ||
!i915_vma_is_active(vma))
ret = i915_vma_unbind(vma);
+ if (awake)
+ intel_gt_pm_put(vm->gt);
+err_vm:
i915_vm_close(vm);
spin_lock(&obj->vma.lock);
}