summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-12-03 15:50:32 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2019-12-03 20:41:34 +0000
commitcb6c3d45f948f8f184687a23fea30017d01e892f (patch)
tree42ab52825638e968ae5d95415070a65c465d7a23 /drivers/gpu/drm/i915/i915_gem.c
parent78eaaba3cd786718f6ed0c9013879d3c11a00998 (diff)
drm/i915/gem: Avoid parking the vma as we unbind
In order to avoid keeping a reference on the i915_vma (which is long overdue!) we have to coordinate all the possible lifetimes and only use the vma while we know it is alive. In this episode, we are reminded that while idle, the closed vma are destroyed. So if the GT idles while we are working with the vma, the vma itself becomes invalid. First class i915_vma here we come, but in the meantime keep piling on the straw. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191203155032.3137263-1-chris@chris-wilson.co.uk
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);
}