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

oscar.mateo at intel.com oscar.mateo at intel.com
Fri May 9 14:08:53 CEST 2014


From: Oscar Mateo <oscar.mateo at 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 at 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 --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 *
-- 
1.9.0




More information about the Intel-gfx mailing list