intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/i915/gt: Set unused mocs entry to follow PTE on tgl as on all others
@ 2019-10-22 11:51 Chris Wilson
  2019-10-22 11:51 ` [PATCH 2/4] drm/i915/gt: Tidy up debug-warns for the mocs control table Chris Wilson
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Chris Wilson @ 2019-10-22 11:51 UTC (permalink / raw)
  To: intel-gfx

Be consistent in our mocs setup on Tigerlake and set the unused control
value to follow the PTE entry as we previously have done. The unused
values are beyond the defines of the ABI, the consistency simplifies our
checking.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/intel_mocs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c
index 5bac3966906b..aea3896cc139 100644
--- a/drivers/gpu/drm/i915/gt/intel_mocs.c
+++ b/drivers/gpu/drm/i915/gt/intel_mocs.c
@@ -482,7 +482,7 @@ static void intel_mocs_init_global(struct intel_gt *gt)
 	for (; index < table.n_entries; index++)
 		intel_uncore_write(uncore,
 				   GEN12_GLOBAL_MOCS(index),
-				   table.table[0].control_value);
+				   table.table[I915_MOCS_PTE].control_value);
 }
 
 void intel_mocs_init(struct intel_gt *gt)
-- 
2.24.0.rc0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread
* [PATCH] drm/i915/selftests: Add coverage of mocs registers
@ 2019-10-18 12:06 Chris Wilson
  2019-10-18 14:09 ` Kumar Valsan, Prathap
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2019-10-18 12:06 UTC (permalink / raw)
  To: intel-gfx

Probe the mocs registers for new contexts and across GPU resets. Similar
to intel_workarounds, we have tables of what register values we expect
to see, so verify that user contexts are affected by them. In the
future, we should add tests similar to intel_sseu to cover dynamic
reconfigurations.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Prathap Kumar Valsan <prathap.kumar.valsan@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 drivers/gpu/drm/i915/gt/intel_mocs.c          |   4 +
 drivers/gpu/drm/i915/gt/selftest_mocs.c       | 431 ++++++++++++++++++
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 3 files changed, 436 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gt/selftest_mocs.c

diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c
index 5bac3966906b..f5a239640553 100644
--- a/drivers/gpu/drm/i915/gt/intel_mocs.c
+++ b/drivers/gpu/drm/i915/gt/intel_mocs.c
@@ -490,3 +490,7 @@ void intel_mocs_init(struct intel_gt *gt)
 	if (HAS_GLOBAL_MOCS_REGISTERS(gt->i915))
 		intel_mocs_init_global(gt);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_mocs.c"
+#endif
diff --git a/drivers/gpu/drm/i915/gt/selftest_mocs.c b/drivers/gpu/drm/i915/gt/selftest_mocs.c
new file mode 100644
index 000000000000..94c1c638621b
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_mocs.c
@@ -0,0 +1,431 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "gt/intel_engine_pm.h"
+#include "i915_selftest.h"
+
+#include "gem/selftests/mock_context.h"
+#include "selftests/igt_reset.h"
+#include "selftests/igt_spinner.h"
+
+struct live_mocs {
+	struct drm_i915_mocs_table table;
+	struct i915_gem_context *ctx;
+	struct i915_vma *scratch;
+	void *vaddr;
+};
+
+static int request_add_sync(struct i915_request *rq, int err)
+{
+	i915_request_get(rq);
+	i915_request_add(rq);
+	if (i915_request_wait(rq, 0, HZ / 5) < 0)
+		err = -ETIME;
+	i915_request_put(rq);
+
+	return err;
+}
+
+static int request_add_spin(struct i915_request *rq, struct igt_spinner *spin)
+{
+	int err = 0;
+
+	i915_request_get(rq);
+	i915_request_add(rq);
+	if (spin && !igt_wait_for_spinner(spin, rq))
+		err = -ETIME;
+	i915_request_put(rq);
+
+	return err;
+}
+
+static struct i915_vma *create_scratch(struct intel_gt *gt)
+{
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	int err;
+
+	obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	i915_gem_object_set_cache_coherency(obj, I915_CACHING_CACHED);
+
+	vma = i915_vma_instance(obj, &gt->ggtt->vm, NULL);
+	if (IS_ERR(vma)) {
+		i915_gem_object_put(obj);
+		return vma;
+	}
+
+	err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
+	if (err) {
+		i915_gem_object_put(obj);
+		return ERR_PTR(err);
+	}
+
+	return vma;
+}
+
+static int live_mocs_init(struct live_mocs *arg, struct intel_gt *gt)
+{
+	int err;
+
+	if (!get_mocs_settings(gt->i915, &arg->table))
+		return -EINVAL;
+
+	arg->ctx = kernel_context(gt->i915);
+	if (!arg->ctx)
+		return -ENOMEM;
+
+	arg->scratch = create_scratch(gt);
+	if (IS_ERR(arg->scratch)) {
+		err = PTR_ERR(arg->scratch);
+		goto err_ctx;
+	}
+
+	arg->vaddr = i915_gem_object_pin_map(arg->scratch->obj, I915_MAP_WB);
+	if (IS_ERR(arg->vaddr)) {
+		err = PTR_ERR(arg->vaddr);
+		goto err_scratch;
+	}
+
+	return 0;
+
+err_scratch:
+	i915_vma_unpin_and_release(&arg->scratch, 0);
+err_ctx:
+	kernel_context_close(arg->ctx);
+	return err;
+}
+
+static void live_mocs_fini(struct live_mocs *arg)
+{
+	i915_vma_unpin_and_release(&arg->scratch, I915_VMA_RELEASE_MAP);
+	kernel_context_close(arg->ctx);
+}
+
+static int read_mocs_table(struct i915_request *rq,
+			   const struct drm_i915_mocs_table *table,
+			   struct i915_vma *vma, int *offset)
+{
+	unsigned int i;
+	u32 *cs;
+
+	cs = intel_ring_begin(rq, 4 * table->n_entries);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+
+	for (i = 0; i < table->n_entries; i++) {
+		*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+		*cs++ = i915_mmio_reg_offset(HAS_GLOBAL_MOCS_REGISTERS(rq->i915) ?
+					     GEN12_GLOBAL_MOCS(i) :
+					     mocs_register(rq->engine, i));
+		*cs++ = i915_ggtt_offset(vma) + i * sizeof(u32) + *offset;
+		*cs++ = 0;
+	}
+
+	intel_ring_advance(rq, cs);
+	*offset += i * sizeof(u32);
+
+	return 0;
+}
+
+static int read_l3cc_table(struct i915_request *rq,
+			   const struct drm_i915_mocs_table *table,
+			   struct i915_vma *vma, int *offset)
+{
+	unsigned int i;
+	u32 *cs;
+
+	cs = intel_ring_begin(rq, 4 * table->n_entries / 2);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+
+	/* XXX can't read the MCR range 0xb00 directly */
+	for (i = 0; i < table->n_entries / 2; i++) {
+		*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+		*cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i));
+		*cs++ = i915_ggtt_offset(vma) + i * sizeof(u32) + *offset;
+		*cs++ = 0;
+	}
+
+	intel_ring_advance(rq, cs);
+	*offset += i * sizeof(u32);
+
+	return 0;
+}
+
+static int check_mocs_table(struct intel_engine_cs *engine,
+			    const struct drm_i915_mocs_table *table,
+			    const u32 *vaddr, int *offset)
+{
+	unsigned int i;
+	u32 expect;
+
+	for (i = 0; i < table->size; i++) {
+		if (HAS_GLOBAL_MOCS_REGISTERS(engine->i915))
+			expect = table->table[i].control_value;
+		else
+			expect = get_entry_control(table, i);
+		if (vaddr[*offset] != expect) {
+			pr_err("%s: Invalid MOCS[%d] entry, found %08x, expected %08x\n",
+			       engine->name, i, vaddr[*offset], expect);
+			return -EINVAL;
+		}
+		++*offset;
+	}
+
+	/* All remaining entries are default */
+	if (HAS_GLOBAL_MOCS_REGISTERS(engine->i915))
+		expect = table->table[0].control_value;
+	else
+		expect = table->table[I915_MOCS_PTE].control_value;
+	for (; i < table->n_entries; i++) {
+		if (vaddr[*offset] != expect) {
+			pr_err("%s: Invalid MOCS[%d*] entry, found %08x, expected %08x\n",
+			       engine->name, i, vaddr[*offset], expect);
+			return -EINVAL;
+		}
+		++*offset;
+	}
+
+	return 0;
+}
+
+static int check_l3cc_table(struct intel_engine_cs *engine,
+			    const struct drm_i915_mocs_table *table,
+			    const u32 *vaddr, int *offset)
+{
+	u16 unused_value = table->table[I915_MOCS_PTE].l3cc_value;
+	unsigned int i;
+	u32 expect;
+
+	if (1) { /* XXX skip MCR read back */
+		*offset += table->n_entries / 2;
+		return 0;
+	}
+
+	for (i = 0; i < table->size / 2; i++) {
+		u16 low = get_entry_l3cc(table, 2 * i);
+		u16 high = get_entry_l3cc(table, 2 * i + 1);
+
+		expect = l3cc_combine(table, low, high);
+		if (vaddr[*offset] != expect) {
+			pr_err("%s: Invalid L3CC[%d] entry, found %08x, expected %08x\n",
+			       engine->name, i, vaddr[*offset], expect);
+			return -EINVAL;
+		}
+		++*offset;
+	}
+
+	/* Odd table size - 1 left over */
+	if (table->size & 1) {
+		u16 low = get_entry_l3cc(table, 2 * i);
+
+		expect = l3cc_combine(table, low, unused_value);
+		if (vaddr[*offset] != expect) {
+			pr_err("%s: Invalid L3CC[%d] entry, found %08x, expected %08x\n",
+			       engine->name, i, vaddr[*offset], expect);
+			return -EINVAL;
+		}
+		++*offset;
+		i++;
+	}
+
+	/* All remaining entries are also unused */
+	for (; i < table->n_entries / 2; i++) {
+		expect = l3cc_combine(table, unused_value, unused_value);
+		if (vaddr[*offset] != expect) {
+			pr_err("%s: Invalid L3CC[%d] entry, found %08x, expected %08x\n",
+			       engine->name, i, vaddr[*offset], expect);
+			return -EINVAL;
+		}
+		++*offset;
+	}
+
+	return 0;
+}
+
+static int check_mocs_engine(struct live_mocs *arg,
+			     struct intel_context *ce)
+{
+	struct i915_vma *vma = arg->scratch;
+	struct i915_request *rq;
+	int offset;
+	int err;
+
+	memset32(arg->vaddr, STACK_MAGIC, PAGE_SIZE / sizeof(u32));
+
+	rq = intel_context_create_request(ce);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	i915_vma_lock(vma);
+	err = i915_request_await_object(rq, vma->obj, true);
+	if (!err)
+		err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
+	i915_vma_unlock(vma);
+
+	offset = 0;
+	if (!err)
+		err = read_mocs_table(rq, &arg->table, vma, &offset);
+	if (!err && ce->engine->class == RENDER_CLASS)
+		err = read_l3cc_table(rq, &arg->table, vma, &offset);
+
+	err = request_add_sync(rq, err);
+	if (err)
+		return err;
+
+	offset = 0;
+	if (!err)
+		err = check_mocs_table(ce->engine, &arg->table,
+				       arg->vaddr, &offset);
+	if (!err && ce->engine->class == RENDER_CLASS)
+		err = check_l3cc_table(ce->engine, &arg->table,
+				       arg->vaddr, &offset);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int live_mocs_clean(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	struct live_mocs mocs;
+	int err;
+
+	err = live_mocs_init(&mocs, gt);
+	if (err)
+		return err;
+
+	for_each_engine(engine, gt, id) {
+		struct intel_context *ce;
+
+		ce = intel_context_create(engine->kernel_context->gem_context,
+					  engine);
+		if (IS_ERR(ce)) {
+			err = PTR_ERR(ce);
+			break;
+		}
+
+		err = check_mocs_engine(&mocs, ce);
+		intel_context_put(ce);
+		if (err)
+			break;
+	}
+
+	live_mocs_fini(&mocs);
+
+	return err;
+}
+
+static int active_engine_reset(struct intel_context *ce,
+			       const char *reason)
+{
+	struct igt_spinner spin;
+	struct i915_request *rq;
+	int err;
+
+	err = igt_spinner_init(&spin, ce->engine->gt);
+	if (err)
+		return err;
+
+	rq = igt_spinner_create_request(&spin, ce, MI_NOOP);
+	if (IS_ERR(rq)) {
+		igt_spinner_fini(&spin);
+		return PTR_ERR(rq);
+	}
+
+	err = request_add_spin(rq, &spin);
+	if (err == 0)
+		err = intel_engine_reset(ce->engine, reason);
+
+	igt_spinner_end(&spin);
+	igt_spinner_fini(&spin);
+
+	return err;
+}
+
+static int __live_mocs_reset(struct live_mocs *mocs,
+			     struct intel_context *ce)
+{
+	int err;
+
+	err = intel_engine_reset(ce->engine, "mocs");
+	if (err)
+		return err;
+
+	err = check_mocs_engine(mocs, ce);
+	if (err)
+		return err;
+
+	err = active_engine_reset(ce, "mocs");
+	if (err)
+		return err;
+
+	err = check_mocs_engine(mocs, ce);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int live_mocs_reset(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	struct live_mocs mocs;
+	int err = 0;
+
+	if (!intel_has_reset_engine(gt))
+		return 0;
+
+	err = live_mocs_init(&mocs, gt);
+	if (err)
+		return err;
+
+	igt_global_reset_lock(gt);
+	for_each_engine(engine, gt, id) {
+		struct intel_context *ce;
+
+		ce = intel_context_create(engine->kernel_context->gem_context,
+					  engine);
+		if (IS_ERR(ce)) {
+			err = PTR_ERR(ce);
+			break;
+		}
+
+		intel_engine_pm_get(engine);
+		err = __live_mocs_reset(&mocs, ce);
+		intel_engine_pm_put(engine);
+
+		intel_context_put(ce);
+		if (err)
+			break;
+	}
+	igt_global_reset_unlock(gt);
+
+	live_mocs_fini(&mocs);
+	return err;
+}
+
+int intel_mocs_live_selftests(struct drm_i915_private *i915)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(live_mocs_clean),
+		SUBTEST(live_mocs_reset),
+	};
+	struct drm_i915_mocs_table table;
+
+	if (!get_mocs_settings(i915, &table))
+		return 0;
+
+	return intel_gt_live_subtests(tests, &i915->gt);
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 6daf6599ec79..1a6abcffce81 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -16,6 +16,7 @@ selftest(gt_engines, intel_engine_live_selftests)
 selftest(gt_timelines, intel_timeline_live_selftests)
 selftest(gt_contexts, intel_context_live_selftests)
 selftest(gt_lrc, intel_lrc_live_selftests)
+selftest(gt_mocs, intel_mocs_live_selftests)
 selftest(gt_pm, intel_gt_pm_live_selftests)
 selftest(requests, i915_request_live_selftests)
 selftest(active, i915_active_live_selftests)
-- 
2.23.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread
* [PATCH] drm/i915/selftests: Add coverage of mocs registers
@ 2019-10-17  8:01 Chris Wilson
  2019-10-17  9:27 ` Chris Wilson
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2019-10-17  8:01 UTC (permalink / raw)
  To: intel-gfx

Probe the mocs registers for new contexts and across GPU resets. Similar
to intel_workarounds, we have tables of what register values we expect
to see, so verify that user contexts are affected by them. In the
future, we should add tests similar to intel_sseu to cover dynamic
reconfigurations.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Prathap Kumar Valsan <prathap.kumar.valsan@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_mocs.c          |   4 +
 drivers/gpu/drm/i915/gt/selftest_mocs.c       | 309 ++++++++++++++++++
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 3 files changed, 314 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gt/selftest_mocs.c

diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c
index 5bac3966906b..f5a239640553 100644
--- a/drivers/gpu/drm/i915/gt/intel_mocs.c
+++ b/drivers/gpu/drm/i915/gt/intel_mocs.c
@@ -490,3 +490,7 @@ void intel_mocs_init(struct intel_gt *gt)
 	if (HAS_GLOBAL_MOCS_REGISTERS(gt->i915))
 		intel_mocs_init_global(gt);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_mocs.c"
+#endif
diff --git a/drivers/gpu/drm/i915/gt/selftest_mocs.c b/drivers/gpu/drm/i915/gt/selftest_mocs.c
new file mode 100644
index 000000000000..0aac3b1ab846
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_mocs.c
@@ -0,0 +1,309 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_selftest.h"
+
+#include "gem/selftests/mock_context.h"
+#include "selftests/igt_reset.h"
+#include "selftests/igt_spinner.h"
+
+struct live_mocs {
+	struct drm_i915_mocs_table table;
+	struct i915_gem_context *ctx;
+	struct i915_vma *scratch;
+	void *vaddr;
+};
+
+static int request_add_sync(struct i915_request *rq, int err)
+{
+	i915_request_get(rq);
+	i915_request_add(rq);
+	if (i915_request_wait(rq, 0, HZ / 5) < 0)
+		err = -ETIME;
+	i915_request_put(rq);
+
+	return err;
+}
+
+static int request_add_spin(struct i915_request *rq, struct igt_spinner *spin)
+{
+	int err = 0;
+
+	i915_request_get(rq);
+	i915_request_add(rq);
+	if (spin && !igt_wait_for_spinner(spin, rq))
+		err = -ETIME;
+	i915_request_put(rq);
+
+	return err;
+}
+
+static struct i915_vma *create_scratch(struct intel_gt *gt)
+{
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	int err;
+
+	obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	i915_gem_object_set_cache_coherency(obj, I915_CACHING_CACHED);
+
+	vma = i915_vma_instance(obj, &gt->ggtt->vm, NULL);
+	if (IS_ERR(vma)) {
+		i915_gem_object_put(obj);
+		return vma;
+	}
+
+	err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
+	if (err) {
+		i915_gem_object_put(obj);
+		return ERR_PTR(err);
+	}
+
+	return vma;
+}
+
+static int live_mocs_init(struct live_mocs *arg, struct intel_gt *gt)
+{
+	int err;
+
+	if (!get_mocs_settings(gt->i915, &arg->table))
+		return -EINVAL;
+
+	arg->ctx = kernel_context(gt->i915);
+	if (!arg->ctx)
+		return -ENOMEM;
+
+	arg->scratch = create_scratch(gt);
+	if (IS_ERR(arg->scratch)) {
+		err = PTR_ERR(arg->scratch);
+		goto err_ctx;
+	}
+
+	arg->vaddr = i915_gem_object_pin_map(arg->scratch->obj, I915_MAP_WB);
+	if (IS_ERR(arg->vaddr)) {
+		err = PTR_ERR(arg->vaddr);
+		goto err_scratch;
+	}
+
+	return 0;
+
+err_scratch:
+	i915_vma_put(arg->scratch);
+err_ctx:
+	kernel_context_close(arg->ctx);
+	return err;
+}
+
+static void live_mocs_fini(struct live_mocs *arg)
+{
+	i915_vma_unpin_and_release(&arg->scratch, I915_VMA_RELEASE_MAP);
+	kernel_context_close(arg->ctx);
+}
+
+static int read_mocs_table(struct i915_request *rq,
+			   const struct drm_i915_mocs_table *table,
+			   struct i915_vma *vma)
+{
+	unsigned int i;
+	int err;
+	u32 *cs;
+
+	i915_vma_lock(vma);
+	err = i915_request_await_object(rq, vma->obj, true);
+	if (!err)
+		err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
+	i915_vma_unlock(vma);
+	if (err)
+		return err;
+
+	cs = intel_ring_begin(rq, 4 * table->n_entries);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+
+	for (i = 0; i < table->n_entries; i++) {
+		*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+		*cs++ = i915_mmio_reg_offset(HAS_GLOBAL_MOCS_REGISTERS(rq->i915) ?
+					     GEN12_GLOBAL_MOCS(i) :
+					     mocs_register(rq->engine, i));
+		*cs++ = i915_ggtt_offset(vma) + i * sizeof(u32);
+		*cs++ = 0;
+	}
+
+	intel_ring_advance(rq, cs);
+
+	return 0;
+}
+
+static int check_mocs_table(struct intel_engine_cs *engine,
+			    const struct drm_i915_mocs_table *table,
+			    const u32 *vaddr)
+{
+	unsigned int i;
+	u32 expect;
+
+	for (i = 0; i < table->size; i++) {
+		if (HAS_GLOBAL_MOCS_REGISTERS(engine->i915))
+			expect = table->table[i].control_value;
+		else
+			expect = get_entry_control(table, i);
+
+		if (vaddr[i] != expect) {
+			pr_err("%s: Invalid MOCS[%d] entry, found %08x, expected %08x\n",
+			       engine->name, i, vaddr[i], expect);
+			return -EINVAL;
+		}
+	}
+
+	/* All remaining entries are default */
+	if (HAS_GLOBAL_MOCS_REGISTERS(engine->i915))
+		expect = table->table[0].control_value;
+	else
+		expect = table->table[I915_MOCS_PTE].control_value;
+	for (; i < table->n_entries; i++) {
+		if (vaddr[i] != expect) {
+			pr_err("%s: Invalid MOCS[%d*] entry, found %08x, expected %08x\n",
+			       engine->name, i, vaddr[i], expect);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int check_mocs_engine(struct live_mocs *arg,
+			     struct intel_context *ce)
+{
+	struct i915_request *rq;
+	int err;
+
+	memset32(arg->vaddr, STACK_MAGIC, PAGE_SIZE/sizeof(u32));
+
+	rq = intel_context_create_request(ce);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	err = read_mocs_table(rq, &arg->table, arg->scratch);
+
+	err = request_add_sync(rq, err);
+	if(err)
+		return err;
+
+	return check_mocs_table(ce->engine, &arg->table, arg->vaddr);
+}
+
+static int live_mocs_clean(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct i915_gem_engines_iter it;
+	struct intel_context *ce;
+	struct live_mocs mocs;
+	int err;
+
+	err = live_mocs_init(&mocs, gt);
+	if (err)
+		return err;
+
+	/* XXX for_each_engine(gt) once we can create raw intel_context */
+	for_each_gem_engine(ce, i915_gem_context_engines(mocs.ctx), it) {
+		err = check_mocs_engine(&mocs, ce);
+		if (err)
+			break;
+	}
+	i915_gem_context_unlock_engines(mocs.ctx);
+
+	live_mocs_fini(&mocs);
+
+	return err;
+}
+
+static int active_engine_reset(struct intel_context *ce,
+			       const char *reason)
+{
+	struct igt_spinner spin;
+	struct i915_request *rq;
+	int err;
+
+	err = igt_spinner_init(&spin, ce->engine->gt);
+	if (err)
+		return err;
+
+	rq = igt_spinner_create_request(&spin, ce, MI_NOOP);
+	if (IS_ERR(rq)) {
+		igt_spinner_fini(&spin);
+		return PTR_ERR(rq);
+	}
+
+	err = request_add_spin(rq, &spin);
+	if (err == 0)
+		err = intel_engine_reset(ce->engine, reason);
+
+	igt_spinner_end(&spin);
+	igt_spinner_fini(&spin);
+
+	return err;
+
+}
+static int live_mocs_reset(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct i915_gem_engines_iter it;
+	struct intel_context *ce;
+	intel_wakeref_t wakeref;
+	struct live_mocs mocs;
+	int err = 0;
+
+	if (!intel_has_reset_engine(gt))
+		return 0;
+
+	err = live_mocs_init(&mocs, gt);
+	if (err)
+		return err;
+
+	igt_global_reset_lock(gt);
+	wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+	for_each_gem_engine(ce, i915_gem_context_engines(mocs.ctx), it) {
+		err = intel_engine_reset(ce->engine, "mocs");
+		if (err)
+			break;
+
+		err = check_mocs_engine(&mocs, ce);
+		if (err)
+			break;
+
+		err = active_engine_reset(ce, "mocs");
+		if (err)
+			break;
+
+		err = check_mocs_engine(&mocs, ce);
+		if (err)
+			break;
+	}
+	i915_gem_context_unlock_engines(mocs.ctx);
+
+	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
+	igt_global_reset_unlock(gt);
+
+	live_mocs_fini(&mocs);
+	return err;
+}
+
+int intel_mocs_live_selftests(struct drm_i915_private *i915)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(live_mocs_clean),
+		SUBTEST(live_mocs_reset),
+	};
+	struct drm_i915_mocs_table table;
+
+	if (!get_mocs_settings(i915, &table))
+		return 0;
+
+	return intel_gt_live_subtests(tests, &i915->gt);
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 6daf6599ec79..1a6abcffce81 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -16,6 +16,7 @@ selftest(gt_engines, intel_engine_live_selftests)
 selftest(gt_timelines, intel_timeline_live_selftests)
 selftest(gt_contexts, intel_context_live_selftests)
 selftest(gt_lrc, intel_lrc_live_selftests)
+selftest(gt_mocs, intel_mocs_live_selftests)
 selftest(gt_pm, intel_gt_pm_live_selftests)
 selftest(requests, i915_request_live_selftests)
 selftest(active, i915_active_live_selftests)
-- 
2.23.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2019-10-24 16:44 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-10-22 11:51 [PATCH 1/4] drm/i915/gt: Set unused mocs entry to follow PTE on tgl as on all others Chris Wilson
2019-10-22 11:51 ` [PATCH 2/4] drm/i915/gt: Tidy up debug-warns for the mocs control table Chris Wilson
2019-10-22 11:51 ` [PATCH 3/4] drm/i915/gt: Refactor mocs loops into single control macro Chris Wilson
2019-10-22 11:51 ` [PATCH 4/4] drm/i915/selftests: Add coverage of mocs registers Chris Wilson
2019-10-22 11:57   ` [PATCH] " Chris Wilson
2019-10-23 21:03     ` Kumar Valsan, Prathap
2019-10-23 21:03       ` [Intel-gfx] " Kumar Valsan, Prathap
2019-10-24  7:13       ` Chris Wilson
2019-10-24  7:13         ` [Intel-gfx] " Chris Wilson
2019-10-24 17:01         ` Kumar Valsan, Prathap
2019-10-24 17:01           ` [Intel-gfx] " Kumar Valsan, Prathap
2019-10-22 19:28 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/4] drm/i915/gt: Set unused mocs entry to follow PTE on tgl as on all others (rev2) Patchwork
2019-10-22 19:55 ` ✓ Fi.CI.BAT: success " Patchwork
2019-10-23 11:00 ` ✓ Fi.CI.IGT: " Patchwork
2019-10-23 11:00   ` [Intel-gfx] " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2019-10-18 12:06 [PATCH] drm/i915/selftests: Add coverage of mocs registers Chris Wilson
2019-10-18 14:09 ` Kumar Valsan, Prathap
2019-10-17  8:01 Chris Wilson
2019-10-17  9:27 ` Chris Wilson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).