diff mbox series

[2/2] drm/i915/gem: Avoid parking the vma as we unbind

Message ID 20191203101347.2836057-2-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series [1/2] drm/i915/gem: Take runtime-pm wakeref prior to unbinding | expand

Commit Message

Chris Wilson Dec. 3, 2019, 10:13 a.m. UTC
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>
---
 drivers/gpu/drm/i915/i915_gem.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

Comments

Matthew Auld Dec. 3, 2019, 1:29 p.m. UTC | #1
On Tue, 3 Dec 2019 at 10:13, Chris Wilson <chris@chris-wilson.co.uk> wrote:
>
> 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>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f7b5fe0f5424..e5371a076b89 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -141,18 +141,32 @@  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;
 
+		if (i915_vma_is_closed(vma)) {
+			if (!intel_gt_pm_get_if_awake(vm->gt)) {
+				spin_unlock(&obj->vma.lock);
+				goto err_vm;
+			}
+
+			awake = true;
+		}
+
 		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);
 	}