All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH igt v3 1/2] lib/gt: Mark up engine classes
@ 2017-11-06 10:49 Chris Wilson
  2017-11-06 10:49 ` [PATCH igt v3 2/2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
  2017-11-06 11:07 ` ✗ Fi.CI.BAT: failure for series starting with [v3,1/2] lib/gt: Mark up engine classes Patchwork
  0 siblings, 2 replies; 3+ messages in thread
From: Chris Wilson @ 2017-11-06 10:49 UTC (permalink / raw)
  To: intel-gfx

We introduce the concept of classes that each engine may belong to.
There may be more than one engine available in each class, but each
engine only belongs to one class. Each class has a unique set of
capabilities and purpose (e.g. 3D rendering or video decode), but
different engines within each class may have different features (e.g.
only the first decoder instance may have the full set of fixed function
blocks, but most of the work can still be offload onto the other decoders
which shared the same ISA etc).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 lib/igt_gt.c | 16 ++++++++--------
 lib/igt_gt.h |  7 +++++++
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 89727d22..e8272d29 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -578,14 +578,14 @@ unsigned intel_detect_and_clear_missed_interrupts(int fd)
 }
 
 const struct intel_execution_engine intel_execution_engines[] = {
-	{ "default", NULL, 0, 0 },
-	{ "render", "rcs0", I915_EXEC_RENDER, 0 },
-	{ "bsd", "vcs0", I915_EXEC_BSD, 0 },
-	{ "bsd1", "vcs0", I915_EXEC_BSD, 1<<13 /*I915_EXEC_BSD_RING1*/ },
-	{ "bsd2", "vcs1", I915_EXEC_BSD, 2<<13 /*I915_EXEC_BSD_RING2*/ },
-	{ "blt", "bcs0", I915_EXEC_BLT, 0 },
-	{ "vebox", "vecs0", I915_EXEC_VEBOX, 0 },
-	{ NULL, 0, 0 }
+	{ "default", NULL, 0, LOCAL_ENGINE_CLASS_OTHER, 0 },
+	{ "render", "rcs0", I915_EXEC_RENDER, LOCAL_ENGINE_CLASS_RENDER, 0 },
+	{ "bsd", "vcs0", I915_EXEC_BSD, LOCAL_ENGINE_CLASS_VIDEO, 0 },
+	{ "bsd1", "vcs0", I915_EXEC_BSD, LOCAL_ENGINE_CLASS_VIDEO, 1<<13 /*I915_EXEC_BSD_RING1*/ },
+	{ "bsd2", "vcs1", I915_EXEC_BSD, LOCAL_ENGINE_CLASS_VIDEO, 2<<13 /*I915_EXEC_BSD_RING2*/ },
+	{ "blt", "bcs0", I915_EXEC_BLT, LOCAL_ENGINE_CLASS_COPY, 0 },
+	{ "vebox", "vecs0", I915_EXEC_VEBOX, LOCAL_ENGINE_CLASS_VIDEO_ENHANCE, 0 },
+	{ NULL }
 };
 
 bool gem_can_store_dword(int fd, unsigned int engine)
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index 2579cbd3..264efce2 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -63,10 +63,17 @@ void igt_clflush_range(void *addr, int size);
 
 unsigned intel_detect_and_clear_missed_interrupts(int fd);
 
+#define LOCAL_ENGINE_CLASS_OTHER		0
+#define LOCAL_ENGINE_CLASS_RENDER		1
+#define LOCAL_ENGINE_CLASS_COPY			2
+#define LOCAL_ENGINE_CLASS_VIDEO		3
+#define LOCAL_ENGINE_CLASS_VIDEO_ENHANCE	4
+
 extern const struct intel_execution_engine {
 	const char *name;
 	const char *full_name;
 	unsigned exec_id;
+	unsigned class_id;
 	unsigned flags;
 } intel_execution_engines[];
 
-- 
2.15.0

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

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

* [PATCH igt v3 2/2] igt/gem_ctx_isolation: Check isolation of registers between contexts
  2017-11-06 10:49 [PATCH igt v3 1/2] lib/gt: Mark up engine classes Chris Wilson
@ 2017-11-06 10:49 ` Chris Wilson
  2017-11-06 11:07 ` ✗ Fi.CI.BAT: failure for series starting with [v3,1/2] lib/gt: Mark up engine classes Patchwork
  1 sibling, 0 replies; 3+ messages in thread
From: Chris Wilson @ 2017-11-06 10:49 UTC (permalink / raw)
  To: intel-gfx

A new context assumes that all of its registers are in the default state
when it is created. What may happen is that a register written by one
context may leak into the second, causing mass confusion.

v2: extend back to Sandybridge, ignore non-priv registers that are not
context-saved (remind me what this test is all about!!!)
v3: Check context preserves registers across suspend/hibernate and
resets.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 tests/Makefile.sources    |   1 +
 tests/gem_ctx_isolation.c | 775 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/gem_exec_fence.c    |   2 +-
 3 files changed, 777 insertions(+), 1 deletion(-)
 create mode 100644 tests/gem_ctx_isolation.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 2313c12b..9a25a8b5 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -56,6 +56,7 @@ TESTS_progs = \
 	gem_ctx_basic \
 	gem_ctx_create \
 	gem_ctx_exec \
+	gem_ctx_isolation \
 	gem_ctx_param \
 	gem_ctx_switch \
 	gem_ctx_thrash \
diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
new file mode 100644
index 00000000..a8269991
--- /dev/null
+++ b/tests/gem_ctx_isolation.c
@@ -0,0 +1,775 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+#include "igt_dummyload.h"
+
+#define MAX_REG 0x40000
+#define NUM_REGS (MAX_REG / sizeof(uint32_t))
+
+#define PAGE_ALIGN(x) ALIGN(x, 4096)
+
+#define DIRTY1 0x1
+#define DIRTY2 0x2
+#define UNSAFE 0x4
+#define RESET 0x8
+
+enum {
+	RCS_MASK = 0x1,
+	BCS_MASK = 0x2,
+	VCS_MASK = 0x4,
+	VECS_MASK = 0x8,
+};
+
+#define ALL ~0u
+#define GEN_RANGE(x, y) ((ALL >> (32 - (y - x + 1))) << x)
+#define GEN6 (ALL << 6)
+#define GEN7 (ALL << 7)
+#define GEN8 (ALL << 8)
+#define GEN9 (ALL << 9)
+
+#define NOCTX 0
+
+#define LAST_KNOWN_GEN 10
+
+static const struct named_register {
+	const char *name;
+	unsigned int gen_mask;
+	unsigned int engine_mask;
+	uint32_t offset;
+	uint32_t count;
+} safe_registers[] = {
+	{ "NOPID", NOCTX, RCS_MASK, 0x2094 },
+	{ "MI_PREDICATE_RESULT_2", NOCTX, RCS_MASK, 0x23bc },
+	{ "INSTPM", GEN8, RCS_MASK, 0x20c0 },
+	{ "IA_VERTICES_COUNT", GEN6, RCS_MASK, 0x2310, 2 },
+	{ "IA_PRIMITIVES_COUNT", GEN6, RCS_MASK, 0x2318, 2 },
+	{ "VS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2320, 2 },
+	{ "HS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2300, 2 },
+	{ "DS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2308, 2 },
+	{ "GS_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2328, 2 },
+	{ "GS_PRIMITIVES_COUNT", GEN6, RCS_MASK, 0x2330, 2 },
+	{ "CL_INVOCATION_COUNT", GEN6, RCS_MASK, 0x2338, 2 },
+	{ "CL_PRIMITIVES_COUNT", GEN6, RCS_MASK, 0x2340, 2 },
+	{ "PS_INVOCATION_COUNT_0", GEN6, RCS_MASK, 0x22c8, 2 },
+	{ "PS_DEPTH_COUNT_0", GEN6, RCS_MASK, 0x22d8, 2 },
+	{ "GPUGPU_DISPATCHDIMX", GEN8, RCS_MASK, 0x2500 },
+	{ "GPUGPU_DISPATCHDIMY", GEN8, RCS_MASK, 0x2504 },
+	{ "GPUGPU_DISPATCHDIMZ", GEN8, RCS_MASK, 0x2508 },
+	{ "MI_PREDICATE_SRC0", GEN8, RCS_MASK, 0x2400, 2 },
+	{ "MI_PREDICATE_SRC1", GEN8, RCS_MASK, 0x2408, 2 },
+	{ "MI_PREDICATE_DATA", GEN8, RCS_MASK, 0x2410, 2 },
+	{ "MI_PRED_RESULT", GEN8, RCS_MASK, 0x2418 },
+	{ "3DPRIM_END_OFFSET", GEN6, RCS_MASK, 0x2420 },
+	{ "3DPRIM_START_VERTEX", GEN6, RCS_MASK, 0x2430 },
+	{ "3DPRIM_VERTEX_COUNT", GEN6, RCS_MASK, 0x2434 },
+	{ "3DPRIM_INSTANCE_COUNT", GEN6, RCS_MASK, 0x2438 },
+	{ "3DPRIM_START_INSTANCE", GEN6, RCS_MASK, 0x243c },
+	{ "3DPRIM_BASE_VERTEX", GEN6, RCS_MASK, 0x2440 },
+	{ "GPGPU_THREADS_DISPATCHED", GEN8, RCS_MASK, 0x2290, 2 },
+	{ "PS_INVOCATION_COUNT_1", GEN8, RCS_MASK, 0x22f0, 2 },
+	{ "PS_DEPTH_COUNT_1", GEN8, RCS_MASK, 0x22f8, 2 },
+	{ "BB_OFFSET", GEN8, RCS_MASK, 0x2158 },
+	{ "MI_PREDICATE_RESULT_1", GEN8, RCS_MASK, 0x241c },
+	{ "CS_GPR", GEN8, RCS_MASK, 0x2600, 32 },
+	{ "OA_CTX_CONTROL", GEN8, RCS_MASK, 0x2360 },
+	{ "OACTXID", GEN8, RCS_MASK, 0x2364 },
+	{ "PS_INVOCATION_COUNT_2", GEN8, RCS_MASK, 0x2448, 2 },
+	{ "PS_DEPTH_COUNT_2", GEN8, RCS_MASK, 0x2450, 2 },
+	{ "Cache_Mode_0", GEN7, RCS_MASK, 0x7000 },
+	{ "Cache_Mode_1", GEN7, RCS_MASK, 0x7004 },
+	{ "GT_MODE", GEN8, RCS_MASK, 0x7008 },
+	{ "L3_Config", GEN7, RCS_MASK, 0x7034 },
+	{ "TD_CTL", GEN8, RCS_MASK, 0xe400 },
+	{ "TD_CTL2", GEN8, RCS_MASK, 0xe404 },
+	{ "SO_NUM_PRIMS_WRITEN0", GEN6, RCS_MASK, 0x5200, 2 },
+	{ "SO_NUM_PRIMS_WRITEN1", GEN6, RCS_MASK, 0x5208, 2 },
+	{ "SO_NUM_PRIMS_WRITEN2", GEN6, RCS_MASK, 0x5210, 2 },
+	{ "SO_NUM_PRIMS_WRITEN3", GEN6, RCS_MASK, 0x5218, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED0", GEN6, RCS_MASK, 0x5240, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED1", GEN6, RCS_MASK, 0x5248, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED2", GEN6, RCS_MASK, 0x5250, 2 },
+	{ "SO_PRIM_STORAGE_NEEDED3", GEN6, RCS_MASK, 0x5258, 2 },
+	{ "SO_WRITE_OFFSET0", GEN7, RCS_MASK, 0x5280 },
+	{ "SO_WRITE_OFFSET1", GEN7, RCS_MASK, 0x5284 },
+	{ "SO_WRITE_OFFSET2", GEN7, RCS_MASK, 0x5288 },
+	{ "SO_WRITE_OFFSET3", GEN7, RCS_MASK, 0x528c },
+	{ "OA_CONTROL", NOCTX, RCS_MASK, 0x2b00 },
+	{ "PERF_CNT_1", NOCTX, RCS_MASK, 0x91b8, 2 },
+	{ "PERF_CNT_2", NOCTX, RCS_MASK, 0x91c0, 2 },
+
+	/* Privileged (enabled by w/a + FORCE_TO_NONPRIV) */
+	{ "CTX_PREEMPT", NOCTX /* GEN_RANGE(9, 10) */, RCS_MASK, 0x2248 },
+	{ "CS_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x2580 },
+	{ "HDC_CHICKEN1", GEN_RANGE(9, 10), RCS_MASK, 0x7304 },
+	{ "L3SQREG1", GEN8, RCS_MASK, 0xb010 },
+
+	{ "BCS_GPR", GEN9, BCS_MASK, 0x22600, 32 },
+	{ "BCS_SWCTRL", GEN8, BCS_MASK, 0x22200 },
+
+	{ "VCS0_GPR", GEN9, VCS_MASK, 0x12600, 32 },
+	{ "MFC_VDBOX1", NOCTX, VCS_MASK, 0x12800, 64 },
+
+	{ "VCS1_GPR", GEN9, VCS_MASK, 0x1c600, 32 },
+	{ "MFC_VDBOX2", NOCTX, VCS_MASK, 0x1c800, 64 },
+
+	{ "VECS_GPR", GEN9, VECS_MASK, 0x1a600, 32 },
+
+	{}
+}, ignore_registers[] = {
+	{ "RCS timestamp", GEN6, RCS_MASK, 0x2358 },
+	{ "VCS0 timestamp", GEN7, VCS_MASK, 0x12358 },
+	{ "VCS1 timestamp", GEN7, VCS_MASK, 0x1c358 },
+	{ "BCS timestamp", GEN7, BCS_MASK, 0x22358 },
+	{ "VECS timestamp", GEN8, VECS_MASK, 0x1a358 },
+	{}
+};
+
+static const char *register_name(uint32_t offset, char *buf, size_t len)
+{
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		unsigned int width = r->count ? 4*r->count : 4;
+		if (offset >= r->offset && offset < r->offset + width) {
+			if (r->count <= 1)
+				return r->name;
+
+			snprintf(buf, len, "%s[%d]",
+				 r->name, (offset - r->offset)/4);
+			return buf;
+		}
+	}
+
+	return "unknown";
+}
+
+static bool ignore_register(uint32_t offset)
+{
+	for (const struct named_register *r = ignore_registers; r->name; r++) {
+		unsigned int width = r->count ? 4*r->count : 4;
+		if (offset >= r->offset && offset < r->offset + width)
+			return true;
+	}
+
+	return false;
+}
+
+static uint32_t read_regs(int fd,
+			  uint32_t ctx, unsigned int engine,
+			  unsigned int flags)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	const bool r64b = gen >= 8;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry *reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int regs_size, batch_size;
+	unsigned int engine_bit, gen_bit;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	batch_size = NUM_REGS * 4 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = gem_create(fd, regs_size);
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x24 << 23 | (1 + r64b);
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = sizeof(uint32_t) * n;
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+			*b++ = reloc[n].delta;
+			if (r64b)
+				*b++ = 0;
+		}
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x24 << 23 | (1 + r64b); /* SRM */
+				*b++ = offset;
+				reloc[n].target_handle = obj[0].handle;
+				reloc[n].presumed_offset = 0;
+				reloc[n].offset = (b - batch) * sizeof(*b);
+				reloc[n].delta = offset;
+				reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+				reloc[n].write_domain = I915_GEM_DOMAIN_RENDER;
+				*b++ = offset;
+				if (r64b)
+					*b++ = 0;
+				n++;
+			}
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+	free(reloc);
+
+	return obj[0].handle;
+}
+
+static void write_regs(int fd,
+		       uint32_t ctx, unsigned int engine,
+		       unsigned int flags,
+		       uint32_t value)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, batch_size);
+
+	b = batch = gem_mmap__cpu(fd, obj.handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x22 << 23 | 1; /* LRI */
+			*b++ = n * sizeof(uint32_t);
+			*b++ = value;
+		}
+	} else {
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x22 << 23 | 1; /* LRI */
+				*b++ = offset;
+				*b++ = value;
+			}
+		}
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj.handle);
+}
+
+static void restore_regs(int fd,
+			 uint32_t ctx, unsigned int engine,
+			 unsigned int flags,
+			 uint32_t regs)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	const bool r64b = gen >= 8;
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_relocation_entry *reloc;
+	unsigned int engine_bit, gen_bit;
+	unsigned int batch_size;
+	uint32_t *batch, *b;
+
+	if (gen < 7) /* no LRM */
+		return;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	reloc = calloc(NUM_REGS, sizeof(*reloc));
+	igt_assert(reloc);
+
+	batch_size = NUM_REGS * 3 * sizeof(uint32_t) + 4;
+	batch_size = PAGE_ALIGN(batch_size);
+
+	memset(obj, 0, sizeof(obj));
+	obj[0].handle = regs;
+	obj[1].handle = gem_create(fd, batch_size);
+	obj[1].relocs_ptr = to_user_pointer(reloc);
+
+	b = batch = gem_mmap__cpu(fd, obj[1].handle, 0, batch_size, PROT_WRITE);
+	gem_set_domain(fd, obj[1].handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+	if (flags & UNSAFE) {
+		for (unsigned int n = 0; n < NUM_REGS; n++) {
+			*b++ = 0x29 << 23 | (1 + r64b); /* LRM */
+			*b++ = n * sizeof(uint32_t);
+			reloc[n].target_handle = obj[0].handle;
+			reloc[n].presumed_offset = 0;
+			reloc[n].offset = (b - batch) * sizeof(*b);
+			reloc[n].delta = n * sizeof(uint32_t);
+			reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+			reloc[n].write_domain = 0;
+			*b++ = reloc[n].delta;
+			if (r64b)
+				*b++ = 0;
+		}
+
+		obj[1].relocation_count = NUM_REGS;
+	} else {
+		unsigned int n = 0;
+
+		for (const struct named_register *r = safe_registers;
+		     r->name; r++) {
+			if (!(r->engine_mask & engine_bit))
+				continue;
+			if (!(r->gen_mask & gen_bit))
+				continue;
+
+			for (unsigned count = r->count ?: 1, offset = r->offset;
+			     count--; offset += 4) {
+				*b++ = 0x29 << 23 | (1 + r64b); /* LRM */
+				*b++ = offset;
+				reloc[n].target_handle = obj[0].handle;
+				reloc[n].presumed_offset = 0;
+				reloc[n].offset = (b - batch) * sizeof(*b);
+				reloc[n].delta = offset;
+				reloc[n].read_domains = I915_GEM_DOMAIN_RENDER;
+				reloc[n].write_domain = 0;
+				*b++ = offset;
+				if (gen >= 9)
+					*b++ = 0;
+				n++;
+			}
+		}
+
+		obj[1].relocation_count = n;
+	}
+	*b++ = MI_BATCH_BUFFER_END;
+	munmap(batch, batch_size);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = 2;
+	execbuf.flags = engine;
+	execbuf.rsvd1 = ctx;
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[1].handle);
+}
+
+__attribute__((unused))
+static void dump_regs(int fd, unsigned int engine, unsigned int regs)
+{
+	const int gen = intel_gen(intel_get_drm_devid(fd));
+	unsigned int engine_bit, gen_bit;
+	unsigned int regs_size;
+	uint32_t *out;
+
+	switch (engine & 0x63) {
+	case I915_EXEC_DEFAULT:
+	case I915_EXEC_RENDER:
+		engine_bit = RCS_MASK;
+		break;
+	case I915_EXEC_BLT:
+		engine_bit = BCS_MASK;
+		break;
+	case I915_EXEC_BSD:
+		engine_bit = VCS_MASK;
+		break;
+	case I915_EXEC_VEBOX:
+		engine_bit = VECS_MASK;
+		break;
+	default:
+		igt_assert(0);
+	}
+	gen_bit = 1 << gen;
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	out = gem_mmap__cpu(fd, regs, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, regs, I915_GEM_DOMAIN_CPU, 0);
+
+	for (const struct named_register *r = safe_registers; r->name; r++) {
+		if (!(r->engine_mask & engine_bit))
+			continue;
+		if (!(r->gen_mask & gen_bit))
+			continue;
+
+		if (r->count <= 1) {
+			igt_debug("0x%04x (%s): 0x%08x\n",
+				  r->offset, r->name, out[r->offset/4]);
+		} else {
+			for (unsigned x = 0; x < r->count; x++)
+				igt_debug("0x%04x (%s[%d]): 0x%08x\n",
+					  r->offset+4*x, r->name, x,
+					  out[r->offset/4 + x]);
+		}
+	}
+	munmap(out, regs_size);
+}
+
+static void compare_regs(int fd, uint32_t A, uint32_t B, const char *who)
+{
+	unsigned int num_errors;
+	unsigned int regs_size;
+	uint32_t *a, *b;
+	char buf[80];
+
+	regs_size = NUM_REGS * sizeof(uint32_t);
+	regs_size = PAGE_ALIGN(regs_size);
+
+	a = gem_mmap__cpu(fd, A, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, A, I915_GEM_DOMAIN_CPU, 0);
+
+	b = gem_mmap__cpu(fd, B, 0, regs_size, PROT_READ);
+	gem_set_domain(fd, B, I915_GEM_DOMAIN_CPU, 0);
+
+	num_errors = 0;
+	for (unsigned int n = 0; n < NUM_REGS; n++) {
+		uint32_t offset = n * sizeof(uint32_t);
+		if (a[n] != b[n] && !ignore_register(offset)) {
+			igt_warn("Register 0x%04x (%s): A=%08x B=%08x\n",
+				 offset,
+				 register_name(offset, buf, sizeof(buf)),
+				 a[n], b[n]);
+			num_errors++;
+		}
+	}
+	munmap(b, regs_size);
+	munmap(a, regs_size);
+
+	igt_assert_f(num_errors == 0,
+		     "%d registers mistached between %s.\n",
+		     num_errors, who);
+}
+
+static void isolation(int fd, unsigned int engine, unsigned int flags)
+{
+	static const uint32_t values[] = {
+		0x0,
+		0xffffffff,
+		0xcccccccc,
+		0x33333333,
+		0x55555555,
+		0xaaaaaaaa,
+		0xdeadbeef
+	};
+	unsigned int num_values =
+		flags & (DIRTY1 | DIRTY2) ? ARRAY_SIZE(values) : 1;
+
+	for (int v = 0; v < num_values; v++) {
+		igt_spin_t *spin = NULL;
+		uint32_t ctx[2], regs[2], tmp;
+
+		ctx[0] = gem_context_create(fd);
+		regs[0] = read_regs(fd, ctx[0], engine, flags);
+
+		spin = igt_spin_batch_new(fd, ctx[0], engine, 0);
+
+		if (flags & DIRTY1) {
+			igt_debug("%s[%d]: Setting all registers of ctx 0 to 0x%08x\n",
+				  __func__, v, values[v]);
+			write_regs(fd, ctx[0], engine, flags, values[v]);
+		}
+
+		/*
+		 * We create and execute a new context, whilst the HW is
+		 * occupied with the previous context (we should switch from
+		 * the old to the new proto-context without idling, which could
+		 * then load the powercontext). If all goes well, we only see
+		 * the default values from this context, but if goes badly we
+		 * see the corruption from the previous context instead!
+		 */
+		ctx[1] = gem_context_create(fd);
+		regs[1] = read_regs(fd, ctx[1], engine, flags);
+
+		if (flags & DIRTY2) {
+			igt_debug("%s[%d]: Setting all registers of ctx 1 to 0x%08x\n",
+				  __func__, v, ~values[v]);
+			write_regs(fd, ctx[1], engine, flags, ~values[v]);
+		}
+
+		/*
+		 * Restore the original register values before the HW idles.
+		 * Or else it may never restart!
+		 */
+		tmp = read_regs(fd, ctx[0], engine, flags);
+		restore_regs(fd, ctx[0], engine, flags, regs[0]);
+
+		igt_spin_batch_free(fd, spin);
+
+		if (!(flags & DIRTY1))
+			compare_regs(fd, regs[0], tmp, "two reads of the same ctx");
+		compare_regs(fd, regs[0], regs[1], "two virgin contexts");
+
+		for (int n = 0; n < ARRAY_SIZE(ctx); n++) {
+			gem_close(fd, regs[n]);
+			gem_context_destroy(fd, ctx[n]);
+		}
+		gem_close(fd, tmp);
+	}
+}
+
+#define NOSLEEP (0 << 8)
+#define S3_DEVICES (1 << 8)
+#define S3 (2 << 8)
+#define S4_DEVICES (3 << 8)
+#define S4 (4 << 8)
+#define SLEEP_MASK (0xf << 8)
+
+static void preservation(int fd, unsigned int engine, unsigned int flags)
+{
+	static const uint32_t values[] = {
+		0x0,
+		0xffffffff,
+		0xcccccccc,
+		0x33333333,
+		0x55555555,
+		0xaaaaaaaa,
+		0xdeadbeef
+	};
+	const unsigned int num_values = ARRAY_SIZE(values);
+	uint32_t ctx[num_values +1 ];
+	uint32_t regs[num_values + 1][2];
+	igt_spin_t *spin;
+
+	ctx[num_values] = gem_context_create(fd);
+	spin = igt_spin_batch_new(fd, ctx[num_values], engine, 0);
+	regs[num_values][0] = read_regs(fd, ctx[num_values], engine, flags);
+	for (int v = 0; v < num_values; v++) {
+		ctx[v] = gem_context_create(fd);
+		write_regs(fd, ctx[v], engine, flags, values[v]);
+
+		regs[v][0] = read_regs(fd, ctx[v], engine, flags);
+
+	}
+	gem_close(fd, read_regs(fd, ctx[num_values], engine, flags));
+	igt_spin_batch_free(fd, spin);
+
+	if (flags & RESET)
+		igt_force_gpu_reset(fd);
+
+	switch (flags & SLEEP_MASK) {
+	case NOSLEEP:
+		break;
+
+	case S3_DEVICES:
+		igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
+					      SUSPEND_TEST_DEVICES);
+		break;
+
+	case S3:
+		igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
+					      SUSPEND_TEST_NONE);
+		break;
+
+	case S4_DEVICES:
+		igt_system_suspend_autoresume(SUSPEND_STATE_DISK,
+					      SUSPEND_TEST_DEVICES);
+		break;
+
+	case S4:
+		igt_system_suspend_autoresume(SUSPEND_STATE_DISK,
+					      SUSPEND_TEST_NONE);
+		break;
+	}
+
+	spin = igt_spin_batch_new(fd, ctx[num_values], engine, 0);
+	for (int v = 0; v < num_values; v++)
+		regs[v][1] = read_regs(fd, ctx[v], engine, flags);
+	regs[num_values][1] = read_regs(fd, ctx[num_values], engine, flags);
+	igt_spin_batch_free(fd, spin);
+
+	for (int v = 0; v < num_values; v++) {
+		char buf[80];
+
+		snprintf(buf, sizeof(buf), "dirty %x context\n", values[v]);
+		compare_regs(fd, regs[v][0], regs[v][1], buf);
+
+		gem_close(fd, regs[v][0]);
+		gem_close(fd, regs[v][1]);
+		gem_context_destroy(fd, ctx[v]);
+	}
+	compare_regs(fd, regs[num_values][0], regs[num_values][1], "clean");
+	gem_context_destroy(fd, ctx[num_values]);
+}
+
+static unsigned int __has_context_isolation(int fd)
+{
+	struct drm_i915_getparam gp;
+	int value = 0;
+
+	memset(&gp, 0, sizeof(gp));
+	gp.param = 50; /* I915_PARAM_HAS_CONTEXT_ISOLATION */
+	gp.value = &value;
+
+	igt_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+	errno = 0;
+
+	return value;
+}
+
+igt_main
+{
+	const unsigned int platform_validation = 0;
+	unsigned int has_context_isolation = 0;
+	int fd = -1;
+
+	igt_fixture {
+		int gen;
+
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+
+		gem_context_destroy(fd, gem_context_create(fd));
+		has_context_isolation = __has_context_isolation(fd);
+		igt_require(has_context_isolation);
+
+		gen = intel_gen(intel_get_drm_devid(fd));
+		//igt_ci_fail_on(gen > LAST_KNOWN_GEN);
+		igt_skip_on(gen > LAST_KNOWN_GEN);
+	}
+
+	for (const struct intel_execution_engine *e =
+	     intel_execution_engines; e->name; e++) {
+		igt_subtest_group {
+			unsigned int engine = e->exec_id | e->flags;
+			igt_fixture {
+				igt_require(has_context_isolation & (1 << e->class_id));
+				gem_require_ring(fd, engine);
+			}
+
+			igt_subtest_f("%s-clean", e->name)
+				isolation(fd, engine, 0);
+			igt_subtest_f("%s-dirty-create", e->name)
+				isolation(fd, engine, DIRTY1);
+			igt_subtest_f("%s-dirty-switch", e->name)
+				isolation(fd, engine, DIRTY2);
+
+			igt_subtest_f("%s-none", e->name)
+				preservation(fd, engine, 0);
+			igt_subtest_f("%s-reset", e->name) {
+				igt_hang_t hang = igt_allow_hang(fd, 0, 0);
+				preservation(fd, engine, RESET);
+				igt_disallow_hang(fd, hang);
+			}
+			igt_subtest_f("%s-S3", e->name)
+				preservation(fd, engine, S3);
+			igt_subtest_f("%s-S4", e->name)
+				preservation(fd, engine, S4);
+
+			igt_subtest_f("%s-unsafe", e->name) {
+				igt_require(platform_validation);
+				isolation(fd, engine, DIRTY2 | DIRTY1 | UNSAFE);
+			}
+		}
+	}
+}
diff --git a/tests/gem_exec_fence.c b/tests/gem_exec_fence.c
index 2a6da8b0..980e7f7f 100644
--- a/tests/gem_exec_fence.c
+++ b/tests/gem_exec_fence.c
@@ -698,7 +698,7 @@ static bool has_submit_fence(int fd)
 	int value = 0;
 
 	memset(&gp, 0, sizeof(gp));
-	gp.param = 50; /* I915_PARAM_HAS_EXEC_SUBMIT_FENCE */
+	gp.param = 0xdeadbeef ^ 51; /* I915_PARAM_HAS_EXEC_SUBMIT_FENCE */
 	gp.value = &value;
 
 	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
-- 
2.15.0

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

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

* ✗ Fi.CI.BAT: failure for series starting with [v3,1/2] lib/gt: Mark up engine classes
  2017-11-06 10:49 [PATCH igt v3 1/2] lib/gt: Mark up engine classes Chris Wilson
  2017-11-06 10:49 ` [PATCH igt v3 2/2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
@ 2017-11-06 11:07 ` Patchwork
  1 sibling, 0 replies; 3+ messages in thread
From: Patchwork @ 2017-11-06 11:07 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v3,1/2] lib/gt: Mark up engine classes
URL   : https://patchwork.freedesktop.org/series/33239/
State : failure

== Summary ==

IGT patchset tested on top of latest successful build
c8d1ea24d3bfaf11b223bbe22407aeca196d0d89 tests/debugfs_test: Pretty print subdirectories

with latest DRM-Tip kernel build CI_DRM_3315
9cc9686b44e1 drm-tip: 2017y-11m-06d-10h-10m-17s UTC integration manifest

Testlist changes:
+igt@gem_ctx_isolation@blt-S3
+igt@gem_ctx_isolation@blt-S4
+igt@gem_ctx_isolation@blt-clean
+igt@gem_ctx_isolation@blt-dirty-create
+igt@gem_ctx_isolation@blt-dirty-switch
+igt@gem_ctx_isolation@blt-none
+igt@gem_ctx_isolation@blt-reset
+igt@gem_ctx_isolation@blt-unsafe
+igt@gem_ctx_isolation@bsd1-S3
+igt@gem_ctx_isolation@bsd1-S4
+igt@gem_ctx_isolation@bsd1-clean
+igt@gem_ctx_isolation@bsd1-dirty-create
+igt@gem_ctx_isolation@bsd1-dirty-switch
+igt@gem_ctx_isolation@bsd1-none
+igt@gem_ctx_isolation@bsd1-reset
+igt@gem_ctx_isolation@bsd1-unsafe
+igt@gem_ctx_isolation@bsd2-S3
+igt@gem_ctx_isolation@bsd2-S4
+igt@gem_ctx_isolation@bsd2-clean
+igt@gem_ctx_isolation@bsd2-dirty-create
+igt@gem_ctx_isolation@bsd2-dirty-switch
+igt@gem_ctx_isolation@bsd2-none
+igt@gem_ctx_isolation@bsd2-reset
+igt@gem_ctx_isolation@bsd2-unsafe
+igt@gem_ctx_isolation@bsd-S3
+igt@gem_ctx_isolation@bsd-S4
+igt@gem_ctx_isolation@bsd-clean
+igt@gem_ctx_isolation@bsd-dirty-create
+igt@gem_ctx_isolation@bsd-dirty-switch
+igt@gem_ctx_isolation@bsd-none
+igt@gem_ctx_isolation@bsd-reset
+igt@gem_ctx_isolation@bsd-unsafe
+igt@gem_ctx_isolation@default-S3
+igt@gem_ctx_isolation@default-S4
+igt@gem_ctx_isolation@default-clean
+igt@gem_ctx_isolation@default-dirty-create
+igt@gem_ctx_isolation@default-dirty-switch
+igt@gem_ctx_isolation@default-none
+igt@gem_ctx_isolation@default-reset
+igt@gem_ctx_isolation@default-unsafe
+igt@gem_ctx_isolation@render-S3
+igt@gem_ctx_isolation@render-S4
+igt@gem_ctx_isolation@render-clean
+igt@gem_ctx_isolation@render-dirty-create
+igt@gem_ctx_isolation@render-dirty-switch
+igt@gem_ctx_isolation@render-none
+igt@gem_ctx_isolation@render-reset
+igt@gem_ctx_isolation@render-unsafe
+igt@gem_ctx_isolation@vebox-S3
+igt@gem_ctx_isolation@vebox-S4
+igt@gem_ctx_isolation@vebox-clean
+igt@gem_ctx_isolation@vebox-dirty-create
+igt@gem_ctx_isolation@vebox-dirty-switch
+igt@gem_ctx_isolation@vebox-none
+igt@gem_ctx_isolation@vebox-reset
+igt@gem_ctx_isolation@vebox-unsafe

Test debugfs_test:
        Subgroup read_all_entries:
                pass       -> DMESG-WARN (fi-kbl-7567u)
Test gem_exec_reloc:
        Subgroup basic-write-cpu:
                pass       -> INCOMPLETE (fi-glk-dsi)

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:448s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:453s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:382s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:546s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:280s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:513s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:499s
fi-byt-j1900     total:289  pass:253  dwarn:1   dfail:0   fail:0   skip:35  time:519s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:497s
fi-cfl-s         total:289  pass:254  dwarn:3   dfail:0   fail:0   skip:32  time:559s
fi-cnl-y         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:599s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:431s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:263s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:583s
fi-glk-dsi       total:87   pass:67   dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:441s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:431s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:432s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:501s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:469s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:577s
fi-kbl-7567u     total:289  pass:268  dwarn:1   dfail:0   fail:0   skip:20  time:483s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:586s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:578s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:458s
fi-skl-6600u     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:600s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:650s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:527s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:506s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:463s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:576s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:422s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_477/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-11-06 11:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-06 10:49 [PATCH igt v3 1/2] lib/gt: Mark up engine classes Chris Wilson
2017-11-06 10:49 ` [PATCH igt v3 2/2] igt/gem_ctx_isolation: Check isolation of registers between contexts Chris Wilson
2017-11-06 11:07 ` ✗ Fi.CI.BAT: failure for series starting with [v3,1/2] lib/gt: Mark up engine classes Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.