Commit 65fcb806 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Move timeline from GTT to ring



In the future, we want to move a request between engines. To achieve
this, we first realise that we have two timelines in effect here. The
first runs through the GTT is required for ordering vma access, which is
tracked currently by engine. The second is implied by sequential
execution of commands inside the ringbuffer. This timeline is one that
maps to userspace's expectations when submitting requests (i.e. given the
same context, batch A is executed before batch B). As the rings's
timelines map to userspace and the GTT timeline an implementation
detail, move the timeline from the GTT into the ring itself (per-context
in logical-ring-contexts/execlists, or a global per-engine timeline for
the shared ringbuffers in legacy submission.

The two timelines are still assumed to be equivalent at the moment (no
migrating requests between engines yet) and so we can simply move from
one to the other without adding extra ordering.

v2: Reinforce that one isn't allowed to mix the engine execution
timeline with the client timeline from userspace (on the ring).

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180502163839.3248-1-chris@chris-wilson.co.uk
parent 81cf8b74
Loading
Loading
Loading
Loading
+2 −11
Original line number Diff line number Diff line
@@ -2059,7 +2059,8 @@ struct drm_i915_private {
		void (*resume)(struct drm_i915_private *);
		void (*cleanup_engine)(struct intel_engine_cs *engine);

		struct i915_gem_timeline global_timeline;
		struct i915_gem_timeline execution_timeline;
		struct i915_gem_timeline legacy_timeline;
		struct list_head timelines;

		struct list_head active_rings;
@@ -3235,16 +3236,6 @@ i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
	return ctx;
}

static inline struct intel_timeline *
i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
				 struct intel_engine_cs *engine)
{
	struct i915_address_space *vm;

	vm = ctx->ppgtt ? &ctx->ppgtt->base : &ctx->i915->ggtt.base;
	return &vm->timeline.engine[engine->id];
}

int i915_perf_open_ioctl(struct drm_device *dev, void *data,
			 struct drm_file *file);
int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
+5 −4
Original line number Diff line number Diff line
@@ -3110,10 +3110,10 @@ static void engine_skip_context(struct i915_request *request)
{
	struct intel_engine_cs *engine = request->engine;
	struct i915_gem_context *hung_ctx = request->ctx;
	struct intel_timeline *timeline;
	struct intel_timeline *timeline = request->timeline;
	unsigned long flags;

	timeline = i915_gem_context_lookup_timeline(hung_ctx, engine);
	GEM_BUG_ON(timeline == engine->timeline);

	spin_lock_irqsave(&engine->timeline->lock, flags);
	spin_lock(&timeline->lock);
@@ -3782,7 +3782,7 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)

		ret = wait_for_engines(i915);
	} else {
		ret = wait_for_timeline(&i915->gt.global_timeline, flags);
		ret = wait_for_timeline(&i915->gt.execution_timeline, flags);
	}

	return ret;
@@ -5652,7 +5652,8 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
	WARN_ON(dev_priv->mm.object_count);

	mutex_lock(&dev_priv->drm.struct_mutex);
	i915_gem_timeline_fini(&dev_priv->gt.global_timeline);
	i915_gem_timeline_fini(&dev_priv->gt.legacy_timeline);
	i915_gem_timeline_fini(&dev_priv->gt.execution_timeline);
	WARN_ON(!list_empty(&dev_priv->gt.timelines));
	mutex_unlock(&dev_priv->drm.struct_mutex);

+14 −1
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
	lockdep_assert_held(&ctx->i915->drm.struct_mutex);
	GEM_BUG_ON(!i915_gem_context_is_closed(ctx));

	i915_gem_timeline_free(ctx->timeline);
	i915_ppgtt_put(ctx->ppgtt);

	for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++) {
@@ -376,6 +377,18 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
		ctx->desc_template = default_desc_template(dev_priv, ppgtt);
	}

	if (HAS_EXECLISTS(dev_priv)) {
		struct i915_gem_timeline *timeline;

		timeline = i915_gem_timeline_create(dev_priv, ctx->name);
		if (IS_ERR(timeline)) {
			__destroy_hw_context(ctx, file_priv);
			return ERR_CAST(timeline);
		}

		ctx->timeline = timeline;
	}

	trace_i915_context_create(ctx);

	return ctx;
@@ -584,7 +597,7 @@ static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
	list_for_each_entry(timeline, &engine->i915->gt.timelines, link) {
		struct intel_timeline *tl;

		if (timeline == &engine->i915->gt.global_timeline)
		if (timeline == &engine->i915->gt.execution_timeline)
			continue;

		tl = &timeline->engine[engine->id];
+2 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ struct i915_gem_context {
	/** file_priv: owning file descriptor */
	struct drm_i915_file_private *file_priv;

	struct i915_gem_timeline *timeline;

	/**
	 * @ppgtt: unique address space (GTT)
	 *
+0 −3
Original line number Diff line number Diff line
@@ -2111,8 +2111,6 @@ static void i915_address_space_init(struct i915_address_space *vm,
				    struct drm_i915_private *dev_priv,
				    const char *name)
{
	i915_gem_timeline_init(dev_priv, &vm->timeline, name);

	drm_mm_init(&vm->mm, 0, vm->total);
	vm->mm.head_node.color = I915_COLOR_UNEVICTABLE;

@@ -2129,7 +2127,6 @@ static void i915_address_space_fini(struct i915_address_space *vm)
	if (pagevec_count(&vm->free_pages))
		vm_free_pages_release(vm, true);

	i915_gem_timeline_fini(&vm->timeline);
	drm_mm_takedown(&vm->mm);
	list_del(&vm->global_link);
}
Loading