public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH v3 0/3] new engine discovery interface
@ 2018-11-26 20:43 Andi Shyti
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 1/3] include/drm-uapi: import i915_drm.h header file Andi Shyti
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Andi Shyti @ 2018-11-26 20:43 UTC (permalink / raw)
  To: IGT dev; +Cc: Tvrtko Ursulin, Andi Shyti

From: Andi Shyti <andi@etezian.org>

Hi,

Il will send this series as a PATCH v3 after the two round of
RFCs[1, 2].

In this patchset I propose an alternative way of engine discovery
thanks to the new interfaces developed by Tvrtko and Chris[3].

Thanks Chris and Tvrtko for your comments in the RFC.

V1 --> V2
=========
RFC v1: [1]
- added a demo test that simply queries the driver about the
  engines and executes a buffer (thanks Tvrtko)
- refactored the for_each_engine_ctx() macro so that what in the
  previous version was done by the "bind" function, now it's done
  in the first iteration. (Thanks Crhis)
- removed the "gem_has_ring_ctx()" because it was out of the
  scope.
- rename functions to more meaningful names

V2 -- V3
========
RFC v2: [2]
- removed a standalone gem_query_engines_demo test and added the
  exec-ctx subtest inside gem_exec_basic (thanks Tvrtko).
- fixed most of Tvrtko's comments in [4], which consist in
  putting the mallocs igt_assert and ictls in igt_require and few
  refactoring (thanks Tvrtko).

Andi

[1] RFC v1: https://lists.freedesktop.org/archives/igt-dev/2018-November/007025.html
[2] RFC v2: https://lists.freedesktop.org/archives/igt-dev/2018-November/007079.html
[3] git://people.freedesktop.org/~tursulin/drm-intel
[4] https://lists.freedesktop.org/archives/igt-dev/2018-November/007100.html

Andi Shyti (3):
  include/drm-uapi: import i915_drm.h header file
  lib: implement new engine discovery interface
  tests: gem_exec_basic: add "exec-ctx" buffer execution demo test

 include/drm-uapi/i915_drm.h | 239 +++++++++++++++++++++++++++++++++++-
 lib/igt_gt.c                |  74 +++++++++++
 lib/igt_gt.h                |   5 +
 tests/i915/gem_exec_basic.c |  32 +++++
 4 files changed, 348 insertions(+), 2 deletions(-)

-- 
2.20.0.rc1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] [PATCH v3 1/3] include/drm-uapi: import i915_drm.h header file
  2018-11-26 20:43 [igt-dev] [PATCH v3 0/3] new engine discovery interface Andi Shyti
@ 2018-11-26 20:43 ` Andi Shyti
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface Andi Shyti
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Andi Shyti @ 2018-11-26 20:43 UTC (permalink / raw)
  To: IGT dev; +Cc: Tvrtko Ursulin, Andi Shyti

This header file is imported in order to include the two new
ioctls DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM and
DRM_IOCTL_I915_QUERY. They are not based on a latest version of
the branch, but based on the

git://people.freedesktop.org/~tursulin/drm-intel

tree, "media" branch. In this RFC it's just to give a meaning to
the next patch.

Signed-off-by: Andi Shyti <andi.shyti@intel.com>
---
 include/drm-uapi/i915_drm.h | 239 +++++++++++++++++++++++++++++++++++-
 1 file changed, 237 insertions(+), 2 deletions(-)

diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 16e452aa..b14ca969 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -62,6 +62,26 @@ extern "C" {
 #define I915_ERROR_UEVENT		"ERROR"
 #define I915_RESET_UEVENT		"RESET"
 
+/*
+ * i915_user_extension: Base class for defining a chain of extensions
+ *
+ * Many interfaces need to grow over time. In most cases we can simply
+ * extend the struct and have userspace pass in more data. Another option,
+ * as demonstrated by Vulkan's approach to providing extensions for forward
+ * and backward compatibility, is to use a list of optional structs to
+ * provide those extra details.
+ *
+ * The key advantage to using an extension chain is that it allows us to
+ * redefine the interface more easily than an ever growing struct of
+ * increasing complexity, and for large parts of that interface to be
+ * entirely optional. The downside is more pointer chasing; chasing across
+ * the boundary with pointers encapsulated inside u64.
+ */
+struct i915_user_extension {
+	__u64 next_extension;
+	__u64 name;
+};
+
 /*
  * MOCS indexes used for GPU surfaces, defining the cacheability of the
  * surface data and the coherency for this data wrt. CPU vs. GPU accesses.
@@ -367,6 +387,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
 #define DRM_IOCTL_I915_GEM_WAIT		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
 #define DRM_IOCTL_I915_GEM_CONTEXT_CREATE	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
+#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE_v2	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create_v2)
 #define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
 #define DRM_IOCTL_I915_REG_READ			DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
 #define DRM_IOCTL_I915_GET_RESET_STATS		DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
@@ -412,6 +433,14 @@ typedef struct drm_i915_irq_wait {
 	int irq_seq;
 } drm_i915_irq_wait_t;
 
+/*
+ * Different modes of per-process Graphics Translation Table,
+ * see I915_PARAM_HAS_ALIASING_PPGTT
+ */
+#define I915_GEM_PPGTT_NONE	0
+#define I915_GEM_PPGTT_ALIASING	1
+#define I915_GEM_PPGTT_FULL	2
+
 /* Ioctl to query kernel params:
  */
 #define I915_PARAM_IRQ_ACTIVE            1
@@ -529,6 +558,35 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51
 
+/*
+ * Once upon a time we supposed that writes through the GGTT would be
+ * immediately in physical memory (once flushed out of the CPU path). However,
+ * on a few different processors and chipsets, this is not necessarily the case
+ * as the writes appear to be buffered internally. Thus a read of the backing
+ * storage (physical memory) via a different path (with different physical tags
+ * to the indirect write via the GGTT) will see stale values from before
+ * the GGTT write. Inside the kernel, we can for the most part keep track of
+ * the different read/write domains in use (e.g. set-domain), but the assumption
+ * of coherency is baked into the ABI, hence reporting its true state in this
+ * parameter.
+ *
+ * Reports true when writes via mmap_gtt are immediately visible following an
+ * lfence to flush the WCB.
+ *
+ * Reports false when writes via mmap_gtt are indeterminately delayed in an in
+ * internal buffer and are _not_ immediately visible to third parties accessing
+ * directly via mmap_cpu/mmap_wc. Use of mmap_gtt as part of an IPC
+ * communications channel when reporting false is strongly disadvised.
+ */
+#define I915_PARAM_MMAP_GTT_COHERENT	52
+
+/*
+ * Query whether DRM_I915_GEM_EXECBUFFER2 supports coordination of parallel
+ * execution through use of explicit fence support.
+ * See I915_EXEC_FENCE_OUT and I915_EXEC_FENCE_SUBMIT.
+ */
+#define I915_PARAM_HAS_EXEC_SUBMIT_FENCE 53
+
 typedef struct drm_i915_getparam {
 	__s32 param;
 	/*
@@ -942,7 +1000,7 @@ struct drm_i915_gem_execbuffer2 {
 	 * struct drm_i915_gem_exec_fence *fences.
 	 */
 	__u64 cliprects_ptr;
-#define I915_EXEC_RING_MASK              (7<<0)
+#define I915_EXEC_RING_MASK              (0x3f)
 #define I915_EXEC_DEFAULT                (0<<0)
 #define I915_EXEC_RENDER                 (1<<0)
 #define I915_EXEC_BSD                    (2<<0)
@@ -1048,7 +1106,16 @@ struct drm_i915_gem_execbuffer2 {
  */
 #define I915_EXEC_FENCE_ARRAY   (1<<19)
 
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1))
+/*
+ * Setting I915_EXEC_FENCE_SUBMIT implies that lower_32_bits(rsvd2) represent
+ * a sync_file fd to wait upon (in a nonblocking manner) prior to executing
+ * the batch.
+ *
+ * Returns -EINVAL if the sync_file fd cannot be found.
+ */
+#define I915_EXEC_FENCE_SUBMIT		(1<<20)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT<<1))
 
 #define I915_EXEC_CONTEXT_ID_MASK	(0xffffffff)
 #define i915_execbuffer2_set_context_id(eb2, context) \
@@ -1387,6 +1454,16 @@ struct drm_i915_gem_context_create {
 	__u32 pad;
 };
 
+struct drm_i915_gem_context_create_v2 {
+	/*  output: id of new context*/
+	__u32 ctx_id;
+	__u32 flags;
+#define I915_GEM_CONTEXT_SHARE_GTT		0x1
+#define I915_GEM_CONTEXT_SINGLE_TIMELINE	0x2
+	__u32 share_ctx;
+	__u32 pad;
+};
+
 struct drm_i915_gem_context_destroy {
 	__u32 ctx_id;
 	__u32 pad;
@@ -1456,9 +1533,122 @@ struct drm_i915_gem_context_param {
 #define   I915_CONTEXT_MAX_USER_PRIORITY	1023 /* inclusive */
 #define   I915_CONTEXT_DEFAULT_PRIORITY		0
 #define   I915_CONTEXT_MIN_USER_PRIORITY	-1023 /* inclusive */
+
+/*
+ * I915_CONTEXT_PARAM_ENGINES:
+ *
+ * Bind this context to operate on this subset of available engines. Henceforth,
+ * the I915_EXEC_RING selector for DRM_IOCTL_I915_GEM_EXECBUFFER2 operates as
+ * an index into this array of engines; I915_EXEC_DEFAULT selecting engine[0]
+ * and upwards. The array created is offset by 1, such that by default
+ * I915_EXEC_DEFAULT is left empty, to be filled in as directed. Slots 1...N
+ * are then filled in using the specified (class, instance).
+ *
+ * Setting the number of engines bound to the context will revert back to
+ * default settings.
+ *
+ * See struct i915_context_param_engines.
+ *
+ * Extensions:
+ *   i915_context_engines_load_balance (I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE)
+ *   i915_context_engines_bond (I915_CONTEXT_ENGINES_EXT_BOND)
+ */
+#define I915_CONTEXT_PARAM_ENGINES	0x7
+
+/*
+ * When using the following param, value should be a pointer to
+ * drm_i915_gem_context_param_sseu.
+ */
+#define I915_CONTEXT_PARAM_SSEU		0x8
+
 	__u64 value;
 };
 
+/*
+ * i915_context_engines_load_balance:
+ *
+ * Enable load balancing across this set of engines.
+ *
+ * Into the I915_EXEC_DEFAULT slot, a virtual engine is created that when
+ * used will proxy the execbuffer request onto one of the set of engines
+ * in such a way as to distribute the load evenly across the set.
+ *
+ * The set of engines must be compatible (e.g. the same HW class) as they
+ * will share the same logical GPU context and ring.
+ *
+ * The context must be defined to use a single timeline for all engines.
+ */
+struct i915_context_engines_load_balance {
+	struct i915_user_extension base;
+
+	__u64 flags; /* all undefined flags must be zero */
+	__u64 engines_mask;
+
+	__u64 mbz[4]; /* reserved for future use; must be zero */
+};
+
+/*
+ * i915_context_engines_bond:
+ *
+ */
+struct i915_context_engines_bond {
+	struct i915_user_extension base;
+
+	__u16 master_class;
+	__u16 master_instance;
+	__u32 flags; /* all undefined flags must be zero */
+	__u64 sibling_mask;
+};
+
+struct i915_context_param_engines {
+	__u64 extensions;
+#define I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE 0
+#define I915_CONTEXT_ENGINES_EXT_BOND 1
+
+	struct {
+		__u16 class; /* see enum drm_i915_gem_engine_class */
+		__u16 instance;
+	} class_instance[0];
+};
+
+struct drm_i915_gem_context_param_sseu {
+	/*
+	 * Engine class & instance to be configured or queried.
+	 */
+	__u16 class;
+	__u16 instance;
+
+	/*
+	 * Unused for now. Must be cleared to zero.
+	 */
+	__u32 rsvd1;
+
+	/*
+	 * Mask of slices to enable for the context. Valid values are a subset
+	 * of the bitmask value returned for I915_PARAM_SLICE_MASK.
+	 */
+	__u64 slice_mask;
+
+	/*
+	 * Mask of subslices to enable for the context. Valid values are a
+	 * subset of the bitmask value return by I915_PARAM_SUBSLICE_MASK.
+	 */
+	__u64 subslice_mask;
+
+	/*
+	 * Minimum/Maximum number of EUs to enable per subslice for the
+	 * context. min_eus_per_subslice must be inferior or equal to
+	 * max_eus_per_subslice.
+	 */
+	__u16 min_eus_per_subslice;
+	__u16 max_eus_per_subslice;
+
+	/*
+	 * Unused for now. Must be cleared to zero.
+	 */
+	__u32 rsvd2;
+};
+
 enum drm_i915_oa_format {
 	I915_OA_FORMAT_A13 = 1,	    /* HSW only */
 	I915_OA_FORMAT_A29,	    /* HSW only */
@@ -1620,6 +1810,7 @@ struct drm_i915_perf_oa_config {
 struct drm_i915_query_item {
 	__u64 query_id;
 #define DRM_I915_QUERY_TOPOLOGY_INFO    1
+#define DRM_I915_QUERY_ENGINE_INFO	2
 
 	/*
 	 * When set to zero by userspace, this is filled with the size of the
@@ -1717,6 +1908,50 @@ struct drm_i915_query_topology_info {
 	__u8 data[];
 };
 
+/**
+ * struct drm_i915_engine_info
+ *
+ * Describes one engine and it's capabilities as known to the driver.
+ */
+struct drm_i915_engine_info {
+	/** Engine class as in enum drm_i915_gem_engine_class. */
+	__u16 class;
+
+	/** Engine instance number. */
+	__u16 instance;
+
+	/** Reserved field. */
+	__u32 rsvd0;
+
+	/** Engine flags. */
+	__u64 flags;
+
+	/** Capabilities of this engine. */
+	__u64 capabilities;
+#define I915_VIDEO_CLASS_CAPABILITY_HEVC		(1 << 0)
+#define I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC	(1 << 1)
+
+	/** Reserved fields. */
+	__u64 rsvd1[4];
+};
+
+/**
+ * struct drm_i915_query_engine_info
+ *
+ * Engine info query enumerates all engines known to the driver by filling in
+ * an array of struct drm_i915_engine_info structures.
+ */
+struct drm_i915_query_engine_info {
+	/** Number of struct drm_i915_engine_info structs following. */
+	__u32 num_engines;
+
+	/** MBZ */
+	__u32 rsvd[3];
+
+	/** Marker for drm_i915_engine_info structures. */
+	struct drm_i915_engine_info engines[];
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.20.0.rc1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface
  2018-11-26 20:43 [igt-dev] [PATCH v3 0/3] new engine discovery interface Andi Shyti
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 1/3] include/drm-uapi: import i915_drm.h header file Andi Shyti
@ 2018-11-26 20:43 ` Andi Shyti
  2018-11-27 12:00   ` Tvrtko Ursulin
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 3/3] tests: gem_exec_basic: add "exec-ctx" buffer execution demo test Andi Shyti
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Andi Shyti @ 2018-11-26 20:43 UTC (permalink / raw)
  To: IGT dev; +Cc: Tvrtko Ursulin, Andi Shyti

Kernel commits:

[1] ae8f4544dd8f ("drm/i915: Engine discovery query")
[2] 31e7d35667a0 ("drm/i915: Allow a context to define its set of engines")

from [*] repository, implement a new uapi for engine discovery
that consist in first querying the driver about the engines in
the gpu [1] and then binding a context to the set of engines that
it can access [2].

In igt the classic way for discovering engines is done through
the for_each_physical_engine() macro, that would be replaced by
the new for_each_engine_ctx().

[*] git://people.freedesktop.org/~tursulin/drm-intel

Signed-off-by: Andi Shyti <andi.shyti@intel.com>
---
 lib/igt_gt.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_gt.h |  5 ++++
 2 files changed, 79 insertions(+)

diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index a2061924..e5543b27 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -650,3 +650,77 @@ bool gem_ring_has_physical_engine(int fd, unsigned ring)
 
 	return gem_has_ring(fd, ring);
 }
+
+static struct drm_i915_query_engine_info *query_engines(int fd)
+{
+	struct drm_i915_query query = { };
+	struct drm_i915_query_item item = { };
+	struct drm_i915_query_engine_info *query_engines;
+
+	item.query_id = DRM_I915_QUERY_ENGINE_INFO;
+	query.items_ptr = to_user_pointer(&item);
+	query.num_items = 1;
+
+	/*
+	 * The first ioctl is sent with item.length = 0
+	 * which asks to the driver to store in length the
+	 * memory needed for the engines. In the driver, length
+	 * is equal to
+	 *
+	 *   len = sizeof(struct drm_i915_query_engine_info) +
+	 *                   INTEL_INFO(i915)->num_rings *
+	 *                   sizeof(struct drm_i915_engine_info);
+	 */
+	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
+
+	igt_assert((query_engines = calloc(item.length, 1)));
+	item.data_ptr = to_user_pointer(query_engines);
+
+	/* The second ioctl stores the engines in query_engines */
+	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
+
+	return query_engines;
+}
+
+static void set_param(int fd, uint32_t ctx_id,
+		      struct drm_i915_query_engine_info *query_engine)
+{
+	int i;
+	struct drm_i915_gem_context_param ctx_param;
+	struct i915_context_param_engines *ctx_engine;
+	size_t size = sizeof(struct i915_context_param_engines) +
+		      query_engine->num_engines *
+		      sizeof(*ctx_engine->class_instance);
+
+	igt_assert((ctx_engine = malloc(size)));
+
+	ctx_engine->extensions = 0;
+	for (i = 0; i < query_engine->num_engines; i++) {
+		ctx_engine->class_instance[i].class = query_engine->engines[i].class;
+		ctx_engine->class_instance[i].instance = query_engine->engines[i].instance;
+	}
+
+	ctx_param.ctx_id = ctx_id;
+	ctx_param.size = size;
+	ctx_param.param = I915_CONTEXT_PARAM_ENGINES;
+	ctx_param.value = to_user_pointer(ctx_engine);
+
+	/* check whether we free the engines */
+	igt_require(!ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctx_param));
+
+	free(ctx_engine);
+}
+
+int __gem_setup_ctx_engines(int fd, uint32_t ctx_id)
+{
+	struct drm_i915_query_engine_info *query_engine;
+	int n;
+
+	query_engine = query_engines(fd);
+	set_param(fd, ctx_id, query_engine);
+
+	n = query_engine->num_engines;
+	free(query_engine);
+
+	return n;
+}
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index 54e95da9..512f958d 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -86,8 +86,13 @@ extern const struct intel_execution_engine {
 	     e__++) \
 		for_if (gem_ring_has_physical_engine(fd__, flags__ = e__->exec_id | e__->flags))
 
+#define for_each_engine_ctx(fd, ctx, e) \
+		for (int __m = __gem_setup_ctx_engines(fd, ctx), __e = e = 1; \
+				__e <= __m; e = ++__e)
+
 bool gem_ring_is_physical_engine(int fd, unsigned int ring);
 bool gem_ring_has_physical_engine(int fd, unsigned int ring);
+int __gem_setup_ctx_engines(int fd, uint32_t ctx_id);
 
 bool gem_can_store_dword(int fd, unsigned int engine);
 
-- 
2.20.0.rc1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] [PATCH v3 3/3] tests: gem_exec_basic: add "exec-ctx" buffer execution demo test
  2018-11-26 20:43 [igt-dev] [PATCH v3 0/3] new engine discovery interface Andi Shyti
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 1/3] include/drm-uapi: import i915_drm.h header file Andi Shyti
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface Andi Shyti
@ 2018-11-26 20:43 ` Andi Shyti
  2018-11-26 21:10   ` Chris Wilson
  2018-11-26 22:23 ` [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev3) Patchwork
  2018-12-14 15:50 ` [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev4) Patchwork
  4 siblings, 1 reply; 14+ messages in thread
From: Andi Shyti @ 2018-11-26 20:43 UTC (permalink / raw)
  To: IGT dev; +Cc: Tvrtko Ursulin, Andi Shyti

The "exec-ctx" is a demo subtest inserted in the gem_exec_basic
test. The main scope is to demonstrate an alternative way for
querying engines as implemented in the new API in commit 87079e04
("lib: implement new engine discovery interface").

The "exec-ctx" subtest simply gets the list of engines, binds
them to a context and executes a buffer. This is done through a
new "for_each_engine_ctx" loop which iterates through the
engines.

Signed-off-by: Andi Shyti <andi.shyti@intel.com>
---
 tests/i915/gem_exec_basic.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/tests/i915/gem_exec_basic.c b/tests/i915/gem_exec_basic.c
index dcb83864..70128547 100644
--- a/tests/i915/gem_exec_basic.c
+++ b/tests/i915/gem_exec_basic.c
@@ -114,6 +114,22 @@ static void gtt(int fd, unsigned ring)
 	munmap(execbuf, 4096);
 }
 
+static void execbuf_in_ctx(int fd, uint32_t engine, uint32_t ctx, uint32_t handle)
+{
+	struct drm_i915_gem_exec_object2 exec = {
+		.handle = handle,
+	};
+	struct drm_i915_gem_execbuffer2 execbuf = {
+		.buffers_ptr = to_user_pointer(&exec),
+		.buffer_count = 1,
+		.flags = engine,
+		.rsvd1 = ctx & I915_EXEC_CONTEXT_ID_MASK,
+	};
+
+	igt_assert(execbuf.rsvd1);
+	gem_execbuf(fd, &execbuf);
+}
+
 igt_main
 {
 	const struct intel_execution_engine *e;
@@ -135,6 +151,22 @@ igt_main
 			gtt(fd, e->exec_id | e->flags);
 	}
 
+	igt_subtest("exec-ctx") {
+		uint32_t ctx_id, r;
+		uint32_t handle;
+		uint32_t bbend = MI_BATCH_BUFFER_END;
+
+		ctx_id = gem_context_create(fd);
+		handle = gem_create(fd, 4096);
+		gem_write(fd, handle, 0, &bbend, sizeof(bbend));
+
+		for_each_engine_ctx(fd, ctx_id, r)
+			execbuf_in_ctx(fd, r, ctx_id, handle);
+
+		gem_close(fd, handle);
+		gem_context_destroy(fd, ctx_id);
+	}
+
 	igt_fixture {
 		igt_stop_hang_detector();
 		close(fd);
-- 
2.20.0.rc1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: [igt-dev] [PATCH v3 3/3] tests: gem_exec_basic: add "exec-ctx" buffer execution demo test
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 3/3] tests: gem_exec_basic: add "exec-ctx" buffer execution demo test Andi Shyti
@ 2018-11-26 21:10   ` Chris Wilson
  2018-11-27 11:40     ` Tvrtko Ursulin
  0 siblings, 1 reply; 14+ messages in thread
From: Chris Wilson @ 2018-11-26 21:10 UTC (permalink / raw)
  To: Andi Shyti, IGT dev; +Cc: Andi Shyti, Tvrtko Ursulin

Quoting Andi Shyti (2018-11-26 20:43:49)
> The "exec-ctx" is a demo subtest inserted in the gem_exec_basic
> test. The main scope is to demonstrate an alternative way for
> querying engines as implemented in the new API in commit 87079e04
> ("lib: implement new engine discovery interface").
> 
> The "exec-ctx" subtest simply gets the list of engines, binds
> them to a context and executes a buffer. This is done through a
> new "for_each_engine_ctx" loop which iterates through the
> engines.

See gem_ctx_engines for the intent of validating the ctx->engines[] api.
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev3)
  2018-11-26 20:43 [igt-dev] [PATCH v3 0/3] new engine discovery interface Andi Shyti
                   ` (2 preceding siblings ...)
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 3/3] tests: gem_exec_basic: add "exec-ctx" buffer execution demo test Andi Shyti
@ 2018-11-26 22:23 ` Patchwork
  2018-12-14 15:50 ` [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev4) Patchwork
  4 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2018-11-26 22:23 UTC (permalink / raw)
  To: Andi Shyti; +Cc: igt-dev

== Series Details ==

Series: new engine discovery interface (rev3)
URL   : https://patchwork.freedesktop.org/series/52699/
State : failure

== Summary ==

= CI Bug Log - changes from IGT_4729 -> IGTPW_2095 =

== Summary - FAILURE ==

  Serious unknown changes coming with IGTPW_2095 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_2095, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/52699/revisions/3/mbox/

== Possible new issues ==

  Here are the unknown changes that may have been introduced in IGTPW_2095:

  === IGT changes ===

    ==== Possible regressions ====

    igt@gem_exec_suspend@basic-s4-devices:
      fi-ivb-3520m:       PASS -> FAIL

    
    ==== Warnings ====

    igt@kms_pipe_crc_basic@nonblocking-crc-pipe-c:
      {fi-kbl-7567u}:     PASS -> SKIP +33

    
== Known issues ==

  Here are the changes found in IGTPW_2095 that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_ctx_create@basic-files:
      fi-bsw-n3050:       PASS -> DMESG-FAIL (fdo#108656)

    igt@kms_frontbuffer_tracking@basic:
      {fi-icl-u3}:        PASS -> FAIL (fdo#103167)

    igt@kms_pipe_crc_basic@read-crc-pipe-b:
      fi-byt-clapper:     PASS -> FAIL (fdo#107362) +1

    igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
      fi-byt-clapper:     PASS -> FAIL (fdo#107362, fdo#103191)

    {igt@runner@aborted}:
      fi-bsw-n3050:       NOTRUN -> FAIL (fdo#108656)

    
    ==== Possible fixes ====

    igt@gem_exec_suspend@basic-s4-devices:
      fi-blb-e6850:       INCOMPLETE (fdo#107718) -> PASS

    igt@i915_selftest@live_hangcheck:
      {fi-icl-u3}:        INCOMPLETE (fdo#108315) -> PASS

    igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a-frame-sequence:
      fi-byt-clapper:     FAIL (fdo#107362, fdo#103191) -> PASS +2

    
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#103191 https://bugs.freedesktop.org/show_bug.cgi?id=103191
  fdo#107362 https://bugs.freedesktop.org/show_bug.cgi?id=107362
  fdo#107718 https://bugs.freedesktop.org/show_bug.cgi?id=107718
  fdo#108315 https://bugs.freedesktop.org/show_bug.cgi?id=108315
  fdo#108656 https://bugs.freedesktop.org/show_bug.cgi?id=108656


== Participating hosts (51 -> 46) ==

  Missing    (5): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 


== Build changes ==

    * IGT: IGT_4729 -> IGTPW_2095

  CI_DRM_5205: 48f2a38e885181b63502de679e4975551955ea74 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2095: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2095/
  IGT_4729: 2388bbd062c17b5912039101efd4603e8d876c88 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@gem_exec_basic@exec-ctx

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2095/issues.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: [igt-dev] [PATCH v3 3/3] tests: gem_exec_basic: add "exec-ctx" buffer execution demo test
  2018-11-26 21:10   ` Chris Wilson
@ 2018-11-27 11:40     ` Tvrtko Ursulin
  0 siblings, 0 replies; 14+ messages in thread
From: Tvrtko Ursulin @ 2018-11-27 11:40 UTC (permalink / raw)
  To: Chris Wilson, Andi Shyti, IGT dev; +Cc: Andi Shyti, Tvrtko Ursulin


On 26/11/2018 21:10, Chris Wilson wrote:
> Quoting Andi Shyti (2018-11-26 20:43:49)
>> The "exec-ctx" is a demo subtest inserted in the gem_exec_basic
>> test. The main scope is to demonstrate an alternative way for
>> querying engines as implemented in the new API in commit 87079e04
>> ("lib: implement new engine discovery interface").
>>
>> The "exec-ctx" subtest simply gets the list of engines, binds
>> them to a context and executes a buffer. This is done through a
>> new "for_each_engine_ctx" loop which iterates through the
>> engines.
> 
> See gem_ctx_engines for the intent of validating the ctx->engines[] api.

My bad, I wanted to suggest a simplest possible test which currently 
uses for_each_physical_engine, but gem_exec_basic is obviously not it.

Maybe gem_exec_nop?

Regards,

Tvrtko
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface
  2018-11-26 20:43 ` [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface Andi Shyti
@ 2018-11-27 12:00   ` Tvrtko Ursulin
  2018-11-27 20:33     ` Andi Shyti
  0 siblings, 1 reply; 14+ messages in thread
From: Tvrtko Ursulin @ 2018-11-27 12:00 UTC (permalink / raw)
  To: Andi Shyti, IGT dev; +Cc: Andi Shyti, Tvrtko Ursulin


On 26/11/2018 20:43, Andi Shyti wrote:
> Kernel commits:
> 
> [1] ae8f4544dd8f ("drm/i915: Engine discovery query")
> [2] 31e7d35667a0 ("drm/i915: Allow a context to define its set of engines")
> 
> from [*] repository, implement a new uapi for engine discovery
> that consist in first querying the driver about the engines in
> the gpu [1] and then binding a context to the set of engines that
> it can access [2].
> 
> In igt the classic way for discovering engines is done through
> the for_each_physical_engine() macro, that would be replaced by
> the new for_each_engine_ctx().
> 
> [*] git://people.freedesktop.org/~tursulin/drm-intel
> 
> Signed-off-by: Andi Shyti <andi.shyti@intel.com>
> ---
>   lib/igt_gt.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>   lib/igt_gt.h |  5 ++++
>   2 files changed, 79 insertions(+)
> 
> diff --git a/lib/igt_gt.c b/lib/igt_gt.c
> index a2061924..e5543b27 100644
> --- a/lib/igt_gt.c
> +++ b/lib/igt_gt.c
> @@ -650,3 +650,77 @@ bool gem_ring_has_physical_engine(int fd, unsigned ring)
>   
>   	return gem_has_ring(fd, ring);
>   }
> +
> +static struct drm_i915_query_engine_info *query_engines(int fd)
> +{
> +	struct drm_i915_query query = { };
> +	struct drm_i915_query_item item = { };
> +	struct drm_i915_query_engine_info *query_engines;
> +
> +	item.query_id = DRM_I915_QUERY_ENGINE_INFO;
> +	query.items_ptr = to_user_pointer(&item);
> +	query.num_items = 1;
> +
> +	/*
> +	 * The first ioctl is sent with item.length = 0
> +	 * which asks to the driver to store in length the
> +	 * memory needed for the engines. In the driver, length
> +	 * is equal to
> +	 *
> +	 *   len = sizeof(struct drm_i915_query_engine_info) +
> +	 *                   INTEL_INFO(i915)->num_rings *
> +	 *                   sizeof(struct drm_i915_engine_info);
> +	 */
> +	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
> +
> +	igt_assert((query_engines = calloc(item.length, 1)));
> +	item.data_ptr = to_user_pointer(query_engines);
> +
> +	/* The second ioctl stores the engines in query_engines */
> +	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
> +
> +	return query_engines;
> +}
> +
> +static void set_param(int fd, uint32_t ctx_id,
> +		      struct drm_i915_query_engine_info *query_engine)
> +{
> +	int i;
> +	struct drm_i915_gem_context_param ctx_param;
> +	struct i915_context_param_engines *ctx_engine;
> +	size_t size = sizeof(struct i915_context_param_engines) +
> +		      query_engine->num_engines *
> +		      sizeof(*ctx_engine->class_instance);
> +
> +	igt_assert((ctx_engine = malloc(size)));
> +
> +	ctx_engine->extensions = 0;
> +	for (i = 0; i < query_engine->num_engines; i++) {
> +		ctx_engine->class_instance[i].class = query_engine->engines[i].class;
> +		ctx_engine->class_instance[i].instance = query_engine->engines[i].instance;
> +	}
> +
> +	ctx_param.ctx_id = ctx_id;
> +	ctx_param.size = size;
> +	ctx_param.param = I915_CONTEXT_PARAM_ENGINES;
> +	ctx_param.value = to_user_pointer(ctx_engine);
> +
> +	/* check whether we free the engines */
> +	igt_require(!ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctx_param));
> +
> +	free(ctx_engine);

Leaks on skip, not that it matters a lot, but the comments makes me 
think you wanted to handle it.

> +}
> +
> +int __gem_setup_ctx_engines(int fd, uint32_t ctx_id)
> +{
> +	struct drm_i915_query_engine_info *query_engine;
> +	int n;
> +
> +	query_engine = query_engines(fd);
> +	set_param(fd, ctx_id, query_engine);
> +
> +	n = query_engine->num_engines;
> +	free(query_engine);
> +
> +	return n;
> +}
> diff --git a/lib/igt_gt.h b/lib/igt_gt.h
> index 54e95da9..512f958d 100644
> --- a/lib/igt_gt.h
> +++ b/lib/igt_gt.h
> @@ -86,8 +86,13 @@ extern const struct intel_execution_engine {
>   	     e__++) \
>   		for_if (gem_ring_has_physical_engine(fd__, flags__ = e__->exec_id | e__->flags))
>   
> +#define for_each_engine_ctx(fd, ctx, e) \
> +		for (int __m = __gem_setup_ctx_engines(fd, ctx), __e = e = 1; \
> +				__e <= __m; e = ++__e)
> +

Is __e needed? Could just use passed in e?

>   bool gem_ring_is_physical_engine(int fd, unsigned int ring);
>   bool gem_ring_has_physical_engine(int fd, unsigned int ring);
> +int __gem_setup_ctx_engines(int fd, uint32_t ctx_id);
>   
>   bool gem_can_store_dword(int fd, unsigned int engine);
>   
> 

Looks okay. But we need to decide whether we want the iterator to be a 
struct sooner rather than later now.

I think if you go and convert one of the tests which uses 
for_each_physical_engine to enumerate subtests and so, it will become 
clearer what approach work better. (struct iterator, or helpers to get 
data from engine index.)

Regards,

Tvrtko

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface
  2018-11-27 12:00   ` Tvrtko Ursulin
@ 2018-11-27 20:33     ` Andi Shyti
  2018-11-28  8:29       ` Tvrtko Ursulin
  0 siblings, 1 reply; 14+ messages in thread
From: Andi Shyti @ 2018-11-27 20:33 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: IGT dev, Andi Shyti, Tvrtko Ursulin

Hi Tvrtko,

> > +	ctx_param.ctx_id = ctx_id;
> > +	ctx_param.size = size;
> > +	ctx_param.param = I915_CONTEXT_PARAM_ENGINES;
> > +	ctx_param.value = to_user_pointer(ctx_engine);
> > +
> > +	/* check whether we free the engines */
> > +	igt_require(!ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctx_param));
> > +
> > +	free(ctx_engine);
> 
> Leaks on skip, not that it matters a lot, but the comments makes me think
> you wanted to handle it.

The comment is a leftover from the cleanup. I need to fix/remove
it.

While as for freeing ctx_engine in case of failure, some ugly code
would be required. I think it's cleaner to leave it as it is,
anyway 'igt_require' exits in case of failure.

> > +#define for_each_engine_ctx(fd, ctx, e) \
> > +		for (int __m = __gem_setup_ctx_engines(fd, ctx), __e = e = 1; \
> > +				__e <= __m; e = ++__e)
> > +
> 
> Is __e needed? Could just use passed in e?

I cannot mix declarations and "already declared variables"
initializations in the first expression in 'for'. If I do
something like:

  for (int __m = __gem_setup_ctx_engines(), e = 1; ... )

I would re-define 'e' and it would be a different variable
outside the loop.

So that either I declare '__m' outside, or I initialize 'e'
outside, or I use the double 'for' loop as it was done
previously, or do some ugly tricks.

It looked simplier to define an '__e'.

Am I missing anything?

> >   bool gem_ring_is_physical_engine(int fd, unsigned int ring);
> >   bool gem_ring_has_physical_engine(int fd, unsigned int ring);
> > +int __gem_setup_ctx_engines(int fd, uint32_t ctx_id);
> >   bool gem_can_store_dword(int fd, unsigned int engine);
> > 
> 
> Looks okay. But we need to decide whether we want the iterator to be a
> struct sooner rather than later now.
> 
> I think if you go and convert one of the tests which uses
> for_each_physical_engine to enumerate subtests and so, it will become
> clearer what approach work better. (struct iterator, or helpers to get data
> from engine index.)

All right, I'll try it out and I will post something as a reply to this
patch.

Thanks a lot, Tvrtko!
Andi
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface
  2018-11-27 20:33     ` Andi Shyti
@ 2018-11-28  8:29       ` Tvrtko Ursulin
  2018-12-14 15:34         ` [igt-dev] [PATCH v3.5 " Andi Shyti
  0 siblings, 1 reply; 14+ messages in thread
From: Tvrtko Ursulin @ 2018-11-28  8:29 UTC (permalink / raw)
  To: Andi Shyti; +Cc: IGT dev, Andi Shyti, Tvrtko Ursulin


On 27/11/2018 20:33, Andi Shyti wrote:
> Hi Tvrtko,
> 
>>> +	ctx_param.ctx_id = ctx_id;
>>> +	ctx_param.size = size;
>>> +	ctx_param.param = I915_CONTEXT_PARAM_ENGINES;
>>> +	ctx_param.value = to_user_pointer(ctx_engine);
>>> +
>>> +	/* check whether we free the engines */
>>> +	igt_require(!ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctx_param));
>>> +
>>> +	free(ctx_engine);
>>
>> Leaks on skip, not that it matters a lot, but the comments makes me think
>> you wanted to handle it.
> 
> The comment is a leftover from the cleanup. I need to fix/remove
> it.
> 
> While as for freeing ctx_engine in case of failure, some ugly code
> would be required. I think it's cleaner to leave it as it is,
> anyway 'igt_require' exits in case of failure.

Yeah, ok.

>>> +#define for_each_engine_ctx(fd, ctx, e) \
>>> +		for (int __m = __gem_setup_ctx_engines(fd, ctx), __e = e = 1; \
>>> +				__e <= __m; e = ++__e)
>>> +
>>
>> Is __e needed? Could just use passed in e?
> 
> I cannot mix declarations and "already declared variables"
> initializations in the first expression in 'for'. If I do
> something like:
> 
>    for (int __m = __gem_setup_ctx_engines(), e = 1; ... )
> 
> I would re-define 'e' and it would be a different variable
> outside the loop.
> 
> So that either I declare '__m' outside, or I initialize 'e'
> outside, or I use the double 'for' loop as it was done
> previously, or do some ugly tricks.
> 
> It looked simplier to define an '__e'.
> 
> Am I missing anything?

No, looks like you're right, makes sense.

>>>    bool gem_ring_is_physical_engine(int fd, unsigned int ring);
>>>    bool gem_ring_has_physical_engine(int fd, unsigned int ring);
>>> +int __gem_setup_ctx_engines(int fd, uint32_t ctx_id);
>>>    bool gem_can_store_dword(int fd, unsigned int engine);
>>>
>>
>> Looks okay. But we need to decide whether we want the iterator to be a
>> struct sooner rather than later now.
>>
>> I think if you go and convert one of the tests which uses
>> for_each_physical_engine to enumerate subtests and so, it will become
>> clearer what approach work better. (struct iterator, or helpers to get data
>> from engine index.)
> 
> All right, I'll try it out and I will post something as a reply to this
> patch.

Ack.

Regards,

Tvrtko

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] [PATCH v3.5 2/3] lib: implement new engine discovery interface
  2018-11-28  8:29       ` Tvrtko Ursulin
@ 2018-12-14 15:34         ` Andi Shyti
  2018-12-21 11:48           ` Tvrtko Ursulin
  0 siblings, 1 reply; 14+ messages in thread
From: Andi Shyti @ 2018-12-14 15:34 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: IGT dev, Andi Shyti, Tvrtko Ursulin

Hi Tvrtko,

would the following patch work? the "for_each_engine_ctx()" gets
an argument more that is a double pointer to a "struct
intel_execution_engine2".

The __gem_setup_ctx_engines() function allocates an array of
engines where it stores the engines present in the GPU.

The new iterator can be used either:

  ...
  struct intel_execution_engine2 *engines;

  for_each_engine_ctx(fd, ctx_id, r, &engines) {
    printf("engine %d is %s\n", r, engines[r].name);
  }

or, if the user is not interested at getting the structure, can
send NULL instead and get nothing.

  for_each_engine_ctx(fd, ctx_id, r, NULL) {
    ...
  }

Is this what you meant to get from the kernel?

Thanks,
Andi

---
 lib/igt_gt.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_gt.h |  6 ++++
 2 files changed, 105 insertions(+)

diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index a20619246296..8616dba44f13 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -650,3 +650,102 @@ bool gem_ring_has_physical_engine(int fd, unsigned ring)
 
 	return gem_has_ring(fd, ring);
 }
+
+static struct drm_i915_query_engine_info *query_engines(int fd)
+{
+	struct drm_i915_query query = { };
+	struct drm_i915_query_item item = { };
+	struct drm_i915_query_engine_info *query_engines;
+
+	item.query_id = DRM_I915_QUERY_ENGINE_INFO;
+	query.items_ptr = to_user_pointer(&item);
+	query.num_items = 1;
+
+	/*
+	 * The first ioctl is sent with item.length = 0
+	 * which asks to the driver to store in length the
+	 * memory needed for the engines. In the driver, length
+	 * is equal to
+	 *
+	 *   len = sizeof(struct drm_i915_query_engine_info) +
+	 *                   INTEL_INFO(i915)->num_rings *
+	 *                   sizeof(struct drm_i915_engine_info);
+	 */
+	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
+
+	igt_assert((query_engines = calloc(item.length, 1)));
+	item.data_ptr = to_user_pointer(query_engines);
+
+	/* The second ioctl stores the engines in query_engines */
+	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
+
+	return query_engines;
+}
+
+static void store_engine(struct intel_execution_engine2 *to,
+			 struct drm_i915_engine_info *from)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(intel_execution_engines2); i++)
+		if (from->class == intel_execution_engines2[i].class &&
+		    from->instance == intel_execution_engines2[i].instance) {
+			to->name = intel_execution_engines2[i].name;
+			to->instance = intel_execution_engines2[i].instance;
+			to->class = intel_execution_engines2[i].class;
+		}
+}
+
+static void set_param(int fd, uint32_t ctx_id,
+		      struct drm_i915_query_engine_info *query_engine,
+		      struct intel_execution_engine2 *engines)
+{
+	int i;
+	struct drm_i915_gem_context_param ctx_param;
+	struct i915_context_param_engines *ctx_engine;
+	size_t size = sizeof(struct i915_context_param_engines) +
+		      query_engine->num_engines *
+		      sizeof(*ctx_engine->class_instance);
+
+	igt_assert((ctx_engine = malloc(size)));
+
+	ctx_engine->extensions = 0;
+	for (i = 0; i < query_engine->num_engines; i++) {
+
+		ctx_engine->class_instance[i].class = query_engine->engines[i].class;
+		ctx_engine->class_instance[i].instance = query_engine->engines[i].instance;
+
+		if(engines)
+			store_engine(&engines[i], &query_engine->engines[i]);
+	}
+
+	ctx_param.ctx_id = ctx_id;
+	ctx_param.size = size;
+	ctx_param.param = I915_CONTEXT_PARAM_ENGINES;
+	ctx_param.value = to_user_pointer(ctx_engine);
+
+	/* check whether we free the engines */
+	igt_require(!ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctx_param));
+
+	free(ctx_engine);
+}
+
+int __gem_setup_ctx_engines(int fd, uint32_t ctx_id,
+			    struct intel_execution_engine2 **engines)
+{
+	struct drm_i915_query_engine_info *query_engine;
+	int n;
+
+	query_engine = query_engines(fd);
+
+	n = query_engine->num_engines;
+
+	if (engines)
+		igt_assert(*engines = malloc(n * sizeof(**engines)));
+
+	set_param(fd, ctx_id, query_engine, engines ? *engines : NULL);
+
+	free(query_engine);
+
+	return n;
+}
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index 54e95da98084..cb51082b1bed 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -86,6 +86,10 @@ extern const struct intel_execution_engine {
 	     e__++) \
 		for_if (gem_ring_has_physical_engine(fd__, flags__ = e__->exec_id | e__->flags))
 
+#define for_each_engine_ctx(fd, ctx, e, engines) \
+		for (int __m = __gem_setup_ctx_engines(fd, ctx, engines), __e = e = 1; \
+				__e < __m; e = ++__e)
+
 bool gem_ring_is_physical_engine(int fd, unsigned int ring);
 bool gem_ring_has_physical_engine(int fd, unsigned int ring);
 
@@ -97,6 +101,8 @@ extern const struct intel_execution_engine2 {
 	int instance;
 } intel_execution_engines2[];
 
+int __gem_setup_ctx_engines(int fd, uint32_t ctx_id, struct intel_execution_engine2 **engines);
+
 unsigned int
 gem_class_instance_to_eb_flags(int gem_fd,
 			       enum drm_i915_gem_engine_class class,
-- 
2.20.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev4)
  2018-11-26 20:43 [igt-dev] [PATCH v3 0/3] new engine discovery interface Andi Shyti
                   ` (3 preceding siblings ...)
  2018-11-26 22:23 ` [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev3) Patchwork
@ 2018-12-14 15:50 ` Patchwork
  4 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2018-12-14 15:50 UTC (permalink / raw)
  To: Andi Shyti; +Cc: igt-dev

== Series Details ==

Series: new engine discovery interface (rev4)
URL   : https://patchwork.freedesktop.org/series/52699/
State : failure

== Summary ==

Applying: include/drm-uapi: import i915_drm.h header file
Using index info to reconstruct a base tree...
M	include/drm-uapi/i915_drm.h
Falling back to patching base and 3-way merge...
Auto-merging include/drm-uapi/i915_drm.h
CONFLICT (content): Merge conflict in include/drm-uapi/i915_drm.h
Patch failed at 0001 include/drm-uapi: import i915_drm.h header file
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: [igt-dev] [PATCH v3.5 2/3] lib: implement new engine discovery interface
  2018-12-14 15:34         ` [igt-dev] [PATCH v3.5 " Andi Shyti
@ 2018-12-21 11:48           ` Tvrtko Ursulin
  0 siblings, 0 replies; 14+ messages in thread
From: Tvrtko Ursulin @ 2018-12-21 11:48 UTC (permalink / raw)
  To: Andi Shyti; +Cc: IGT dev, Andi Shyti, Tvrtko Ursulin


On 14/12/2018 15:34, Andi Shyti wrote:
> Hi Tvrtko,
> 
> would the following patch work? the "for_each_engine_ctx()" gets
> an argument more that is a double pointer to a "struct
> intel_execution_engine2".
> 
> The __gem_setup_ctx_engines() function allocates an array of
> engines where it stores the engines present in the GPU.
> 
> The new iterator can be used either:
> 
>    ...
>    struct intel_execution_engine2 *engines;
> 
>    for_each_engine_ctx(fd, ctx_id, r, &engines) {
>      printf("engine %d is %s\n", r, engines[r].name);
>    }
> 
> or, if the user is not interested at getting the structure, can
> send NULL instead and get nothing.
> 
>    for_each_engine_ctx(fd, ctx_id, r, NULL) {
>      ...
>    }
> 
> Is this what you meant to get from the kernel?

I was thinking that either on the first call to the new iterator, or 
somewhere from drm fd open, we would create this dynamic array, 
replacing the existing static array in lib/igt_gt.c.

So we wouldn't have this extra parameter to the iterator.

Another note - see to convert for_each_engine_class_instance to the new 
scheme and also all places which use PMU to probe for engine existence. 
(Could be only perf_pmu is upstream which does it.)

Basically all code which uses gem_class_instance_to_eb_flags needs to be 
converted to the engine map approach and that helper removed.

Can be a second stage together with for_each_physical_engine conversion.

Regards,

Tvrtko

> 
> Thanks,
> Andi
> 
> ---
>   lib/igt_gt.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>   lib/igt_gt.h |  6 ++++
>   2 files changed, 105 insertions(+)
> 
> diff --git a/lib/igt_gt.c b/lib/igt_gt.c
> index a20619246296..8616dba44f13 100644
> --- a/lib/igt_gt.c
> +++ b/lib/igt_gt.c
> @@ -650,3 +650,102 @@ bool gem_ring_has_physical_engine(int fd, unsigned ring)
>   
>   	return gem_has_ring(fd, ring);
>   }
> +
> +static struct drm_i915_query_engine_info *query_engines(int fd)
> +{
> +	struct drm_i915_query query = { };
> +	struct drm_i915_query_item item = { };
> +	struct drm_i915_query_engine_info *query_engines;
> +
> +	item.query_id = DRM_I915_QUERY_ENGINE_INFO;
> +	query.items_ptr = to_user_pointer(&item);
> +	query.num_items = 1;
> +
> +	/*
> +	 * The first ioctl is sent with item.length = 0
> +	 * which asks to the driver to store in length the
> +	 * memory needed for the engines. In the driver, length
> +	 * is equal to
> +	 *
> +	 *   len = sizeof(struct drm_i915_query_engine_info) +
> +	 *                   INTEL_INFO(i915)->num_rings *
> +	 *                   sizeof(struct drm_i915_engine_info);
> +	 */
> +	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
> +
> +	igt_assert((query_engines = calloc(item.length, 1)));
> +	item.data_ptr = to_user_pointer(query_engines);
> +
> +	/* The second ioctl stores the engines in query_engines */
> +	igt_require(!ioctl(fd, DRM_IOCTL_I915_QUERY, &query));
> +
> +	return query_engines;
> +}
> +
> +static void store_engine(struct intel_execution_engine2 *to,
> +			 struct drm_i915_engine_info *from)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(intel_execution_engines2); i++)
> +		if (from->class == intel_execution_engines2[i].class &&
> +		    from->instance == intel_execution_engines2[i].instance) {
> +			to->name = intel_execution_engines2[i].name;
> +			to->instance = intel_execution_engines2[i].instance;
> +			to->class = intel_execution_engines2[i].class;
> +		}
> +}
> +
> +static void set_param(int fd, uint32_t ctx_id,
> +		      struct drm_i915_query_engine_info *query_engine,
> +		      struct intel_execution_engine2 *engines)
> +{
> +	int i;
> +	struct drm_i915_gem_context_param ctx_param;
> +	struct i915_context_param_engines *ctx_engine;
> +	size_t size = sizeof(struct i915_context_param_engines) +
> +		      query_engine->num_engines *
> +		      sizeof(*ctx_engine->class_instance);
> +
> +	igt_assert((ctx_engine = malloc(size)));
> +
> +	ctx_engine->extensions = 0;
> +	for (i = 0; i < query_engine->num_engines; i++) {
> +
> +		ctx_engine->class_instance[i].class = query_engine->engines[i].class;
> +		ctx_engine->class_instance[i].instance = query_engine->engines[i].instance;
> +
> +		if(engines)
> +			store_engine(&engines[i], &query_engine->engines[i]);
> +	}
> +
> +	ctx_param.ctx_id = ctx_id;
> +	ctx_param.size = size;
> +	ctx_param.param = I915_CONTEXT_PARAM_ENGINES;
> +	ctx_param.value = to_user_pointer(ctx_engine);
> +
> +	/* check whether we free the engines */
> +	igt_require(!ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctx_param));
> +
> +	free(ctx_engine);
> +}
> +
> +int __gem_setup_ctx_engines(int fd, uint32_t ctx_id,
> +			    struct intel_execution_engine2 **engines)
> +{
> +	struct drm_i915_query_engine_info *query_engine;
> +	int n;
> +
> +	query_engine = query_engines(fd);
> +
> +	n = query_engine->num_engines;
> +
> +	if (engines)
> +		igt_assert(*engines = malloc(n * sizeof(**engines)));
> +
> +	set_param(fd, ctx_id, query_engine, engines ? *engines : NULL);
> +
> +	free(query_engine);
> +
> +	return n;
> +}
> diff --git a/lib/igt_gt.h b/lib/igt_gt.h
> index 54e95da98084..cb51082b1bed 100644
> --- a/lib/igt_gt.h
> +++ b/lib/igt_gt.h
> @@ -86,6 +86,10 @@ extern const struct intel_execution_engine {
>   	     e__++) \
>   		for_if (gem_ring_has_physical_engine(fd__, flags__ = e__->exec_id | e__->flags))
>   
> +#define for_each_engine_ctx(fd, ctx, e, engines) \
> +		for (int __m = __gem_setup_ctx_engines(fd, ctx, engines), __e = e = 1; \
> +				__e < __m; e = ++__e)
> +
>   bool gem_ring_is_physical_engine(int fd, unsigned int ring);
>   bool gem_ring_has_physical_engine(int fd, unsigned int ring);
>   
> @@ -97,6 +101,8 @@ extern const struct intel_execution_engine2 {
>   	int instance;
>   } intel_execution_engines2[];
>   
> +int __gem_setup_ctx_engines(int fd, uint32_t ctx_id, struct intel_execution_engine2 **engines);
> +
>   unsigned int
>   gem_class_instance_to_eb_flags(int gem_fd,
>   			       enum drm_i915_gem_engine_class class,
> 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev3)
  2019-04-08 16:15 [igt-dev] [PATCH v19 0/6] new engine discovery interface Andi Shyti
@ 2019-04-11 14:54 ` Patchwork
  0 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2019-04-11 14:54 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: igt-dev

== Series Details ==

Series: new engine discovery interface (rev3)
URL   : https://patchwork.freedesktop.org/series/59185/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_5909 -> IGTPW_2846
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_2846 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_2846, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/59185/revisions/3/mbox/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_2846:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_wait@basic-busy-all:
    - fi-bwr-2160:        PASS -> FAIL +1
    - fi-pnv-d510:        PASS -> FAIL +1

  
Known issues
------------

  Here are the changes found in IGTPW_2846 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-blb-e6850:       PASS -> INCOMPLETE [fdo#107718]

  * igt@i915_selftest@live_evict:
    - fi-bsw-kefka:       PASS -> DMESG-WARN [fdo#107709]

  * igt@i915_selftest@live_execlists:
    - fi-apl-guc:         PASS -> INCOMPLETE [fdo#103927] / [fdo#109720]

  * igt@kms_cursor_legacy@basic-flip-before-cursor-varying-size:
    - fi-glk-dsi:         PASS -> INCOMPLETE [fdo#103359] / [k.org#198133]

  * igt@runner@aborted:
    - fi-bsw-kefka:       NOTRUN -> FAIL [fdo#107709]
    - fi-apl-guc:         NOTRUN -> FAIL [fdo#108622] / [fdo#109720]

  
#### Possible fixes ####

  * igt@i915_selftest@live_hangcheck:
    - fi-bxt-dsi:         INCOMPLETE [fdo#103927] -> PASS

  
  [fdo#103359]: https://bugs.freedesktop.org/show_bug.cgi?id=103359
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#107709]: https://bugs.freedesktop.org/show_bug.cgi?id=107709
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#108622]: https://bugs.freedesktop.org/show_bug.cgi?id=108622
  [fdo#109720]: https://bugs.freedesktop.org/show_bug.cgi?id=109720
  [k.org#198133]: https://bugzilla.kernel.org/show_bug.cgi?id=198133


Participating hosts (49 -> 41)
------------------------------

  Missing    (8): fi-ilk-m540 fi-skl-6770hq fi-byt-squawks fi-bsw-cyan fi-gdg-551 fi-cfl-8109u fi-bdw-samus fi-skl-6700k2 


Build changes
-------------

    * IGT: IGT_4943 -> IGTPW_2846

  CI_DRM_5909: af07fbb536d0728e381cc001cac5bc259c41fe02 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2846: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2846/
  IGT_4943: 5941f371b0fe25084d4b1c49882faa8d41d44c9f @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Logs ==

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

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

end of thread, other threads:[~2019-04-11 14:54 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-26 20:43 [igt-dev] [PATCH v3 0/3] new engine discovery interface Andi Shyti
2018-11-26 20:43 ` [igt-dev] [PATCH v3 1/3] include/drm-uapi: import i915_drm.h header file Andi Shyti
2018-11-26 20:43 ` [igt-dev] [PATCH v3 2/3] lib: implement new engine discovery interface Andi Shyti
2018-11-27 12:00   ` Tvrtko Ursulin
2018-11-27 20:33     ` Andi Shyti
2018-11-28  8:29       ` Tvrtko Ursulin
2018-12-14 15:34         ` [igt-dev] [PATCH v3.5 " Andi Shyti
2018-12-21 11:48           ` Tvrtko Ursulin
2018-11-26 20:43 ` [igt-dev] [PATCH v3 3/3] tests: gem_exec_basic: add "exec-ctx" buffer execution demo test Andi Shyti
2018-11-26 21:10   ` Chris Wilson
2018-11-27 11:40     ` Tvrtko Ursulin
2018-11-26 22:23 ` [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev3) Patchwork
2018-12-14 15:50 ` [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev4) Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2019-04-08 16:15 [igt-dev] [PATCH v19 0/6] new engine discovery interface Andi Shyti
2019-04-11 14:54 ` [igt-dev] ✗ Fi.CI.BAT: failure for new engine discovery interface (rev3) Patchwork

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox