Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84c2377f authored by Oscar Mateo's avatar Oscar Mateo Committed by Daniel Vetter
Browse files

drm/i915/bdw: Allocate ringbuffers for Logical Ring Contexts



As we have said a couple of times by now, logical ring contexts have
their own ringbuffers: not only the backing pages, but the whole
management struct.

In a previous version of the series, this was achieved with two separate
patches:
drm/i915/bdw: Allocate ringbuffer backing objects for default global LRC
drm/i915/bdw: Allocate ringbuffer for user-created LRCs

Signed-off-by: default avatarOscar Mateo <oscar.mateo@intel.com>
Reviewed-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 8c857917
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -635,6 +635,7 @@ struct intel_context {
	/* Execlists */
	/* Execlists */
	struct {
	struct {
		struct drm_i915_gem_object *state;
		struct drm_i915_gem_object *state;
		struct intel_ringbuffer *ringbuf;
	} engine[I915_NUM_RINGS];
	} engine[I915_NUM_RINGS];


	struct list_head link;
	struct list_head link;
+38 −0
Original line number Original line Diff line number Diff line
@@ -65,7 +65,11 @@ void intel_lr_context_free(struct intel_context *ctx)


	for (i = 0; i < I915_NUM_RINGS; i++) {
	for (i = 0; i < I915_NUM_RINGS; i++) {
		struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state;
		struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state;
		struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf;

		if (ctx_obj) {
		if (ctx_obj) {
			intel_destroy_ringbuffer_obj(ringbuf);
			kfree(ringbuf);
			i915_gem_object_ggtt_unpin(ctx_obj);
			i915_gem_object_ggtt_unpin(ctx_obj);
			drm_gem_object_unreference(&ctx_obj->base);
			drm_gem_object_unreference(&ctx_obj->base);
		}
		}
@@ -99,6 +103,7 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
	struct drm_device *dev = ring->dev;
	struct drm_device *dev = ring->dev;
	struct drm_i915_gem_object *ctx_obj;
	struct drm_i915_gem_object *ctx_obj;
	uint32_t context_size;
	uint32_t context_size;
	struct intel_ringbuffer *ringbuf;
	int ret;
	int ret;


	WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL);
	WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL);
@@ -119,6 +124,39 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
		return ret;
		return ret;
	}
	}


	ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL);
	if (!ringbuf) {
		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);
		ret = -ENOMEM;
		return ret;
	}

	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_alloc_ringbuffer_obj(dev, ringbuf);
	if (ret) {
		DRM_DEBUG_DRIVER("Failed to allocate ringbuffer obj %s: %d\n",
				ring->name, ret);
		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].state = ctx_obj;
	ctx->engine[ring->id].state = ctx_obj;


	return 0;
	return 0;
+3 −3
Original line number Original line Diff line number Diff line
@@ -1519,7 +1519,7 @@ static int init_phys_status_page(struct intel_engine_cs *ring)
	return 0;
	return 0;
}
}


static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
{
{
	if (!ringbuf->obj)
	if (!ringbuf->obj)
		return;
		return;
@@ -1530,7 +1530,7 @@ static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
	ringbuf->obj = NULL;
	ringbuf->obj = NULL;
}
}


static int intel_alloc_ringbuffer_obj(struct drm_device *dev,
int intel_alloc_ringbuffer_obj(struct drm_device *dev,
			       struct intel_ringbuffer *ringbuf)
			       struct intel_ringbuffer *ringbuf)
{
{
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct drm_i915_private *dev_priv = to_i915(dev);
+4 −0
Original line number Original line Diff line number Diff line
@@ -355,6 +355,10 @@ intel_write_status_page(struct intel_engine_cs *ring,
#define I915_GEM_HWS_SCRATCH_INDEX	0x30
#define I915_GEM_HWS_SCRATCH_INDEX	0x30
#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)


void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
int intel_alloc_ringbuffer_obj(struct drm_device *dev,
			       struct intel_ringbuffer *ringbuf);

void intel_stop_ring_buffer(struct intel_engine_cs *ring);
void intel_stop_ring_buffer(struct intel_engine_cs *ring);
void intel_cleanup_ring_buffer(struct intel_engine_cs *ring);
void intel_cleanup_ring_buffer(struct intel_engine_cs *ring);