summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorMichel Thierry <michel.thierry@intel.com>2014-08-06 17:04:44 +0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-08-12 17:22:26 +0400
commitb9d06dd9d1dd3672b391e6387d62aa8dc4e377bd (patch)
tree3d9185f91583b1f061d5744d17d9f6c25f485025 /drivers/gpu/drm/i915/i915_gem.c
parent14bf993e83e1d6924f4bf4506120a15c4b255e58 (diff)
downloadlinux-b9d06dd9d1dd3672b391e6387d62aa8dc4e377bd.tar.xz
drm/i915: vma/ppgtt lifetime rules
VMAs should take a reference of the address space they use. Now, when the fd is closed, it will release the ref that the context was holding, but it will still be referenced by any vmas that are still active. ppgtt_release() should then only be called when the last thing referencing it releases the ref, and it can just call the base cleanup and free the ppgtt. Note that with this we will extend the lifetime of ppgtts which contain shared objects. But all the non-shared objects will get removed as soon as they drop of the active list and for the shared ones the shrinker can eventually reap them. Since we currently can't evict ppgtt pagetables either I don't think that temporary leak is important. Signed-off-by: Michel Thierry <michel.thierry@intel.com> [danvet: Add note about potential ppgtt leak with this approach.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9acb2469116a..63aee412b258 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4476,12 +4476,20 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
void i915_gem_vma_destroy(struct i915_vma *vma)
{
+ struct i915_address_space *vm = NULL;
+ struct i915_hw_ppgtt *ppgtt = NULL;
WARN_ON(vma->node.allocated);
/* Keep the vma as a placeholder in the execbuffer reservation lists */
if (!list_empty(&vma->exec_list))
return;
+ vm = vma->vm;
+ ppgtt = vm_to_ppgtt(vm);
+
+ if (ppgtt)
+ kref_put(&ppgtt->ref, ppgtt_release);
+
list_del(&vma->vma_link);
kfree(vma);