From: Ben Widawsky <bwidawsk@gmail.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 9/9] drm/i915/context: Insert MI_SET_CONTEXT in ringbuffer context switch
Date: Tue, 1 Feb 2011 10:16:26 -0800 [thread overview]
Message-ID: <1296584186-20446-10-git-send-email-bwidawsk@gmail.com> (raw)
In-Reply-To: <1296584186-20446-1-git-send-email-bwidawsk@gmail.com>
Added ringbuffer code to initiate context switch. The context switch can
fail since intel_ring_begin() can fail, and I am not sure how to handle
that yet. In most cases a context switch failure is pretty much fatal.
Modified the locking on deinit, which had a race (though results were
not fatal, just slower).
Fixed execbuffer to pass default_context when there is no context
specified by userspace.
---
drivers/gpu/drm/i915/i915_context.c | 28 ++++++++++++-----
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 13 +++++--
drivers/gpu/drm/i915/intel_ringbuffer.c | 46 ++++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +-
4 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_context.c b/drivers/gpu/drm/i915/i915_context.c
index 4f255fb..6674a9d 100644
--- a/drivers/gpu/drm/i915/i915_context.c
+++ b/drivers/gpu/drm/i915/i915_context.c
@@ -81,7 +81,7 @@ i915_context_validate(struct drm_device *dev, struct drm_file *file,
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
struct drm_i915_gem_context *ctx;
- int i, ret = 0;
+ int i;
ctx = i915_context_lookup_id(dev, ctx_id);
if (ctx == NULL) {
@@ -261,21 +261,32 @@ static void i915_context_hw_init(struct drm_device *dev,
mutex_unlock(&dev->struct_mutex);
}
-static void i915_context_hw_deinit(struct drm_device *dev,
+static int i915_context_hw_deinit(struct drm_device *dev,
struct drm_i915_gem_context *ctx,
struct intel_ring_buffer *ring)
{
+ int ret;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
/* 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.
*/
- struct drm_i915_private *dev_priv = dev->dev_private;
+ mutex_lock(&dev->struct_mutex);
if (ring->last_context == ctx && ctx != dev_priv->default_context) {
- mutex_lock(&dev->struct_mutex);
- ring->context_switch(ring, dev_priv->default_context,
- I915_CONTEXT_NORMAL_SWITCH);
- mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG_DRIVER("Switching to default context\n");
+ ret = ring->context_switch(ring, dev_priv->default_context,
+ I915_CONTEXT_NORMAL_SWITCH);
+ if (ret) {
+ DRM_ERROR("Couldn't switch back to default context\n");
+ goto out;
+ }
+ ring->last_context = dev_priv->default_context;
}
+
+out:
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
static int
@@ -428,7 +439,8 @@ void i915_context_init(struct drm_device *dev)
dev_priv->ctx_disable = 1;
idr_destroy(&dev_priv->i915_ctx_idr);
} else {
- DRM_DEBUG_DRIVER("Context support enabled\n", ret);
+ DRM_DEBUG_DRIVER("Default context = %p\n",
+ to_intel_bo(dev_priv->default_context->ctx_obj)->gtt_offset);
}
}
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 9d022fb..c1d9a0a 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -990,7 +990,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_gem_object *batch_obj;
struct drm_clip_rect *cliprects = NULL;
struct intel_ring_buffer *ring;
- struct drm_i915_gem_context *ctx;
+ struct drm_i915_gem_context *ctx = NULL;
u32 exec_start, exec_len;
u32 seqno;
u32 ctx_id;
@@ -1013,7 +1013,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
DRM_DEBUG_DRIVER("Context resubmission required\n");
return -EIO;
}
- }
+ } else
+ ctx = dev_priv->default_context;
+
#if WATCH_EXEC
DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
(int) args->buffers_ptr, args->buffer_count, args->batch_len);
@@ -1203,8 +1205,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}
}
- if (!dev_priv->ctx_disable)
- ring->context_switch(ring, ctx, I915_CONTEXT_NORMAL_SWITCH);
+ if (!dev_priv->ctx_disable) {
+ ret = ring->context_switch(ring, ctx, I915_CONTEXT_NORMAL_SWITCH);
+ if (ret)
+ goto err;
+ }
exec_start = batch_obj->gtt_offset + args->batch_start_offset;
exec_len = args->batch_len;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 89adb9d..4381730 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -750,15 +750,55 @@ render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
return 0;
}
-static void
+static int
render_ring_ctx_switch(struct intel_ring_buffer *ring,
struct drm_i915_gem_context *ctx,
- uint32_t flags)
+ u32 flags)
{
+ struct drm_device *dev = ring->dev;
+ struct drm_gem_object *obj;
+ uint32_t ctx_switch_flags;
+ int ret = 0;
+
if (ring->last_context == ctx)
- return;
+ return 0;
+
+ DRM_DEBUG_DRIVER("Context switch to %d\n",
+ ctx->ctx_id);
ring->last_context = ctx;
+ obj = ctx->ctx_obj;
+
+ if (flags == I915_CONTEXT_SAVE_ONLY)
+ ctx_switch_flags = MI_RESTORE_INHIBIT;
+ else
+ ctx_switch_flags = 0;
+
+ ret = intel_ring_begin(ring, 4);
+ if (ret)
+ return ret;
+
+ if (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev))
+ intel_ring_emit(ring, MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN);
+ else
+ intel_ring_emit(ring, MI_NOOP);
+
+ intel_ring_emit(ring, MI_SET_CONTEXT);
+ intel_ring_emit(ring, to_intel_bo(obj)->gtt_offset |
+ MI_MM_SPACE_GTT |
+ MI_SAVE_EXT_STATE_EN |
+ MI_RESTORE_EXT_STATE_EN |
+ ctx_switch_flags);
+
+ if (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev))
+ intel_ring_emit(ring, MI_SUSPEND_FLUSH);
+ /* TODO: we may need a NOOP here */
+ else
+ intel_ring_emit(ring, MI_NOOP);
+
+ intel_ring_advance(ring);
+
+ return 0;
}
static void cleanup_status_page(struct intel_ring_buffer *ring)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 61525ba..e8f8b6a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -80,7 +80,7 @@ struct intel_ring_buffer {
u32 offset, u32 length);
void (*cleanup)(struct intel_ring_buffer *ring);
struct drm_i915_gem_context *last_context;
- void (*context_switch)(struct intel_ring_buffer *ring,
+ int (*context_switch)(struct intel_ring_buffer *ring,
struct drm_i915_gem_context *ctx,
u32 flags);
--
1.7.3.4
prev parent reply other threads:[~2011-02-01 18:18 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-01 18:16 [PATCH 0/9] drm/1915/context (i915HW Context support, early) Ben Widawsky
2011-02-01 18:16 ` [PATCH 1/9] drm/i915/context: context switch, and PPGTT params Ben Widawsky
2011-02-01 18:31 ` Jesse Barnes
2011-02-01 18:16 ` [PATCH 2/9] drm/i915/context: basic implementation context ioctls Ben Widawsky
2011-02-01 18:45 ` Chris Wilson
2011-02-01 18:16 ` [PATCH 3/9] drm/i915/context: context initialization/destruction Ben Widawsky
2011-02-01 18:16 ` [PATCH 4/9] drm/i915/context: whitespace cleanup, and warning cleanup Ben Widawsky
2011-02-01 18:16 ` [PATCH 5/9] drm/i915/context: switch context support query to variable Ben Widawsky
2011-02-01 18:16 ` [PATCH 6/9] drm/i915/context: minimal support for contexts in execbuffer2 Ben Widawsky
2011-02-01 18:16 ` [PATCH 7/9] drm/i915/context: context validation for execbuffer2 Ben Widawsky
2011-02-01 18:16 ` [PATCH 8/9] drm/i915/context: enable calling context_switch Ben Widawsky
2011-02-01 18:16 ` 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=1296584186-20446-10-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.