From: Ben Widawsky <ben@bwidawsk.net>
To: Ben Widawsky <ben@bwidawsk.net>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 03/25 v2] drm/i915: context basic create & destroy
Date: Wed, 13 Jun 2012 16:27:58 -0700 [thread overview]
Message-ID: <20120613162758.2ea392a5@bwidawsk.net> (raw)
In-Reply-To: <1338846185-10571-4-git-send-email-ben@bwidawsk.net>
TODO from irc: change create_hw_context to return the pointer and use
PTR_ERR as appropriate.
On Mon, 4 Jun 2012 14:42:43 -0700
Ben Widawsky <ben@bwidawsk.net> wrote:
> Invent an abstraction for a hw context which is passed around through
> the core functions. The main bit a hw context holds is the buffer object
> which backs the context. The rest of the members are just helper
> functions. Specifically the ring member, which could likely go away if
> we decide to never implement whatever other hw context support exists.
>
> Of note here is the introduction of the 64k alignment constraint for the
> BO. If contexts become heavily used, we should consider tweaking this
> down to 4k. Until the contexts are merged and tested a bit though, I
> think 64k is a nice start (based on docs).
>
> Since we don't yet switch contexts, there is really not much complexity
> here. Creation/destruction works pretty much as one would expect. An idr
> is used to generate the context id numbers which are unique per file
> descriptor.
>
> v2: add DRM_DEBUG_DRIVERS to distinguish ENOMEM failures (ben)
> convert a BUG_ON to WARN_ON, default destruction is still fatal (ben)
>
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 11 +++
> drivers/gpu/drm/i915/i915_gem_context.c | 142 ++++++++++++++++++++++++++++++-
> drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +
> 3 files changed, 153 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 432b44f..f543679 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -308,6 +308,16 @@ struct i915_hw_ppgtt {
> dma_addr_t scratch_page_dma_addr;
> };
>
> +
> +/* This must match up with the value previously used for execbuf2.rsvd1. */
> +#define DEFAULT_CONTEXT_ID 0
> +struct i915_hw_context {
> + int id;
> + struct drm_i915_file_private *file_priv;
> + struct intel_ring_buffer *ring;
> + struct drm_i915_gem_object *obj;
> +};
> +
> enum no_fbc_reason {
> FBC_NO_OUTPUT, /* no outputs enabled to compress */
> FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */
> @@ -1023,6 +1033,7 @@ struct drm_i915_file_private {
> struct spinlock lock;
> struct list_head request_list;
> } mm;
> + struct idr context_idr;
> };
>
> #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info)
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index e39808e..2aca002 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -89,6 +89,15 @@
> #include "i915_drm.h"
> #include "i915_drv.h"
>
> +/* This is a HW constraint. The value below is the largest known requirement
> + * I've seen in a spec to date, and that was a workaround for a non-shipping
> + * part. It should be safe to decrease this, but it's more future proof as is.
> + */
> +#define CONTEXT_ALIGN (64<<10)
> +
> +static struct i915_hw_context *
> +i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
> +
> static int get_context_size(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -111,6 +120,76 @@ static int get_context_size(struct drm_device *dev)
> return ret;
> }
>
> +static void do_destroy(struct i915_hw_context *ctx)
> +{
> + struct drm_device *dev = ctx->obj->base.dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> +
> + if (ctx->file_priv)
> + idr_remove(&ctx->file_priv->context_idr, ctx->id);
> + else
> + BUG_ON(ctx != dev_priv->ring[RCS].default_context);
> +
> + drm_gem_object_unreference(&ctx->obj->base);
> + kfree(ctx);
> +}
> +
> +static int
> +create_hw_context(struct drm_device *dev,
> + struct drm_i915_file_private *file_priv,
> + struct i915_hw_context **ctx_out)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + int ret, id;
> +
> + *ctx_out = kzalloc(sizeof(struct drm_i915_file_private), GFP_KERNEL);
> + if (*ctx_out == NULL)
> + return -ENOMEM;
> +
> + (*ctx_out)->obj = i915_gem_alloc_object(dev,
> + dev_priv->hw_context_size);
> + if ((*ctx_out)->obj == NULL) {
> + kfree(*ctx_out);
> + DRM_DEBUG_DRIVER("Context object allocated failed\n");
> + return -ENOMEM;
> + }
> +
> + /* The ring associated with the context object is handled by the normal
> + * object tracking code. We give an initial ring value simple to pass an
> + * assertion in the context switch code.
> + */
> + (*ctx_out)->ring = &dev_priv->ring[RCS];
> +
> + /* Default context will never have a file_priv */
> + if (file_priv == NULL)
> + return 0;
> +
> + (*ctx_out)->file_priv = file_priv;
> +
> +again:
> + if (idr_pre_get(&file_priv->context_idr, GFP_KERNEL) == 0) {
> + ret = -ENOMEM;
> + DRM_DEBUG_DRIVER("idr allocation failed\n");
> + goto err_out;
> + }
> +
> + ret = idr_get_new_above(&file_priv->context_idr, *ctx_out,
> + DEFAULT_CONTEXT_ID + 1, &id);
> + if (ret == 0)
> + (*ctx_out)->id = id;
> +
> + if (ret == -EAGAIN)
> + goto again;
> + else if (ret)
> + goto err_out;
> +
> + return 0;
> +
> +err_out:
> + do_destroy(*ctx_out);
> + return ret;
> +}
> +
> /**
> * The default context needs to exist per ring that uses contexts. It stores the
> * context state of the GPU for applications that don't utilize HW contexts, as
> @@ -118,7 +197,30 @@ static int get_context_size(struct drm_device *dev)
> */
> static int create_default_context(struct drm_i915_private *dev_priv)
> {
> - return 0;
> + struct i915_hw_context *ctx;
> + int ret;
> +
> + BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
> +
> + ret = create_hw_context(dev_priv->dev, NULL,
> + &dev_priv->ring[RCS].default_context);
> + if (ret)
> + return ret;
> +
> + /* We may need to do things with the shrinker which require us to
> + * immediately switch back to the default context. This can cause a
> + * problem as pinning the default context also requires GTT space which
> + * may not be available. To avoid this we always pin the
> + * default context.
> + */
> + ctx = dev_priv->ring[RCS].default_context;
> + ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false);
> + if (ret) {
> + do_destroy(ctx);
> + return ret;
> + }
> +
> + return ret;
> }
>
> void i915_gem_context_init(struct drm_device *dev)
> @@ -130,7 +232,8 @@ void i915_gem_context_init(struct drm_device *dev)
> return;
>
> /* If called from reset, or thaw... we've been here already */
> - if (dev_priv->hw_contexts_disabled)
> + if (dev_priv->hw_contexts_disabled ||
> + dev_priv->ring[RCS].default_context)
> return;
>
> ctx_size = get_context_size(dev);
> @@ -156,20 +259,55 @@ void i915_gem_context_fini(struct drm_device *dev)
>
> if (dev_priv->hw_contexts_disabled)
> return;
> +
> + i915_gem_object_unpin(dev_priv->ring[RCS].default_context->obj);
> +
> + do_destroy(dev_priv->ring[RCS].default_context);
> }
>
> void i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> + struct drm_i915_file_private *file_priv = file->driver_priv;
>
> if (dev_priv->hw_contexts_disabled)
> return;
> +
> + idr_init(&file_priv->context_idr);
> +}
> +
> +static int context_idr_cleanup(int id, void *p, void *data)
> +{
> + struct drm_file *file = (struct drm_file *)data;
> + struct drm_i915_file_private *file_priv = file->driver_priv;
> + struct i915_hw_context *ctx;
> +
> + BUG_ON(id == DEFAULT_CONTEXT_ID);
> + ctx = i915_gem_context_get(file_priv, id);
> + if (WARN_ON(ctx == NULL))
> + return -ENXIO;
> +
> + do_destroy(ctx);
> +
> + return 0;
> }
>
> void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> + struct drm_i915_file_private *file_priv = file->driver_priv;
>
> if (dev_priv->hw_contexts_disabled)
> return;
> +
> + mutex_lock(&dev->struct_mutex);
> + idr_for_each(&file_priv->context_idr, context_idr_cleanup, file);
> + idr_destroy(&file_priv->context_idr);
> + mutex_unlock(&dev->struct_mutex);
> +}
> +
> +static __used struct i915_hw_context *
> +i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id)
> +{
> + return (struct i915_hw_context *)idr_find(&file_priv->context_idr, id);
> }
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 55d3da2..bb19bec 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -116,6 +116,8 @@ struct intel_ring_buffer {
>
> wait_queue_head_t irq_queue;
>
> + struct i915_hw_context *default_context;
> +
> void *private;
> };
>
--
Ben Widawsky, Intel Open Source Technology Center
next prev parent reply other threads:[~2012-06-13 23:28 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-04 21:42 [PATCH 00/25] i915 HW context support Ben Widawsky
2012-06-04 21:42 ` [PATCH 01/25] drm/i915: CXT_SIZE register offsets added Ben Widawsky
2012-06-04 21:42 ` [PATCH 02/25 v2] drm/i915: preliminary context support Ben Widawsky
2012-06-05 12:23 ` Ville Syrjälä
2012-06-05 16:30 ` Ben Widawsky
2012-06-04 21:42 ` [PATCH 03/25 v2] drm/i915: context basic create & destroy Ben Widawsky
2012-06-13 23:27 ` Ben Widawsky [this message]
2012-06-04 21:42 ` [PATCH 04/25] drm/i915: add context information to objects Ben Widawsky
2012-06-13 22:01 ` Daniel Vetter
2012-06-13 23:26 ` Ben Widawsky
2012-06-04 21:42 ` [PATCH 05/25] drm/i915: always bind context objects immediately Ben Widawsky
2012-06-04 21:42 ` [PATCH 06/25 v3] drm/i915: context switch implementation Ben Widawsky
2012-06-04 21:42 ` [PATCH 07/25] drm/i915: context trace events Ben Widawsky
2012-06-13 22:23 ` Daniel Vetter
2012-06-13 23:27 ` Ben Widawsky
2012-06-04 21:42 ` [PATCH 08/25] drm/i915: Ivybridge MI_ARB_ON_OFF context w/a Ben Widawsky
2012-06-04 21:42 ` [PATCH 09/25] drm/i915: PIPE_CONTROL_TLB_INVALIDATE Ben Widawsky
2012-06-04 21:42 ` [PATCH 10/25 v2] drm/i915: possibly invalidate TLB before context switch Ben Widawsky
2012-06-04 21:42 ` [PATCH 11/25] drm/i915: use the default context Ben Widawsky
2012-06-04 21:42 ` [PATCH 12/25] drm/i915: add ccid to error state Ben Widawsky
2012-06-04 21:42 ` [PATCH 13/25 v3] drm/i915: switch to default context on idle Ben Widawsky
2012-06-04 21:42 ` [PATCH 14/25 v3] drm/i915/context: create & destroy ioctls Ben Widawsky
2012-06-04 21:42 ` [PATCH 15/25 v2] drm/i915/context: switch contexts with execbuf2 Ben Widawsky
2012-06-04 21:42 ` [PATCH 16/25] drm/i915: reset the GPU on context fini Ben Widawsky
2012-06-04 21:42 ` [PATCH 17/25] intel: wait render placeholder Ben Widawsky
2012-06-04 21:42 ` [PATCH 18/25] intel: Merge updated kernel header Ben Widawsky
2012-06-04 21:42 ` [PATCH 19/25] intel/context: Add drm_intel_context type Ben Widawsky
2012-06-04 21:43 ` [PATCH 20/25] intel/context: new execbuf interface for contexts Ben Widawsky
2012-06-04 21:43 ` [PATCH 21/25] intel: add decoding of MI_SET_CONTEXT Ben Widawsky
2012-06-04 21:43 ` [PATCH 22/25] context: libdrm wrappers Ben Widawsky
2012-06-04 21:43 ` [PATCH 23/25] context: update for new execbuf2 element Ben Widawsky
2012-06-04 21:43 ` [PATCH 24/25] contexts: basic test coverage Ben Widawsky
2012-06-13 23:30 ` Daniel Vetter
2012-06-14 3:13 ` [PATCH] " Ben Widawsky
2012-06-04 21:43 ` [PATCH 25/25] i965: hw context support Ben Widawsky
2012-06-04 23:01 ` Paul Berry
2012-06-04 23:10 ` [Intel-gfx] " Ben Widawsky
2012-06-05 5:53 ` [PATCH 00/25] i915 HW " Dave Airlie
2012-06-05 7:08 ` [Mesa-dev] " Kenneth Graunke
2012-06-05 16:32 ` Ben Widawsky
2012-06-05 23:37 ` Kenneth Graunke
2012-06-07 16:17 ` Ben Widawsky
2012-06-14 16:04 ` 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=20120613162758.2ea392a5@bwidawsk.net \
--to=ben@bwidawsk.net \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox