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

Commit d9d117e4 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/ringbuffer: Serialize load of PD_DIR



After triggering the mm switch with a load of PD_DIR, which may be
deferred unto the MI_SET_CONTEXT on rcs, serialise the next commands
with that load by posting a read of PD_DIR (or else those subsequent
commands may access the stale page tables).

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180611171825.13678-2-chris@chris-wilson.co.uk
parent 68a85703
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -499,7 +499,8 @@ void intel_engine_setup_common(struct intel_engine_cs *engine)
	intel_engine_init_cmd_parser(engine);
}

int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
int intel_engine_create_scratch(struct intel_engine_cs *engine,
				unsigned int size)
{
	struct drm_i915_gem_object *obj;
	struct i915_vma *vma;
@@ -533,7 +534,7 @@ int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
	return ret;
}

static void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
{
	i915_vma_unpin_and_release(&engine->scratch);
}
+37 −12
Original line number Diff line number Diff line
@@ -1361,8 +1361,9 @@ intel_ring_context_pin(struct intel_engine_cs *engine,

static int intel_init_ring_buffer(struct intel_engine_cs *engine)
{
	struct intel_ring *ring;
	struct i915_timeline *timeline;
	struct intel_ring *ring;
	unsigned int size;
	int err;

	intel_engine_setup_common(engine);
@@ -1388,12 +1389,21 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
	GEM_BUG_ON(engine->buffer);
	engine->buffer = ring;

	err = intel_engine_init_common(engine);
	size = PAGE_SIZE;
	if (HAS_BROKEN_CS_TLB(engine->i915))
		size = I830_WA_SIZE;
	err = intel_engine_create_scratch(engine, size);
	if (err)
		goto err_unpin;

	err = intel_engine_init_common(engine);
	if (err)
		goto err_scratch;

	return 0;

err_scratch:
	intel_engine_cleanup_scratch(engine);
err_unpin:
	intel_ring_unpin(ring);
err_ring:
@@ -1455,6 +1465,25 @@ static int load_pd_dir(struct i915_request *rq,
	return 0;
}

static int flush_pd_dir(struct i915_request *rq)
{
	const struct intel_engine_cs * const engine = rq->engine;
	u32 *cs;

	cs = intel_ring_begin(rq, 4);
	if (IS_ERR(cs))
		return PTR_ERR(cs);

	/* Stall until the page table load is complete */
	*cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
	*cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
	*cs++ = i915_ggtt_offset(engine->scratch);
	*cs++ = MI_NOOP;

	intel_ring_advance(rq, cs);
	return 0;
}

static inline int mi_set_context(struct i915_request *rq, u32 flags)
{
	struct drm_i915_private *i915 = rq->i915;
@@ -1638,6 +1667,12 @@ static int switch_context(struct i915_request *rq)
			goto err_mm;
	}

	if (ppgtt) {
		ret = flush_pd_dir(rq);
		if (ret)
			goto err_mm;
	}

	if (ctx->remap_slice) {
		for (i = 0; i < MAX_L3_SLICES; i++) {
			if (!(ctx->remap_slice & BIT(i)))
@@ -2158,16 +2193,6 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
	if (ret)
		return ret;

	if (INTEL_GEN(dev_priv) >= 6) {
		ret = intel_engine_create_scratch(engine, PAGE_SIZE);
		if (ret)
			return ret;
	} else if (HAS_BROKEN_CS_TLB(dev_priv)) {
		ret = intel_engine_create_scratch(engine, I830_WA_SIZE);
		if (ret)
			return ret;
	}

	return 0;
}

+4 −1
Original line number Diff line number Diff line
@@ -869,9 +869,12 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno);

void intel_engine_setup_common(struct intel_engine_cs *engine);
int intel_engine_init_common(struct intel_engine_cs *engine);
int intel_engine_create_scratch(struct intel_engine_cs *engine, int size);
void intel_engine_cleanup_common(struct intel_engine_cs *engine);

int intel_engine_create_scratch(struct intel_engine_cs *engine,
				unsigned int size);
void intel_engine_cleanup_scratch(struct intel_engine_cs *engine);

int intel_init_render_ring_buffer(struct intel_engine_cs *engine);
int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
int intel_init_blt_ring_buffer(struct intel_engine_cs *engine);