From: Jani Nikula <jani.nikula@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/i915: Disallow preallocation of requests
Date: Thu, 27 Sep 2012 10:39:53 +0300 [thread overview]
Message-ID: <87ipaz6hiu.fsf@intel.com> (raw)
In-Reply-To: <1348663651-14124-1-git-send-email-chris@chris-wilson.co.uk>
On Wed, 26 Sep 2012, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> The intention was to allow the caller to avoid a failure to queue a
> request having already written commands to the ring. However, this is a
> moot point as the i915_add_request() can fail for other reasons than a
> mere allocation failure and those failure cases are more likely than
> ENOMEM. So the overlay code already had to handle i915_add_request()
> failures, and due to
>
> commit 3bb73aba1ed5198a2c1dfaac4f3c95459930d84a
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date: Fri Jul 20 12:40:59 2012 +0100
>
> drm/i915: Allow late allocation of request for i915_add_request()
>
> the error handling code in intel_overlay.c was subject to causing
> double-frees, as found by coverity.
>
> Rather than further complicate i915_add_request() and callers, realise
> the battle is lost and adapt intel_overlay.c to take advantage of the
> late allocation of requests.
>
> v2: Handle callers passing in a NULL seqno.
> v3: Ditto. This time for sure.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 +-
> drivers/gpu/drm/i915/i915_gem.c | 15 +++----
> drivers/gpu/drm/i915/intel_overlay.c | 72 +++++++---------------------------
> 3 files changed, 24 insertions(+), 65 deletions(-)
Looks good, and I also like the diffstat.
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index dddc3dc..d8d4736 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1468,7 +1468,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
> int __must_check i915_gem_idle(struct drm_device *dev);
> int i915_add_request(struct intel_ring_buffer *ring,
> struct drm_file *file,
> - struct drm_i915_gem_request *request);
> + u32 *seqno);
> int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
> uint32_t seqno);
> int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index b2effab..014b95e 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2087,11 +2087,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
> int
> i915_add_request(struct intel_ring_buffer *ring,
> struct drm_file *file,
> - struct drm_i915_gem_request *request)
> + u32 *out_seqno)
> {
> drm_i915_private_t *dev_priv = ring->dev->dev_private;
> - uint32_t seqno;
> + struct drm_i915_gem_request *request;
> u32 request_ring_position;
> + u32 seqno;
> int was_empty;
> int ret;
>
> @@ -2106,11 +2107,9 @@ i915_add_request(struct intel_ring_buffer *ring,
> if (ret)
> return ret;
>
> - if (request == NULL) {
> - request = kmalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> - }
> + request = kmalloc(sizeof(*request), GFP_KERNEL);
> + if (request == NULL)
> + return -ENOMEM;
>
> seqno = i915_gem_next_request_seqno(ring);
>
> @@ -2162,6 +2161,8 @@ i915_add_request(struct intel_ring_buffer *ring,
> }
> }
>
> + if (out_seqno)
> + *out_seqno = seqno;
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 2fa20a4..ebcbf48 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -210,7 +210,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
> }
>
> static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
> - struct drm_i915_gem_request *request,
> void (*tail)(struct intel_overlay *))
> {
> struct drm_device *dev = overlay->dev;
> @@ -219,12 +218,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
> int ret;
>
> BUG_ON(overlay->last_flip_req);
> - ret = i915_add_request(ring, NULL, request);
> - if (ret) {
> - kfree(request);
> - return ret;
> - }
> - overlay->last_flip_req = request->seqno;
> + ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
> + if (ret)
> + return ret;
> +
> overlay->flip_tail = tail;
> ret = i915_wait_seqno(ring, overlay->last_flip_req);
> if (ret)
> @@ -241,7 +238,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
> struct drm_device *dev = overlay->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> - struct drm_i915_gem_request *request;
> int ret;
>
> BUG_ON(overlay->active);
> @@ -249,17 +245,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
>
> WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
>
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL) {
> - ret = -ENOMEM;
> - goto out;
> - }
> -
> ret = intel_ring_begin(ring, 4);
> - if (ret) {
> - kfree(request);
> - goto out;
> - }
> + if (ret)
> + return ret;
>
> intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
> intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
> @@ -267,9 +255,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
> intel_ring_emit(ring, MI_NOOP);
> intel_ring_advance(ring);
>
> - ret = intel_overlay_do_wait_request(overlay, request, NULL);
> -out:
> - return ret;
> + return intel_overlay_do_wait_request(overlay, NULL);
> }
>
> /* overlay needs to be enabled in OCMD reg */
> @@ -279,17 +265,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
> struct drm_device *dev = overlay->dev;
> drm_i915_private_t *dev_priv = dev->dev_private;
> struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> - struct drm_i915_gem_request *request;
> u32 flip_addr = overlay->flip_addr;
> u32 tmp;
> int ret;
>
> BUG_ON(!overlay->active);
>
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> -
> if (load_polyphase_filter)
> flip_addr |= OFC_UPDATE;
>
> @@ -299,22 +280,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
> DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
>
> ret = intel_ring_begin(ring, 2);
> - if (ret) {
> - kfree(request);
> + if (ret)
> return ret;
> - }
> +
> intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
> intel_ring_emit(ring, flip_addr);
> intel_ring_advance(ring);
>
> - ret = i915_add_request(ring, NULL, request);
> - if (ret) {
> - kfree(request);
> - return ret;
> - }
> -
> - overlay->last_flip_req = request->seqno;
> - return 0;
> + return i915_add_request(ring, NULL, &overlay->last_flip_req);
> }
>
> static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
> @@ -350,15 +323,10 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> u32 flip_addr = overlay->flip_addr;
> - struct drm_i915_gem_request *request;
> int ret;
>
> BUG_ON(!overlay->active);
>
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> -
> /* According to intel docs the overlay hw may hang (when switching
> * off) without loading the filter coeffs. It is however unclear whether
> * this applies to the disabling of the overlay or to the switching off
> @@ -366,10 +334,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> flip_addr |= OFC_UPDATE;
>
> ret = intel_ring_begin(ring, 6);
> - if (ret) {
> - kfree(request);
> + if (ret)
> return ret;
> - }
> +
> /* wait for overlay to go idle */
> intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
> intel_ring_emit(ring, flip_addr);
> @@ -380,8 +347,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
> intel_ring_advance(ring);
>
> - return intel_overlay_do_wait_request(overlay, request,
> - intel_overlay_off_tail);
> + return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
> }
>
> /* recover from an interruption due to a signal
> @@ -426,24 +392,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
> return 0;
>
> if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
> - struct drm_i915_gem_request *request;
> -
> /* synchronous slowpath */
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> -
> ret = intel_ring_begin(ring, 2);
> - if (ret) {
> - kfree(request);
> + if (ret)
> return ret;
> - }
>
> intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
> intel_ring_emit(ring, MI_NOOP);
> intel_ring_advance(ring);
>
> - ret = intel_overlay_do_wait_request(overlay, request,
> + ret = intel_overlay_do_wait_request(overlay,
> intel_overlay_release_old_vid_tail);
> if (ret)
> return ret;
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2012-09-27 7:35 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-26 12:35 [PATCH] drm/i915: Disallow preallocation of requests Chris Wilson
2012-09-26 12:41 ` Chris Wilson
2012-09-26 12:42 ` Chris Wilson
2012-09-26 12:44 ` Chris Wilson
2012-09-26 12:47 ` Chris Wilson
2012-09-27 7:39 ` Jani Nikula [this message]
2012-09-27 11:46 ` Daniel Vetter
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=87ipaz6hiu.fsf@intel.com \
--to=jani.nikula@linux.intel.com \
--cc=chris@chris-wilson.co.uk \
--cc=intel-gfx@lists.freedesktop.org \
/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.