@@ -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)
@@ -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;
@@ -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 *