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

Commit 531958f6 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/gt: Track timeline activeness in enter/exit



Lift moving the timeline to/from the active_list on enter/exit in order
to shorten the active tracking span in comparison to the existing
pin/unpin.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190815205709.24285-1-chris@chris-wilson.co.uk
parent bfc4c359
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ static void i915_gem_park(struct drm_i915_private *i915)
	for_each_engine(engine, i915, id)
		call_idle_barriers(engine); /* cleanup after wedging */

	intel_timelines_park(i915);
	i915_vma_parked(i915);

	i915_globals_park();
+2 −0
Original line number Diff line number Diff line
@@ -280,10 +280,12 @@ int __init i915_global_context_init(void)
void intel_context_enter_engine(struct intel_context *ce)
{
	intel_engine_pm_get(ce->engine);
	intel_timeline_enter(ce->timeline);
}

void intel_context_exit_engine(struct intel_context *ce)
{
	intel_timeline_exit(ce->timeline);
	intel_engine_pm_put(ce->engine);
}

+2 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
		/* Context switch failed, hope for the best! Maybe reset? */
		return true;

	intel_timeline_enter(rq->timeline);

	/* Check again on the next retirement. */
	engine->wakeref_serial = engine->serial + 1;
	i915_request_add_active_barriers(rq);
+4 −0
Original line number Diff line number Diff line
@@ -3306,6 +3306,8 @@ static void virtual_context_enter(struct intel_context *ce)

	for (n = 0; n < ve->num_siblings; n++)
		intel_engine_pm_get(ve->siblings[n]);

	intel_timeline_enter(ce->timeline);
}

static void virtual_context_exit(struct intel_context *ce)
@@ -3313,6 +3315,8 @@ static void virtual_context_exit(struct intel_context *ce)
	struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
	unsigned int n;

	intel_timeline_exit(ce->timeline);

	for (n = 0; n < ve->num_siblings; n++)
		intel_engine_pm_put(ve->siblings[n]);
}
+36 −62
Original line number Diff line number Diff line
@@ -278,64 +278,11 @@ void intel_timelines_init(struct drm_i915_private *i915)
	timelines_init(&i915->gt);
}

static void timeline_add_to_active(struct intel_timeline *tl)
{
	struct intel_gt_timelines *gt = &tl->gt->timelines;

	mutex_lock(&gt->mutex);
	list_add(&tl->link, &gt->active_list);
	mutex_unlock(&gt->mutex);
}

static void timeline_remove_from_active(struct intel_timeline *tl)
{
	struct intel_gt_timelines *gt = &tl->gt->timelines;

	mutex_lock(&gt->mutex);
	list_del(&tl->link);
	mutex_unlock(&gt->mutex);
}

static void timelines_park(struct intel_gt *gt)
{
	struct intel_gt_timelines *timelines = &gt->timelines;
	struct intel_timeline *timeline;

	mutex_lock(&timelines->mutex);
	list_for_each_entry(timeline, &timelines->active_list, link) {
		/*
		 * All known fences are completed so we can scrap
		 * the current sync point tracking and start afresh,
		 * any attempt to wait upon a previous sync point
		 * will be skipped as the fence was signaled.
		 */
		i915_syncmap_free(&timeline->sync);
	}
	mutex_unlock(&timelines->mutex);
}

/**
 * intel_timelines_park - called when the driver idles
 * @i915: the drm_i915_private device
 *
 * When the driver is completely idle, we know that all of our sync points
 * have been signaled and our tracking is then entirely redundant. Any request
 * to wait upon an older sync point will be completed instantly as we know
 * the fence is signaled and therefore we will not even look them up in the
 * sync point map.
 */
void intel_timelines_park(struct drm_i915_private *i915)
{
	timelines_park(&i915->gt);
}

void intel_timeline_fini(struct intel_timeline *timeline)
{
	GEM_BUG_ON(timeline->pin_count);
	GEM_BUG_ON(!list_empty(&timeline->requests));

	i915_syncmap_free(&timeline->sync);

	if (timeline->hwsp_cacheline)
		cacheline_free(timeline->hwsp_cacheline);
	else
@@ -370,6 +317,7 @@ int intel_timeline_pin(struct intel_timeline *tl)
	if (tl->pin_count++)
		return 0;
	GEM_BUG_ON(!tl->pin_count);
	GEM_BUG_ON(tl->active_count);

	err = i915_vma_pin(tl->hwsp_ggtt, 0, 0, PIN_GLOBAL | PIN_HIGH);
	if (err)
@@ -380,7 +328,6 @@ int intel_timeline_pin(struct intel_timeline *tl)
		offset_in_page(tl->hwsp_offset);

	cacheline_acquire(tl->hwsp_cacheline);
	timeline_add_to_active(tl);

	return 0;

@@ -389,6 +336,40 @@ int intel_timeline_pin(struct intel_timeline *tl)
	return err;
}

void intel_timeline_enter(struct intel_timeline *tl)
{
	struct intel_gt_timelines *timelines = &tl->gt->timelines;

	GEM_BUG_ON(!tl->pin_count);
	if (tl->active_count++)
		return;
	GEM_BUG_ON(!tl->active_count); /* overflow? */

	mutex_lock(&timelines->mutex);
	list_add(&tl->link, &timelines->active_list);
	mutex_unlock(&timelines->mutex);
}

void intel_timeline_exit(struct intel_timeline *tl)
{
	struct intel_gt_timelines *timelines = &tl->gt->timelines;

	GEM_BUG_ON(!tl->active_count);
	if (--tl->active_count)
		return;

	mutex_lock(&timelines->mutex);
	list_del(&tl->link);
	mutex_unlock(&timelines->mutex);

	/*
	 * Since this timeline is idle, all bariers upon which we were waiting
	 * must also be complete and so we can discard the last used barriers
	 * without loss of information.
	 */
	i915_syncmap_free(&tl->sync);
}

static u32 timeline_advance(struct intel_timeline *tl)
{
	GEM_BUG_ON(!tl->pin_count);
@@ -546,16 +527,9 @@ void intel_timeline_unpin(struct intel_timeline *tl)
	if (--tl->pin_count)
		return;

	timeline_remove_from_active(tl);
	GEM_BUG_ON(tl->active_count);
	cacheline_release(tl->hwsp_cacheline);

	/*
	 * Since this timeline is idle, all bariers upon which we were waiting
	 * must also be complete and so we can discard the last used barriers
	 * without loss of information.
	 */
	i915_syncmap_free(&tl->sync);

	__i915_vma_unpin(tl->hwsp_ggtt);
}

Loading