summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem_context.c
diff options
context:
space:
mode:
authorBen Widawsky <benjamin.widawsky@intel.com>2013-12-06 14:11:15 -0800
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-12-18 15:31:20 +0100
commitc7c48dfdff246d65408ff4f336978cc861722ca4 (patch)
tree276dd9417513ef6a8f7dd0b1cdb1bbea0e0b5908 /drivers/gpu/drm/i915/i915_gem_context.c
parent246cbfb5fb9a1ca0997fbb135464c1ff5bb9c549 (diff)
downloadlinux-c7c48dfdff246d65408ff4f336978cc861722ca4.tar.gz
linux-c7c48dfdff246d65408ff4f336978cc861722ca4.tar.bz2
linux-c7c48dfdff246d65408ff4f336978cc861722ca4.zip
drm/i915: Add VM to context
Pretty straightforward so far except for the bit about the refcounting. The PPGTT will potentially be shared amongst multiple contexts. Because contexts themselves have a refcounted lifecycle, the easiest way to manage this will be to refcount the PPGTT. To acheive this, we piggy back off of the existing context refcount, and will increment and decrement the PPGTT refcount with context creation, and destruction. To put it more clearly, if context A, and context B both use PPGTT 0, we can't free the PPGTT until both A, and B are destroyed. Note that because the PPGTT is permanently pinned (for now), it really just matters for the PPGTT destruction, as opposed to making space under memory pressure. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_context.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 149cf007c38e..0b32bcff5d66 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -141,9 +141,19 @@ void i915_gem_context_free(struct kref *ctx_ref)
{
struct i915_hw_context *ctx = container_of(ctx_ref,
typeof(*ctx), ref);
+ struct i915_hw_ppgtt *ppgtt = NULL;
- list_del(&ctx->link);
+ /* We refcount even the aliasing PPGTT to keep the code symmetric */
+ if (USES_ALIASING_PPGTT(ctx->obj->base.dev))
+ ppgtt = container_of(ctx->vm, struct i915_hw_ppgtt, base);
+
+ /* XXX: Free up the object before tearing down the address space, in
+ * case we're bound in the PPGTT */
drm_gem_object_unreference(&ctx->obj->base);
+
+ if (ppgtt)
+ kref_put(&ppgtt->ref, ppgtt_release);
+ list_del(&ctx->link);
kfree(ctx);
}