@@ -586,6 +586,7 @@ struct i915_ctx_hang_stats {
/* This must match up with the value previously used for execbuf2.rsvd1. */
#define DEFAULT_CONTEXT_ID 0
struct intel_context {
+ struct drm_device *dev;
struct kref ref;
int id;
bool is_initialized;
@@ -178,22 +178,21 @@ static int get_context_size(struct drm_device *dev)
void i915_gem_context_free(struct kref *ctx_ref)
{
- struct intel_context *ctx = container_of(ctx_ref,
- typeof(*ctx), ref);
- struct i915_hw_ppgtt *ppgtt = NULL;
+ struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
+ struct drm_device *dev = ctx->dev;
if (ctx->render_obj) {
- /* We refcount even the aliasing PPGTT to keep the code symmetric */
- if (USES_PPGTT(ctx->render_obj->base.dev))
- ppgtt = ctx_to_ppgtt(ctx);
-
/* XXX: Free up the object before tearing down the address space, in
* case we're bound in the PPGTT */
drm_gem_object_unreference(&ctx->render_obj->base);
}
- if (ppgtt)
+ /* We refcount even the aliasing PPGTT to keep the code symmetric */
+ if (USES_PPGTT(dev)) {
+ struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(ctx);
kref_put(&ppgtt->ref, ppgtt_release);
+ }
+
list_del(&ctx->link);
kfree(ctx);
}
@@ -229,8 +228,9 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
}
static struct i915_hw_ppgtt *
-create_vm_for_ctx(struct drm_device *dev, struct intel_context *ctx)
+create_vm_for_ctx(struct intel_context *ctx)
{
+ struct drm_device *dev = ctx->dev;
struct i915_hw_ppgtt *ppgtt;
int ret;
@@ -282,6 +282,7 @@ __create_hw_context(struct drm_device *dev,
} else
ret = DEFAULT_CONTEXT_ID;
+ ctx->dev = dev;
ctx->file_priv = file_priv;
ctx->id = ret;
/* NB: Mark all slices as needing a remap so that when the context first
@@ -334,7 +335,7 @@ i915_gem_create_context(struct drm_device *dev,
}
if (create_vm) {
- struct i915_hw_ppgtt *ppgtt = create_vm_for_ctx(dev, ctx);
+ struct i915_hw_ppgtt *ppgtt = create_vm_for_ctx(ctx);
if (IS_ERR_OR_NULL(ppgtt)) {
DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",