summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index bfdc8a9f82f8..eb9e2609c569 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -141,18 +141,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);
}