All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Widawsky <bwidawsk@gmail.com>
To: intel-gfx@lists.freedesktop.org
Subject: [RFC] [PATCH 8/8] drm/i915/context: create and destroy ioctls
Date: Sat, 26 Feb 2011 10:30:18 -0800	[thread overview]
Message-ID: <1298745018-5937-9-git-send-email-bwidawsk@gmail.com> (raw)
In-Reply-To: <1298745018-5937-1-git-send-email-bwidawsk@gmail.com>

The create and destroy ioctls are quite simple but depend on a lot of
other infrastructure, including:
	file open handling
	file close handling - cleanup stray contexts
	context_fini - possible switch back to default context
	get_context - object lookup is needed by destroy ioctl

There are two things lacking from the previous set of patches:
* no mention of gtt size in create ioctl
* no handling of the "slots"

gtt size and everything else related to ppgtt will be deferred as much as
possible. I think my dream of getting the API right, and not having a
long term topic branch is quickly becoming unattainable.

slots, I'm still undecided on whether or not to use slots to manage the
buffers associated with the context. It remains in the ioctl semantics
for now as I feel the API doesn't really suffer by having it there...
---
 drivers/gpu/drm/i915/i915_context.c |  110 +++++++++++++++++++++++++++++++++--
 1 files changed, 104 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_context.c b/drivers/gpu/drm/i915/i915_context.c
index 3719a87..da4a0ff 100644
--- a/drivers/gpu/drm/i915/i915_context.c
+++ b/drivers/gpu/drm/i915/i915_context.c
@@ -33,6 +33,8 @@
 #define CONTEXT_SIZE dev_priv->context_size
 #define CONTEXT_ALIGN 4096
 
+static int context_idr_cleanup(int id, void *p, void *data);
+
 static int context_generate_id(struct drm_i915_gem_context *ctx)
 {
 	struct drm_i915_file_private *file_priv = ctx->file->driver_priv;
@@ -268,7 +270,50 @@ id_out:
 
 static void logical_context_fini(struct drm_i915_gem_context *ctx)
 {
+	struct drm_device *dev = ctx->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_context *last;
+	int i;
+	int ret = 0;
+
+	if (WARN_ON(!mutex_is_locked(&dev->struct_mutex)))
+		return;
+
+	if (ctx == dev_priv->default_context)
+		return;
+
+	for (i = 0; i < I915_NUM_RINGS; i++) {
+		struct intel_ring_buffer *ring = &dev_priv->ring[i];
+		if (!ring->context_switch)
+			continue;
+
+		if (!(ctx->ring_enable & (1 << i)))
+			continue;
+
+		if (ring->last_context != ctx)
+			continue;
 
+		/*
+		 * XXX We can prevent restoring contexts, but not saving them
+		 * so if we're going to take away our backing context object
+		 * of the last context, we have to switch now.
+		 */
+
+		DRM_DEBUG_DRIVER("Switching to default context\n");
+		last = ring->context_switch(ring, dev_priv->default_context,
+					    0, I915_CONTEXT_NORMAL_SWITCH);
+		if (!last) {
+			DRM_ERROR("Couldn't switch back to default context\n");
+			continue;
+		}
+
+		BUG_ON(last != ctx);
+		ret = wait_for_context_switch(ring);
+		if (ret)
+			DRM_ERROR("Wait for default context switch failed "
+				  "ring = %d (%d)", i, ret);
+		i915_release_context(last);
+	}
 }
 
 static int logical_context_free(struct drm_file *file, uint32_t id)
@@ -304,24 +349,40 @@ static int logical_context_free(struct drm_file *file, uint32_t id)
 }
 
 /**
- * i915_context_create_ioctl() - not yet supported
+ * i915_context_create_ioctl()
  */
 int i915_context_create_ioctl(struct drm_device *dev, void *data,
 			      struct drm_file *file)
 {
 	struct drm_i915_gem_context_create *args = data;
-	args->ctx_id = 0;
-	return -EIO;
+	struct drm_i915_gem_context *out_ctx = NULL;
+	int ret = 0;
+
+	mutex_lock(&dev->struct_mutex);
+	ret = logical_context_alloc(dev, file, args->ring_mask, &out_ctx);
+	mutex_unlock(&dev->struct_mutex);
+	if (ret == 0) {
+		args->ctx_id = out_ctx->id;
+		if (WARN_ON(args->ctx_id == DEFAULT_CONTEXT_ID))
+			return -ENXIO;
+		args->ring_enable = out_ctx->ring_enable;
+	}
+
+	return ret;
 }
 
 /**
- * i915_context_destroy_ioctl() - not yet supported
+ * i915_context_destroy_ioctl()
  */
 int i915_context_destroy_ioctl(struct drm_device *dev, void *data,
 			       struct drm_file *file)
 {
 	struct drm_i915_gem_context_destroy *args = data;
-	return -EINVAL;
+
+	if (args->ctx_id == DEFAULT_CONTEXT_ID)
+		return -EINVAL;
+
+	return logical_context_free(file, args->ctx_id);
 }
 
 /**
@@ -370,18 +431,55 @@ void i915_context_unload(struct drm_device *dev)
 
 void i915_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->contexts_disabled)
+		return;
 
+	idr_init(&file_priv->context_idr);
+	spin_lock_init(&file_priv->context_idr_lock);
 }
 
 void i915_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->contexts_disabled)
+		return;
 
+	idr_for_each(&file_priv->context_idr, context_idr_cleanup, file);
+	idr_destroy(&file_priv->context_idr);
+}
+
+static int context_idr_cleanup(int id, void *p, void *data)
+{
+	struct drm_file *file = (struct drm_file *) data;
+	logical_context_free(file, id);
+	return 0;
 }
 
 struct drm_i915_gem_context *i915_get_context(struct drm_file *file,
 					      uint32_t id)
 {
-	return NULL;
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct drm_i915_gem_context *ctx = NULL;
+	int ret;
+
+	spin_lock(&file_priv->context_idr_lock);
+	ctx = idr_find(&file_priv->context_idr, id);
+	if (ctx) {
+		drm_gem_object_reference(&ctx->obj->base);
+		ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false);
+		if (ret) {
+			drm_gem_object_unreference(&ctx->obj->base);
+			ctx = NULL;
+		}
+	}
+	spin_unlock(&file_priv->context_idr_lock);
+
+	return ctx;
 }
 
 void i915_release_context(struct drm_i915_gem_context *ctx)
-- 
1.7.3.4

      parent reply	other threads:[~2011-02-26 18:30 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-26 18:30 [RFC] [PATCH 0/8] drm/i915/context Ben Widawsky
2011-02-26 18:30 ` [RFC] [PATCH 1/8] drm/i915/context: CXT_SIZE register offset added Ben Widawsky
2011-02-26 18:30 ` [RFC] [PATCH 2/8] drm/i915/context: Preliminary context support Ben Widawsky
2011-02-26 18:30 ` [RFC] [PATCH 3/8] drm/i915/context: implement load and unload Ben Widawsky
2011-02-26 18:30 ` [RFC] [PATCH 4/8] drm/i915/context: logical context free Ben Widawsky
2011-02-26 18:30 ` [RFC] [PATCH 5/8] drm/i915/context: implement context switch wait Ben Widawsky
2011-02-26 18:30 ` [RFC] [PATCH 6/8] drm/i915/context: context init implementation Ben Widawsky
2011-02-26 18:30 ` [RFC] [PATCH 7/8] drm/i915/context: context switch implementation Ben Widawsky
2011-02-26 18:30 ` Ben Widawsky [this message]

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=1298745018-5937-9-git-send-email-bwidawsk@gmail.com \
    --to=bwidawsk@gmail.com \
    --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.