Skip to content

Commit

Permalink
drm/i915: Always use kref tracking for all contexts.
Browse files Browse the repository at this point in the history
If we always initialize kref for the context, even if we are using fake
contexts for hangstats when there is no hw support, we can forgo the
dance to dereference the ctx->obj and inspect whether we are permitted
to use kref inside i915_gem_context_reference() and _unreference().

My ulterior motive here is to improve the debugging of a use-after-free
of ctx->obj. This patch avoids the dereference here and instead forces
the assertion checks associated with kref.

v2: Refactor the fake contexts to being even more like the real
contexts, so that there is much less duplicated and special case code.

v3: Tweaks.
v4: Tweaks, minor.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76671
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Tested-by: lu hua <huax.lu@intel.com>
Cc: Ben Widawsky <benjamin.widawsky@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
[Jani: tiny change to backport to drm-intel-fixes.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
  • Loading branch information
Chris Wilson authored and Jani Nikula committed Apr 11, 2014
1 parent c675949 commit 691e641
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 137 deletions.
8 changes: 3 additions & 5 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2432,20 +2432,18 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
int i915_gem_context_enable(struct drm_i915_private *dev_priv);
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
int i915_switch_context(struct intel_ring_buffer *ring,
struct drm_file *file, struct i915_hw_context *to);
struct i915_hw_context *to);
struct i915_hw_context *
i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
void i915_gem_context_free(struct kref *ctx_ref);
static inline void i915_gem_context_reference(struct i915_hw_context *ctx)
{
if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
kref_get(&ctx->ref);
kref_get(&ctx->ref);
}

static inline void i915_gem_context_unreference(struct i915_hw_context *ctx)
{
if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
kref_put(&ctx->ref, i915_gem_context_free);
kref_put(&ctx->ref, i915_gem_context_free);
}

static inline bool i915_gem_context_is_default(const struct i915_hw_context *c)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2790,7 +2790,7 @@ int i915_gpu_idle(struct drm_device *dev)

/* Flush everything onto the inactive list. */
for_each_ring(ring, dev_priv, i) {
ret = i915_switch_context(ring, NULL, ring->default_context);
ret = i915_switch_context(ring, ring->default_context);
if (ret)
return ret;

Expand Down
Loading

0 comments on commit 691e641

Please sign in to comment.