All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@linux.intel.com>
To: "Daniel, Thomas" <thomas.daniel@intel.com>,
	"Hoath, Nicholas" <nicholas.hoath@intel.com>,
	"intel-gfx@lists.freedesktop.org"
	<intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH] drm/i915: Fix a use after free, and unbalanced refcounting
Date: Tue, 24 Feb 2015 15:20:35 +0200	[thread overview]
Message-ID: <87egpfphss.fsf@intel.com> (raw)
In-Reply-To: <BFEE8FEC12424048AF1805991D65FA91197420C8@irsmsx105.ger.corp.intel.com>

On Mon, 23 Feb 2015, "Daniel, Thomas" <thomas.daniel@intel.com> wrote:
>> -----Original Message-----
>> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
>> Nick Hoath
>> Sent: Thursday, February 19, 2015 4:31 PM
>> To: intel-gfx@lists.freedesktop.org
>> Subject: [Intel-gfx] [PATCH] drm/i915: Fix a use after free, and unbalanced
>> refcounting
>> 
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88652
>> 
>> When converting from implicitly tracked execlist queue items to ref counted
>> requests, not all frees of requests were replaced with unrefs, and extraneous
>> refs/unrefs of contexts were added.
>> Correct the unbalanced refcount & replace the frees.
>> Remove a noisy warning when hitting the request creation path.
>> 
>> drm_i915_gem_request and intel_context are both kref reference counted
>> structures. Upon allocation, drm_i915_gem_request's ref count should be
>> bumped using kref_init. When a context is assigned to the request,
>> the context's reference count should be bumped using
>> i915_gem_context_reference.
>> i915_gem_request_reference will reduce the context reference count when
>> the request is freed.
>> 
>> Problem introduced in
>> commit 6d3d8274bc45de4babb62d64562d92af984dd238
>> Author:     Nick Hoath <nicholas.hoath@intel.com>
>> AuthorDate: Thu Jan 15 13:10:39 2015 +0000
>> 
>>      drm/i915: Subsume intel_ctx_submit_request in to drm_i915_gem_request
>> 
>> v2: Added comments explaining how the ctx pointer and the request object
>> should
>> be ref-counted. Removed noisy warning.
>> 
>> v3: Cleaned up the language used in the commit & the header
>> description (Thanks David Gordon)
>> 
>> Signed-off-by: Nick Hoath <nicholas.hoath@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h  | 11 ++++++++++-
>>  drivers/gpu/drm/i915/i915_gem.c  |  3 +--
>>  drivers/gpu/drm/i915/intel_lrc.c |  8 ++++----
>>  4 files changed, 16 insertions(+), 8 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 2dedd43..956fe26 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -2121,6 +2121,9 @@ void i915_gem_track_fb(struct drm_i915_gem_object
>> *old,
>>   * number comparisons on buffer last_read|write_seqno. It also allows an
>>   * emission time to be associated with the request for tracking how far ahead
>>   * of the GPU the submission is.
>> + *
>> + * The requests are reference counted, so upon creation they should have an
>> + * initial reference taken using kref_init
>>   */
>>  struct drm_i915_gem_request {
>>  	struct kref ref;
>> @@ -2144,7 +2147,16 @@ struct drm_i915_gem_request {
>>  	/** Position in the ringbuffer of the end of the whole request */
>>  	u32 tail;
>> 
>> -	/** Context related to this request */
>> +	/**
>> +	 * Context related to this request
>> +	 * Contexts are refcounted, so when this request is associated with a
>> +	 * context, we must increment the context's refcount, to guarantee that
>> +	 * it persists while any request is linked to it. Requests themselves
>> +	 * are also refcounted, so the request will only be freed when the last
>> +	 * reference to it is dismissed, and the code in
>> +	 * i915_gem_request_free() will then decrement the refcount on the
>> +	 * context.
>> +	 */
>>  	struct intel_context *ctx;
>> 
>>  	/** Batch buffer related to this request if any */
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c
>> b/drivers/gpu/drm/i915/i915_gem.c
>> index 61134ab..996f60f 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2664,8 +2664,7 @@ static void i915_gem_reset_ring_cleanup(struct
>> drm_i915_private *dev_priv,
>>  		if (submit_req->ctx != ring->default_context)
>>  			intel_lr_context_unpin(ring, submit_req->ctx);
>> 
>> -		i915_gem_context_unreference(submit_req->ctx);
>> -		kfree(submit_req);
>> +		i915_gem_request_unreference(submit_req);
>>  	}
>> 
>>  	/*
>> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
>> index aafcef3..62a2b2a 100644
>> --- a/drivers/gpu/drm/i915/intel_lrc.c
>> +++ b/drivers/gpu/drm/i915/intel_lrc.c
>> @@ -512,18 +512,19 @@ static int execlists_context_queue(struct
>> intel_engine_cs *ring,
>>  		 * If there isn't a request associated with this submission,
>>  		 * create one as a temporary holder.
>>  		 */
>> -		WARN(1, "execlist context submission without request");
>>  		request = kzalloc(sizeof(*request), GFP_KERNEL);
>>  		if (request == NULL)
>>  			return -ENOMEM;
>>  		request->ring = ring;
>>  		request->ctx = to;
>> +		kref_init(&request->ref);
>> +		request->uniq = dev_priv->request_uniq++;
>> +		i915_gem_context_reference(request->ctx);
>>  	} else {
>> +		i915_gem_request_reference(request);
>>  		WARN_ON(to != request->ctx);
>>  	}
>>  	request->tail = tail;
>> -	i915_gem_request_reference(request);
>> -	i915_gem_context_reference(request->ctx);
>> 
>>  	intel_runtime_pm_get(dev_priv);
>> 
>> @@ -740,7 +741,6 @@ void intel_execlists_retire_requests(struct
>> intel_engine_cs *ring)
>>  		if (ctx_obj && (ctx != ring->default_context))
>>  			intel_lr_context_unpin(ring, ctx);
>>  		intel_runtime_pm_put(dev_priv);
>> -		i915_gem_context_unreference(ctx);
>>  		list_del(&req->execlist_link);
>>  		i915_gem_request_unreference(req);
>>  	}
>> --
>> 2.1.1
> Reviewed-by: Thomas Daniel <thomas.daniel@intel.com>

Pushed to drm-intel-fixes, with additional r-b from Daniel, thanks for
the patch and review.

BR,
Jani.


>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2015-02-24 13:19 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-19 16:30 [PATCH] drm/i915: Fix a use after free, and unbalanced refcounting Nick Hoath
2015-02-20  7:16 ` shuang.he
2015-02-23 14:10 ` Daniel, Thomas
2015-02-24 13:20   ` Jani Nikula [this message]
2015-02-27  7:31     ` Jani Nikula
  -- strict thread matches above, loose matches on Subject: below --
2015-02-18 14:01 Nick Hoath
2015-02-18 19:50 ` shuang.he
2015-02-19 11:23 ` Dave Gordon
2015-02-19 11:38   ` Nick Hoath
2015-02-13 13:30 Nick Hoath
2015-02-13 13:50 ` Daniel Vetter
2015-02-16 11:13   ` Daniel, Thomas
2015-02-13 22:06 ` shuang.he

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87egpfphss.fsf@intel.com \
    --to=jani.nikula@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=nicholas.hoath@intel.com \
    --cc=thomas.daniel@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.