public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
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

  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