diff mbox

[23/50] drm/i915/bdw: Allocate ringbuffer for user-created LRCs

Message ID 1399637360-4277-24-git-send-email-oscar.mateo@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

oscar.mateo@intel.com May 9, 2014, 12:08 p.m. UTC
From: Oscar Mateo <oscar.mateo@intel.com>

As we said earlier, logical ring contexts created by the user have their
own ringbuffer: not only the backing pages, but the whole management struct.

Since this is now ready, we use the context ringbuffer or the engine's
default ringbuffer depending on whether LRCs are enabled or not.

This patch replaces a similar patch in the early series called:
"drm/i915/bdw: Prepare for user-created LR contexts"

Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c |  5 +++-
 drivers/gpu/drm/i915/intel_lrc.c        | 45 +++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_ringbuffer.c |  8 ++++--
 3 files changed, 42 insertions(+), 16 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 76314e3..e4e616d 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -200,8 +200,11 @@  void i915_gem_context_free(struct kref *ctx_ref)
 			drm_gem_object_unreference(&ctx_obj->base);
 		}
 
-		if (ringbuf)
+		if (ringbuf) {
 			intel_destroy_ring_buffer(ringbuf);
+			if (ctx->file_priv)
+				kfree(ringbuf);
+		}
 	}
 
 	if (ppgtt)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 64d40e4..0f2c5cb 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -74,6 +74,7 @@  int gen8_create_lr_context(struct i915_hw_context *ctx,
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_gem_object *ctx_obj;
 	uint32_t context_size;
+	struct intel_ringbuffer *ringbuf;
 	int ret;
 
 	if (ctx->engine[ring->id].obj)
@@ -95,25 +96,43 @@  int gen8_create_lr_context(struct i915_hw_context *ctx,
 		return ret;
 	}
 
-	if (!file_priv) {
-		ring->default_ringbuf.size = 32 * PAGE_SIZE;
-
-		/* TODO: For now we put this in the mappable region so that we can reuse
-		 * the existing ringbuffer code which ioremaps it. When we start
-		 * creating many contexts, this will no longer work and we must switch
-		 * to a kmapish interface.
-		 */
-		ret = intel_allocate_ring_buffer(dev, &ring->default_ringbuf);
-		if (ret) {
-			DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s: %d\n",
-					ring->name, ret);
+	if (file_priv) {
+		ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL);
+		if (!ringbuf) {
+			ret = -ENOMEM;
+			DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s\n",
+					ring->name);
 			i915_gem_object_ggtt_unpin(ctx_obj);
 			drm_gem_object_unreference(&ctx_obj->base);
 			return ret;
 		}
-		ctx->engine[ring->id].ringbuf = &ring->default_ringbuf;
+	} else
+		ringbuf = &ring->default_ringbuf;
+
+	ringbuf->size = 32 * PAGE_SIZE;
+	ringbuf->effective_size = ringbuf->size;
+	ringbuf->head = 0;
+	ringbuf->tail = 0;
+	ringbuf->space = ringbuf->size;
+	ringbuf->last_retired_head = -1;
+
+	/* TODO: For now we put this in the mappable region so that we can reuse
+	 * the existing ringbuffer code which ioremaps it. When we start
+	 * creating many contexts, this will no longer work and we must switch
+	 * to a kmapish interface.
+	 */
+	ret = intel_allocate_ring_buffer(dev, ringbuf);
+	if (ret) {
+		DRM_DEBUG_DRIVER("Failed to allocate ringbuffer obj %s: %d\n",
+				ring->name, ret);
+		if (file_priv)
+			kfree(ringbuf);
+		i915_gem_object_ggtt_unpin(ctx_obj);
+		drm_gem_object_unreference(&ctx_obj->base);
+		return ret;
 	}
 
+	ctx->engine[ring->id].ringbuf = ringbuf;
 	ctx->engine[ring->id].obj = ctx_obj;
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index e7f61d9..8b0260d 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1709,8 +1709,12 @@  static int __intel_ring_prepare(struct intel_engine *ring,
 struct intel_ringbuffer *
 intel_ringbuffer_get(struct intel_engine *ring, struct i915_hw_context *ctx)
 {
-	/* For the time being, the only ringbuffer is in the engine */
-	return &ring->default_ringbuf;
+	struct drm_i915_private *dev_priv = to_i915(ring->dev);
+
+	if (dev_priv->lrc_enabled)
+		return ctx->engine[ring->id].ringbuf;
+	else
+		return &ring->default_ringbuf;
 }
 
 struct intel_ringbuffer *