* [igt-dev] [PATCH v17 1/7] lib/igt_gt: remove unnecessary argument
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
@ 2019-04-05 1:07 ` Andi Shyti
2019-04-05 14:43 ` Caz Yokoyama
2019-04-05 1:07 ` [igt-dev] [PATCH v17 2/7] lib: ioctl_wrappers: reach engines by index as well Andi Shyti
` (6 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 1:07 UTC (permalink / raw)
To: IGT dev; +Cc: Andi Shyti
From: Andi Shyti <andi.shyti@intel.com>
__for_each_engine_class_instance(fd, e) doesn't need and doesn't
use the fd argument. Remove it.
Signed-off-by: Andi Shyti <andi.shyti@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
lib/igt_gt.h | 2 +-
tests/perf_pmu.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index 54e95da98084..475c0b3c3cc6 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -114,7 +114,7 @@ void gem_require_engine(int gem_fd,
igt_require(gem_has_engine(gem_fd, class, instance));
}
-#define __for_each_engine_class_instance(fd__, e__) \
+#define __for_each_engine_class_instance(e__) \
for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
#define for_each_engine_class_instance(fd__, e__) \
diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
index 1a08f564b066..4f552bc2ae28 100644
--- a/tests/perf_pmu.c
+++ b/tests/perf_pmu.c
@@ -1693,7 +1693,7 @@ igt_main
igt_subtest("invalid-init")
invalid_init();
- __for_each_engine_class_instance(fd, e) {
+ __for_each_engine_class_instance(e) {
const unsigned int pct[] = { 2, 50, 98 };
/**
@@ -1897,7 +1897,7 @@ igt_main
gem_quiescent_gpu(fd);
}
- __for_each_engine_class_instance(render_fd, e) {
+ __for_each_engine_class_instance(e) {
igt_subtest_group {
igt_fixture {
gem_require_engine(render_fd,
--
2.20.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 1/7] lib/igt_gt: remove unnecessary argument
2019-04-05 1:07 ` [igt-dev] [PATCH v17 1/7] lib/igt_gt: remove unnecessary argument Andi Shyti
@ 2019-04-05 14:43 ` Caz Yokoyama
0 siblings, 0 replies; 18+ messages in thread
From: Caz Yokoyama @ 2019-04-05 14:43 UTC (permalink / raw)
To: Andi Shyti, IGT dev
Reviewed-by: Caz Yokoyama <caz.yokoyama@intel.com>
On Fri, 2019-04-05 at 04:07 +0300, Andi Shyti wrote:
> From: Andi Shyti <andi.shyti@intel.com>
>
> __for_each_engine_class_instance(fd, e) doesn't need and doesn't
> use the fd argument. Remove it.
>
> Signed-off-by: Andi Shyti <andi.shyti@intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
> lib/igt_gt.h | 2 +-
> tests/perf_pmu.c | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/lib/igt_gt.h b/lib/igt_gt.h
> index 54e95da98084..475c0b3c3cc6 100644
> --- a/lib/igt_gt.h
> +++ b/lib/igt_gt.h
> @@ -114,7 +114,7 @@ void gem_require_engine(int gem_fd,
> igt_require(gem_has_engine(gem_fd, class, instance));
> }
>
> -#define __for_each_engine_class_instance(fd__, e__) \
> +#define __for_each_engine_class_instance(e__) \
> for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
>
> #define for_each_engine_class_instance(fd__, e__) \
> diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
> index 1a08f564b066..4f552bc2ae28 100644
> --- a/tests/perf_pmu.c
> +++ b/tests/perf_pmu.c
> @@ -1693,7 +1693,7 @@ igt_main
> igt_subtest("invalid-init")
> invalid_init();
>
> - __for_each_engine_class_instance(fd, e) {
> + __for_each_engine_class_instance(e) {
> const unsigned int pct[] = { 2, 50, 98 };
>
> /**
> @@ -1897,7 +1897,7 @@ igt_main
> gem_quiescent_gpu(fd);
> }
>
> - __for_each_engine_class_instance(render_fd, e) {
> + __for_each_engine_class_instance(e) {
> igt_subtest_group {
> igt_fixture {
> gem_require_engine(render_fd,
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread
* [igt-dev] [PATCH v17 2/7] lib: ioctl_wrappers: reach engines by index as well
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
2019-04-05 1:07 ` [igt-dev] [PATCH v17 1/7] lib/igt_gt: remove unnecessary argument Andi Shyti
@ 2019-04-05 1:07 ` Andi Shyti
2019-04-05 7:59 ` Chris Wilson
2019-04-05 1:07 ` [igt-dev] [PATCH v17 3/7] include/drm-uapi: import i915_drm.h header file Andi Shyti
` (5 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 1:07 UTC (permalink / raw)
To: IGT dev; +Cc: Andi Shyti
From: Andi Shyti <andi.shyti@intel.com>
With the new engine query method engines are reachable through
an index and context they are combined with.
The 'gem_has_ring()' becomes 'gem_context_has_engine()' that
requires the index that the engine is mapped within the driver.
The function has been moved from lib/ioctl_wappers to
lib/i915/gem_context where it is more appropriate.
The previous 'gem_has_ring()' function becomes a wrapper to the
new 'gem_context_has_engine()'.
Signed-off-by: Andi Shyti <andi.shyti@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
lib/i915/gem_context.c | 27 +++++++++++++++++++++++++++
lib/i915/gem_context.h | 2 ++
lib/ioctl_wrappers.c | 19 -------------------
lib/ioctl_wrappers.h | 3 ++-
4 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/lib/i915/gem_context.c b/lib/i915/gem_context.c
index 8b4d5b704650..488f4971c448 100644
--- a/lib/i915/gem_context.c
+++ b/lib/i915/gem_context.c
@@ -271,3 +271,30 @@ void gem_context_set_priority(int fd, uint32_t ctx_id, int prio)
{
igt_assert_eq(__gem_context_set_priority(fd, ctx_id, prio), 0);
}
+
+bool gem_context_has_engine(int fd, uint64_t ctx, uint64_t engine)
+{
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_exec_object2 exec;
+
+ /*
+ * 'engine' value can either store an execbuf engine selector
+ * or a context map index; for the latter case we do not expect
+ * to have any value at bit 13 and 14 (BSD1/2 selector),
+ * therefore, we assume that the following check is safe and it
+ * wouldn't produce any result.
+ */
+ if ((engine & ~(3<<13)) == I915_EXEC_BSD) {
+ if (engine & (3 << 13) && !gem_has_bsd2(fd))
+ return false;
+ }
+
+ memset(&exec, 0, sizeof(exec));
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&exec);
+ execbuf.buffer_count = 1;
+ execbuf.flags = engine;
+ execbuf.rsvd1 = ctx;
+
+ return __gem_execbuf(fd, &execbuf) == -ENOENT;
+}
diff --git a/lib/i915/gem_context.h b/lib/i915/gem_context.h
index aef68dda6b26..d4e8fec3acf0 100644
--- a/lib/i915/gem_context.h
+++ b/lib/i915/gem_context.h
@@ -45,4 +45,6 @@ int __gem_context_get_param(int fd, struct drm_i915_gem_context_param *p);
int __gem_context_set_priority(int fd, uint32_t ctx, int prio);
void gem_context_set_priority(int fd, uint32_t ctx, int prio);
+bool gem_context_has_engine(int fd, uint64_t ctx, uint64_t engine);
+
#endif /* GEM_CONTEXT_H */
diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 39920f8707d2..280fdd624529 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -1252,25 +1252,6 @@ void igt_require_gem(int fd)
igt_require_f(err == 0, "Unresponsive i915/GEM device\n");
}
-bool gem_has_ring(int fd, unsigned ring)
-{
- struct drm_i915_gem_execbuffer2 execbuf;
- struct drm_i915_gem_exec_object2 exec;
-
- /* silly ABI, the kernel thinks everyone who has BSD also has BSD2 */
- if ((ring & ~(3<<13)) == I915_EXEC_BSD) {
- if (ring & (3 << 13) && !gem_has_bsd2(fd))
- return false;
- }
-
- memset(&exec, 0, sizeof(exec));
- memset(&execbuf, 0, sizeof(execbuf));
- execbuf.buffers_ptr = to_user_pointer(&exec);
- execbuf.buffer_count = 1;
- execbuf.flags = ring;
- return __gem_execbuf(fd, &execbuf) == -ENOENT;
-}
-
/**
* gem_require_ring:
* @fd: open i915 drm file descriptor
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index f0be26080da6..03211c970bbf 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -142,11 +142,12 @@ bool gem_has_exec_fence(int fd);
/* check functions which auto-skip tests by calling igt_skip() */
void gem_require_caching(int fd);
-bool gem_has_ring(int fd, unsigned ring);
void gem_require_ring(int fd, unsigned ring);
bool gem_has_mocs_registers(int fd);
void gem_require_mocs_registers(int fd);
+#define gem_has_ring(f, r) gem_context_has_engine(f, 0, r)
+
/* prime */
struct local_dma_buf_sync {
uint64_t flags;
--
2.20.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 2/7] lib: ioctl_wrappers: reach engines by index as well
2019-04-05 1:07 ` [igt-dev] [PATCH v17 2/7] lib: ioctl_wrappers: reach engines by index as well Andi Shyti
@ 2019-04-05 7:59 ` Chris Wilson
2019-04-05 8:35 ` Andi Shyti
0 siblings, 1 reply; 18+ messages in thread
From: Chris Wilson @ 2019-04-05 7:59 UTC (permalink / raw)
To: Andi Shyti, IGT dev; +Cc: Andi Shyti
Quoting Andi Shyti (2019-04-05 02:07:32)
> From: Andi Shyti <andi.shyti@intel.com>
>
> With the new engine query method engines are reachable through
> an index and context they are combined with.
>
> The 'gem_has_ring()' becomes 'gem_context_has_engine()' that
> requires the index that the engine is mapped within the driver.
> The function has been moved from lib/ioctl_wappers to
> lib/i915/gem_context where it is more appropriate.
>
> The previous 'gem_has_ring()' function becomes a wrapper to the
> new 'gem_context_has_engine()'.
>
> Signed-off-by: Andi Shyti <andi.shyti@intel.com>
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
> lib/i915/gem_context.c | 27 +++++++++++++++++++++++++++
> lib/i915/gem_context.h | 2 ++
> lib/ioctl_wrappers.c | 19 -------------------
> lib/ioctl_wrappers.h | 3 ++-
> 4 files changed, 31 insertions(+), 20 deletions(-)
>
> diff --git a/lib/i915/gem_context.c b/lib/i915/gem_context.c
> index 8b4d5b704650..488f4971c448 100644
> --- a/lib/i915/gem_context.c
> +++ b/lib/i915/gem_context.c
> @@ -271,3 +271,30 @@ void gem_context_set_priority(int fd, uint32_t ctx_id, int prio)
> {
> igt_assert_eq(__gem_context_set_priority(fd, ctx_id, prio), 0);
> }
> +
> +bool gem_context_has_engine(int fd, uint64_t ctx, uint64_t engine)
Despite appearances, ctx is only a u32. And rsvd1 has the upper 32bits
still unassigned. Left engine as uint64_t, feels overkill but flags is a
full 64b and there may be good reason to stuff extra flags through this
interface (though that may be rightfully considered abuse).
Pushed this first pair, thanks.
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 2/7] lib: ioctl_wrappers: reach engines by index as well
2019-04-05 7:59 ` Chris Wilson
@ 2019-04-05 8:35 ` Andi Shyti
0 siblings, 0 replies; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 8:35 UTC (permalink / raw)
To: Chris Wilson; +Cc: IGT dev, Andi Shyti
On Fri, Apr 05, 2019 at 08:59:30AM +0100, Chris Wilson wrote:
> Quoting Andi Shyti (2019-04-05 02:07:32)
> > From: Andi Shyti <andi.shyti@intel.com>
> >
> > With the new engine query method engines are reachable through
> > an index and context they are combined with.
> >
> > The 'gem_has_ring()' becomes 'gem_context_has_engine()' that
> > requires the index that the engine is mapped within the driver.
> > The function has been moved from lib/ioctl_wappers to
> > lib/i915/gem_context where it is more appropriate.
> >
> > The previous 'gem_has_ring()' function becomes a wrapper to the
> > new 'gem_context_has_engine()'.
> >
> > Signed-off-by: Andi Shyti <andi.shyti@intel.com>
> > Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> > ---
> > lib/i915/gem_context.c | 27 +++++++++++++++++++++++++++
> > lib/i915/gem_context.h | 2 ++
> > lib/ioctl_wrappers.c | 19 -------------------
> > lib/ioctl_wrappers.h | 3 ++-
> > 4 files changed, 31 insertions(+), 20 deletions(-)
> >
> > diff --git a/lib/i915/gem_context.c b/lib/i915/gem_context.c
> > index 8b4d5b704650..488f4971c448 100644
> > --- a/lib/i915/gem_context.c
> > +++ b/lib/i915/gem_context.c
> > @@ -271,3 +271,30 @@ void gem_context_set_priority(int fd, uint32_t ctx_id, int prio)
> > {
> > igt_assert_eq(__gem_context_set_priority(fd, ctx_id, prio), 0);
> > }
> > +
> > +bool gem_context_has_engine(int fd, uint64_t ctx, uint64_t engine)
>
> Despite appearances, ctx is only a u32. And rsvd1 has the upper 32bits
> still unassigned. Left engine as uint64_t, feels overkill but flags is a
> full 64b and there may be good reason to stuff extra flags through this
> interface (though that may be rightfully considered abuse).
Thanks, Chris!
Andi
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread
* [igt-dev] [PATCH v17 3/7] include/drm-uapi: import i915_drm.h header file
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
2019-04-05 1:07 ` [igt-dev] [PATCH v17 1/7] lib/igt_gt: remove unnecessary argument Andi Shyti
2019-04-05 1:07 ` [igt-dev] [PATCH v17 2/7] lib: ioctl_wrappers: reach engines by index as well Andi Shyti
@ 2019-04-05 1:07 ` Andi Shyti
2019-04-05 1:07 ` [igt-dev] [PATCH v17 4/7] lib/i915: add gem_engine_topology library and for_each loop definition Andi Shyti
` (4 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 1:07 UTC (permalink / raw)
To: IGT dev; +Cc: Andi Shyti
From: Andi Shyti <andi.shyti@intel.com>
This header file is imported in order to include the two new
ioctls DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM,
DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM and DRM_IOCTL_I915_QUERY.
Signed-off-by: Andi Shyti <andi.shyti@intel.com>
---
include/drm-uapi/i915_drm.h | 361 ++++++++++++++++++++++++++++++------
1 file changed, 304 insertions(+), 57 deletions(-)
diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 4ae1c6ff6ae6..2bbad08eb9d2 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.
@@ -104,6 +124,9 @@ enum drm_i915_gem_engine_class {
I915_ENGINE_CLASS_INVALID = -1
};
+#define I915_ENGINE_CLASS_INVALID_NONE -1
+#define I915_ENGINE_CLASS_INVALID_VIRTUAL 0
+
/**
* DOC: perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915
*
@@ -321,6 +344,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_PERF_ADD_CONFIG 0x37
#define DRM_I915_PERF_REMOVE_CONFIG 0x38
#define DRM_I915_QUERY 0x39
+#define DRM_I915_GEM_VM_CREATE 0x3a
+#define DRM_I915_GEM_VM_DESTROY 0x3b
/* Must be kept compact -- no holes */
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
@@ -370,6 +395,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_EXT DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create_ext)
#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)
@@ -380,6 +406,8 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
+#define DRM_IOCTL_I915_GEM_VM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_CREATE, struct drm_i915_gem_vm_control)
+#define DRM_IOCTL_I915_GEM_VM_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_VM_DESTROY, struct drm_i915_gem_vm_control)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -563,6 +591,12 @@ typedef struct drm_i915_irq_wait {
*/
#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
/* Must be kept compact -- no holes and well documented */
typedef struct drm_i915_getparam {
@@ -1085,7 +1119,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) \
@@ -1421,65 +1464,18 @@ struct drm_i915_gem_wait {
};
struct drm_i915_gem_context_create {
- /* output: id of new context*/
- __u32 ctx_id;
- __u32 pad;
-};
-
-struct drm_i915_gem_context_destroy {
- __u32 ctx_id;
- __u32 pad;
-};
-
-struct drm_i915_reg_read {
- /*
- * Register offset.
- * For 64bit wide registers where the upper 32bits don't immediately
- * follow the lower 32bits, the offset of the lower 32bits must
- * be specified
- */
- __u64 offset;
-#define I915_REG_READ_8B_WA (1ul << 0)
-
- __u64 val; /* Return value */
-};
-/* Known registers:
- *
- * Render engine timestamp - 0x2358 + 64bit - gen7+
- * - Note this register returns an invalid value if using the default
- * single instruction 8byte read, in order to workaround that pass
- * flag I915_REG_READ_8B_WA in offset field.
- *
- */
-
-struct drm_i915_reset_stats {
- __u32 ctx_id;
- __u32 flags;
-
- /* All resets since boot/module reload, for all contexts */
- __u32 reset_count;
-
- /* Number of batches lost when active in GPU, for this context */
- __u32 batch_active;
-
- /* Number of batches lost pending for execution, for this context */
- __u32 batch_pending;
-
+ __u32 ctx_id; /* output: id of new context*/
__u32 pad;
};
-struct drm_i915_gem_userptr {
- __u64 user_ptr;
- __u64 user_size;
+struct drm_i915_gem_context_create_ext {
+ __u32 ctx_id; /* output: id of new context*/
__u32 flags;
-#define I915_USERPTR_READ_ONLY 0x1
-#define I915_USERPTR_UNSYNCHRONIZED 0x80000000
- /**
- * Returned handle for the object.
- *
- * Object handles are nonzero.
- */
- __u32 handle;
+#define I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS (1u << 0)
+#define I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE (1u << 1)
+#define I915_CONTEXT_CREATE_FLAGS_UNKNOWN \
+ (-(I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE << 1))
+ __u64 extensions;
};
struct drm_i915_gem_context_param {
@@ -1520,7 +1516,43 @@ struct drm_i915_gem_context_param {
* On creation, all new contexts are marked as recoverable.
*/
#define I915_CONTEXT_PARAM_RECOVERABLE 0x8
+
+ /*
+ * The id of the associated virtual memory address space (ppGTT) of
+ * this context. Can be retrieved and passed to another context
+ * (on the same fd) for both to use the same ppGTT and so share
+ * address layouts, and avoid reloading the page tables on context
+ * switches between themselves.
+ *
+ * See DRM_I915_GEM_VM_CREATE and DRM_I915_GEM_VM_DESTROY.
+ */
+#define I915_CONTEXT_PARAM_VM 0x9
+
+/*
+ * 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. Slots 0...N are filled in using the specified (class, instance).
+ * Use
+ * engine_class: I915_ENGINE_CLASS_INVALID,
+ * engine_instance: I915_ENGINE_CLASS_INVALID_NONE
+ * to specify a gap in the array that can be filled in later, e.g. by a
+ * virtual engine used for load balancing.
+ *
+ * Setting the number of engines bound to the context to 0, by passing a zero
+ * sized argument, 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 0xa
/* Must be kept compact -- no holes and well documented */
+
__u64 value;
};
@@ -1553,9 +1585,10 @@ struct drm_i915_gem_context_param_sseu {
__u16 engine_instance;
/*
- * Unused for now. Must be cleared to zero.
+ * Unknown flags must be cleared to zero.
*/
__u32 flags;
+#define I915_CONTEXT_SSEU_FLAG_ENGINE_INDEX (1u << 0)
/*
* Mask of slices to enable for the context. Valid values are a subset
@@ -1583,6 +1616,175 @@ struct drm_i915_gem_context_param_sseu {
__u32 rsvd;
};
+/*
+ * i915_context_engines_load_balance:
+ *
+ * Enable load balancing across this set of engines.
+ *
+ * Into the I915_EXEC_DEFAULT slot [0], 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.
+ *
+ * To intermix rendering with the virtual engine and direct rendering onto
+ * the backing engines (bypassing the load balancing proxy), the context must
+ * be defined to use a single timeline for all engines.
+ */
+struct i915_context_engines_load_balance {
+ struct i915_user_extension base;
+
+ __u16 engine_index;
+ __u16 mbz16; /* reserved for future use; must be zero */
+ __u32 flags; /* all undefined flags must be zero */
+
+ __u64 engines_mask; /* selection mask of engines[] */
+
+ __u64 mbz64[4]; /* reserved for future use; must be zero */
+};
+
+/*
+ * i915_context_engines_bond:
+ *
+ */
+struct i915_context_engines_bond {
+ struct i915_user_extension base;
+
+ __u16 engine_index;
+ __u16 mbz;
+
+ __u16 master_class;
+ __u16 master_instance;
+
+ __u64 sibling_mask;
+ __u64 flags; /* all undefined flags must be zero */
+};
+
+struct i915_context_param_engines {
+ __u64 extensions; /* linked chain of extension blocks, 0 terminates */
+#define I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE 0
+#define I915_CONTEXT_ENGINES_EXT_BOND 1
+
+ struct {
+ __u16 engine_class; /* see enum drm_i915_gem_engine_class */
+ __u16 engine_instance;
+ } class_instance[0];
+} __attribute__((packed));
+
+#define I915_DEFINE_CONTEXT_PARAM_ENGINES(name__, N__) struct { \
+ __u64 extensions; \
+ struct { \
+ __u16 engine_class; \
+ __u16 engine_instance; \
+ } class_instance[N__]; \
+} __attribute__((packed)) name__
+
+struct drm_i915_gem_context_create_ext_setparam {
+#define I915_CONTEXT_CREATE_EXT_SETPARAM 0
+ struct i915_user_extension base;
+ struct drm_i915_gem_context_param setparam;
+};
+
+struct drm_i915_gem_context_create_ext_clone {
+#define I915_CONTEXT_CREATE_EXT_CLONE 1
+ struct i915_user_extension base;
+ __u32 clone_id;
+ __u32 flags;
+#define I915_CONTEXT_CLONE_FLAGS (1u << 0)
+#define I915_CONTEXT_CLONE_SCHED (1u << 1)
+#define I915_CONTEXT_CLONE_SSEU (1u << 2)
+#define I915_CONTEXT_CLONE_TIMELINE (1u << 3)
+#define I915_CONTEXT_CLONE_VM (1u << 4)
+#define I915_CONTEXT_CLONE_ENGINES (1u << 5)
+#define I915_CONTEXT_CLONE_UNKNOWN -(I915_CONTEXT_CLONE_ENGINES << 1)
+ __u64 rsvd;
+};
+
+struct drm_i915_gem_context_destroy {
+ __u32 ctx_id;
+ __u32 pad;
+};
+
+/*
+ * DRM_I915_GEM_VM_CREATE -
+ *
+ * Create a new virtual memory address space (ppGTT) for use within a context
+ * on the same file. Extensions can be provided to configure exactly how the
+ * address space is setup upon creation.
+ *
+ * The id of new VM (bound to the fd) for use with I915_CONTEXT_PARAM_VM is
+ * returned in the outparam @id.
+ *
+ * No flags are defined, with all bits reserved and must be zero.
+ *
+ * An extension chain maybe provided, starting with @extensions, and terminated
+ * by the @next_extension being 0. Currently, no extensions are defined.
+ *
+ * DRM_I915_GEM_VM_DESTROY -
+ *
+ * Destroys a previously created VM id, specified in @id.
+ *
+ * No extensions or flags are allowed currently, and so must be zero.
+ */
+struct drm_i915_gem_vm_control {
+ __u64 extensions;
+ __u32 flags;
+ __u32 id;
+};
+
+struct drm_i915_reg_read {
+ /*
+ * Register offset.
+ * For 64bit wide registers where the upper 32bits don't immediately
+ * follow the lower 32bits, the offset of the lower 32bits must
+ * be specified
+ */
+ __u64 offset;
+#define I915_REG_READ_8B_WA (1ul << 0)
+
+ __u64 val; /* Return value */
+};
+
+/* Known registers:
+ *
+ * Render engine timestamp - 0x2358 + 64bit - gen7+
+ * - Note this register returns an invalid value if using the default
+ * single instruction 8byte read, in order to workaround that pass
+ * flag I915_REG_READ_8B_WA in offset field.
+ *
+ */
+
+struct drm_i915_reset_stats {
+ __u32 ctx_id;
+ __u32 flags;
+
+ /* All resets since boot/module reload, for all contexts */
+ __u32 reset_count;
+
+ /* Number of batches lost when active in GPU, for this context */
+ __u32 batch_active;
+
+ /* Number of batches lost pending for execution, for this context */
+ __u32 batch_pending;
+
+ __u32 pad;
+};
+
+struct drm_i915_gem_userptr {
+ __u64 user_ptr;
+ __u64 user_size;
+ __u32 flags;
+#define I915_USERPTR_READ_ONLY 0x1
+#define I915_USERPTR_UNSYNCHRONIZED 0x80000000
+ /**
+ * Returned handle for the object.
+ *
+ * Object handles are nonzero.
+ */
+ __u32 handle;
+};
+
enum drm_i915_oa_format {
I915_OA_FORMAT_A13 = 1, /* HSW only */
I915_OA_FORMAT_A29, /* HSW only */
@@ -1744,6 +1946,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
/* Must be kept compact -- no holes and well documented */
/*
@@ -1842,6 +2045,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 engine_class;
+
+ /** Engine instance number. */
+ __u16 engine_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.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 18+ messages in thread* [igt-dev] [PATCH v17 4/7] lib/i915: add gem_engine_topology library and for_each loop definition
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
` (2 preceding siblings ...)
2019-04-05 1:07 ` [igt-dev] [PATCH v17 3/7] include/drm-uapi: import i915_drm.h header file Andi Shyti
@ 2019-04-05 1:07 ` Andi Shyti
2019-04-05 8:42 ` Tvrtko Ursulin
2019-04-05 1:07 ` [igt-dev] [PATCH v17 5/7] lib: igt_gt: add eb flags to class helper Andi Shyti
` (3 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 1:07 UTC (permalink / raw)
To: IGT dev; +Cc: Andi Shyti
From: Andi Shyti <andi.shyti@intel.com>
The gem_engine_topology library is a set of functions that
interface with the query and getparam/setparam ioctls.
The library's access point is the 'intel_init_engine_list()'
function that, everytime is called, generates the list of active
engines and returns them in a 'struct intel_engine_data'. The
structure contains only the engines that are actively present in
the GPU.
The function can work in both the cases that the query and
getparam ioctls are implemented or not by the running kernel. In
case they are implemented, a query is made to the driver to fetch
the list of active engines. In case they are not implemented, the
list is taken from the 'intel_execution_engines2' array and
stored only after checking their presence.
The gem_engine_topology library provides some iteration helpers:
- intel_get_current_engine(): provides the current engine in the
iteration.
- intel_get_current_physical_engine(): provides the current
physical engine, if the current engine is a virtual engine,
it moves forward until it finds a physical engine.
- intel_next_engine() it just increments the counter so that it
points to the next engine.
Extend the 'for_each_engine_class_instance' so that it can loop
using the new 'intel_init_engine_list()' and rename it to
'for_each_context_engine'.
Move '__for_each_engine_class_instance' to gem_engine_topology.h
and rename it to '__for_each_static_engine'.
Update accordingly tests/perf_pmu.c to use correctly the new
for_each loops.
Signed-off-by: Andi Shyti <andi.shyti@intel.com>
---
lib/Makefile.sources | 2 +
lib/i915/gem_engine_topology.c | 256 +++++++++++++++++++++++++++++++++
lib/i915/gem_engine_topology.h | 66 +++++++++
lib/igt.h | 1 +
lib/igt_gt.h | 2 +
lib/meson.build | 1 +
6 files changed, 328 insertions(+)
create mode 100644 lib/i915/gem_engine_topology.c
create mode 100644 lib/i915/gem_engine_topology.h
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index e00347f945c5..41331c2f2b80 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -13,6 +13,8 @@ lib_source_list = \
i915/gem_ring.c \
i915/gem_mman.c \
i915/gem_mman.h \
+ i915/gem_engine_topology.c \
+ i915/gem_engine_topology.h \
i915_3d.h \
i915_reg.h \
i915_pciids.h \
diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
new file mode 100644
index 000000000000..51ee1c82bd65
--- /dev/null
+++ b/lib/i915/gem_engine_topology.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright © 2019 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 "drmtest.h"
+#include "ioctl_wrappers.h"
+
+#include "i915/gem_engine_topology.h"
+
+/*
+ * Limit what we support for simplicity due limitation in how much we
+ * can address via execbuf2.
+ */
+#define SIZEOF_CTX_PARAM offsetof(struct i915_context_param_engines, \
+ class_instance[GEM_MAX_ENGINES])
+#define SIZEOF_QUERY offsetof(struct drm_i915_query_engine_info, \
+ engines[GEM_MAX_ENGINES])
+
+static int __gem_query(int fd, struct drm_i915_query *q)
+{
+ int err = 0;
+
+ if (igt_ioctl(fd, DRM_IOCTL_I915_QUERY, q))
+ err = -errno;
+
+ errno = 0;
+ return err;
+}
+
+static void gem_query(int fd, struct drm_i915_query *q)
+{
+ igt_assert_eq(__gem_query(fd, q), 0);
+}
+
+static void query_engines(int fd,
+ struct drm_i915_query_engine_info *query_engines,
+ int length)
+{
+ struct drm_i915_query_item item = { };
+ struct drm_i915_query query = { };
+
+ item.query_id = DRM_I915_QUERY_ENGINE_INFO;
+ query.items_ptr = to_user_pointer(&item);
+ query.num_items = 1;
+ item.length = length;
+
+ item.data_ptr = to_user_pointer(query_engines);
+
+ gem_query(fd, &query);
+}
+
+static void ctx_map_engines(int fd, struct intel_engine_data *ed,
+ struct drm_i915_gem_context_param *param)
+{
+ struct i915_context_param_engines *engines =
+ (struct i915_context_param_engines*) param->value;
+ int i = 0;
+
+ for (typeof(engines->class_instance[0]) *p =
+ &engines->class_instance[0];
+ i < ed->nengines; i++, p++) {
+ p->engine_class = ed->engines[i].class;
+ p->engine_instance = ed->engines[i].instance;
+ }
+
+ param->size = offsetof(typeof(*engines), class_instance[i]);
+ engines->extensions = 0;
+
+ gem_context_set_param(fd, param);
+}
+
+static void init_engine(struct intel_execution_engine2 *e2,
+ int class, int instance, uint64_t flags)
+{
+ const struct intel_execution_engine2 *__e2;
+ static const char *unknown_name = "unknown",
+ *virtual_name = "virtual";
+
+ e2->class = class;
+ e2->instance = instance;
+ e2->flags = flags;
+
+ /* engine is a virtual engine */
+ if (class == I915_ENGINE_CLASS_INVALID) {
+ e2->name = virtual_name;
+ e2->is_virtual = true;
+ return;
+ }
+
+ __for_each_static_engine(__e2)
+ if (__e2->class == class && __e2->instance == instance)
+ break;
+
+ if (__e2->name) {
+ e2->name = __e2->name;
+ } else {
+ igt_warn("found unknown engine (%d, %d)", class, instance);
+ e2->name = unknown_name;
+ }
+
+ /* just to remark it */
+ e2->is_virtual = false;
+}
+
+static void query_engine_list(int fd, struct intel_engine_data *ed)
+{
+ uint8_t buff[SIZEOF_QUERY] = { };
+ struct drm_i915_query_engine_info *query_engine =
+ (struct drm_i915_query_engine_info *) buff;
+ int i;
+
+ query_engines(fd, query_engine, SIZEOF_QUERY);
+
+ for (i = 0; i < query_engine->num_engines; i++)
+ init_engine(&ed->engines[i],
+ query_engine->engines[i].engine_class,
+ query_engine->engines[i].engine_instance, i);
+
+ ed->nengines = query_engine->num_engines;
+}
+
+struct intel_execution_engine2
+*intel_get_current_engine(struct intel_engine_data *ed)
+{
+ if (!ed->n)
+ ed->current_engine = &ed->engines[0];
+ else if (ed->n >= ed->nengines)
+ ed->current_engine = NULL;
+
+ return ed->current_engine;
+}
+
+void intel_next_engine(struct intel_engine_data *ed)
+{
+ if (ed->n + 1 < ed->nengines) {
+ ed->n++;
+ ed->current_engine = &ed->engines[ed->n];
+ } else {
+ ed->current_engine = NULL;
+ }
+}
+
+struct intel_execution_engine2
+*intel_get_current_physical_engine(struct intel_engine_data *ed)
+{
+ struct intel_execution_engine2 *e;
+
+ if (ed->n >= ed->nengines)
+ return NULL;
+
+ if (igt_only_list_subtests())
+ intel_next_engine(ed);
+ else
+ for (e = intel_get_current_engine(ed);
+ e && e->is_virtual;
+ intel_next_engine(ed))
+ ;
+
+ return e;
+}
+
+struct intel_engine_data intel_init_engine_list(int fd, uint32_t ctx_id)
+{
+ I915_DEFINE_CONTEXT_PARAM_ENGINES(engines, GEM_MAX_ENGINES);
+ struct intel_engine_data engine_data = { };
+ struct drm_i915_gem_context_param param = {
+ .param = I915_CONTEXT_PARAM_ENGINES,
+ .ctx_id = ctx_id,
+ .size = SIZEOF_CTX_PARAM,
+ .value = to_user_pointer(&engines),
+ };
+ int i;
+ unsigned int nengines;
+
+ if (igt_only_list_subtests() || __gem_context_get_param(fd, ¶m)) {
+ /* if kernel does not support engine/context mapping */
+ const struct intel_execution_engine2 *e2;
+
+ igt_debug("using pre-allocated engine list\n");
+
+ __for_each_static_engine(e2) {
+ struct intel_execution_engine2 *__e2 =
+ &engine_data.engines[engine_data.nengines];
+
+ if (!igt_only_list_subtests()) {
+ __e2->flags = gem_class_instance_to_eb_flags(fd,
+ e2->class, e2->instance);
+
+ if (!gem_has_ring(fd, __e2->flags))
+ continue;
+ }
+
+ __e2->name = e2->name;
+ __e2->instance = e2->instance;
+ __e2->class = e2->class;
+ __e2->is_virtual = false;
+
+ engine_data.nengines++;
+ }
+ return engine_data;
+ }
+
+ nengines = param.size > sizeof(struct i915_context_param_engines) ?
+ (param.size - sizeof(struct i915_context_param_engines)) /
+ sizeof(engines.class_instance[0]) :
+ 0;
+
+ igt_assert_f(nengines <= GEM_MAX_ENGINES, "unsupported engine count\n");
+
+ if (!param.size) {
+ /* else if context doesn't have mapped engines */
+ query_engine_list(fd, &engine_data);
+ ctx_map_engines(fd, &engine_data, ¶m);
+
+ } else {
+ /* context has a list of mapped engines */
+
+ for (i = 0; i < nengines; i++)
+ init_engine(&engine_data.engines[i],
+ engines.class_instance[i].engine_class,
+ engines.class_instance[i].engine_instance,
+ i);
+
+ engine_data.nengines = i;
+ }
+
+ return engine_data;
+}
+
+bool gem_has_engine_topology(int fd)
+{
+ struct drm_i915_gem_context_param param = {
+ .param = I915_CONTEXT_PARAM_ENGINES,
+ };
+
+ return !__gem_context_get_param(fd, ¶m);
+}
diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
new file mode 100644
index 000000000000..b0285b80f673
--- /dev/null
+++ b/lib/i915/gem_engine_topology.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2019 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.
+ */
+
+#ifndef GEM_ENGINE_TOPOLOGY_H
+#define GEM_ENGINE_TOPOLOGY_H
+
+#include "igt_gt.h"
+#include "i915_drm.h"
+
+#define GEM_MAX_ENGINES I915_EXEC_RING_MASK + 1
+
+struct intel_engine_data {
+ uint32_t nengines;
+ uint32_t n;
+ int error;
+ struct intel_execution_engine2 *current_engine;
+ struct intel_execution_engine2 engines[GEM_MAX_ENGINES];
+};
+
+bool gem_has_engine_topology(int fd);
+struct intel_engine_data intel_init_engine_list(int fd, uint32_t ctx_id);
+
+/* iteration functions */
+struct intel_execution_engine2
+*intel_get_current_engine(struct intel_engine_data *ed);
+
+struct intel_execution_engine2
+*intel_get_current_physical_engine(struct intel_engine_data *ed);
+
+void intel_next_engine(struct intel_engine_data *ed);
+
+#define __for_each_static_engine(e__) \
+ for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
+
+#define for_each_context_engine(fd__, ctx__, e__) \
+ for (struct intel_engine_data i__ = intel_init_engine_list(fd__, ctx__); \
+ ((e__) = intel_get_current_engine(&i__)); \
+ intel_next_engine(&i__))
+
+/* needs to replace "for_each_physical_engine" when conflicts are fixed */
+#define __for_each_physical_engine(fd__, e__) \
+ for (struct intel_engine_data i__ = intel_init_engine_list(fd__, 0); \
+ ((e__) = intel_get_current_physical_engine(&i__)); \
+ intel_next_engine(&i__))
+
+#endif /* GEM_ENGINE_TOPOLOGY_H */
diff --git a/lib/igt.h b/lib/igt.h
index 6654a659c062..03f19ca2dfb6 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -53,5 +53,6 @@
#include "media_spin.h"
#include "rendercopy.h"
#include "i915/gem_mman.h"
+#include "i915/gem_engine_topology.h"
#endif /* IGT_H */
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index 475c0b3c3cc6..52b2f1ea95a5 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -95,6 +95,8 @@ extern const struct intel_execution_engine2 {
const char *name;
int class;
int instance;
+ uint64_t flags;
+ bool is_virtual;
} intel_execution_engines2[];
unsigned int
diff --git a/lib/meson.build b/lib/meson.build
index 89de06e6924a..93c01daa4222 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -5,6 +5,7 @@ lib_sources = [
'i915/gem_submission.c',
'i915/gem_ring.c',
'i915/gem_mman.c',
+ 'i915/gem_engine_topology.c',
'igt_color_encoding.c',
'igt_debugfs.c',
'igt_device.c',
--
2.20.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 4/7] lib/i915: add gem_engine_topology library and for_each loop definition
2019-04-05 1:07 ` [igt-dev] [PATCH v17 4/7] lib/i915: add gem_engine_topology library and for_each loop definition Andi Shyti
@ 2019-04-05 8:42 ` Tvrtko Ursulin
2019-04-05 9:00 ` Andi Shyti
0 siblings, 1 reply; 18+ messages in thread
From: Tvrtko Ursulin @ 2019-04-05 8:42 UTC (permalink / raw)
To: Andi Shyti, IGT dev
On 05/04/2019 02:07, Andi Shyti wrote:
> From: Andi Shyti <andi.shyti@intel.com>
>
> The gem_engine_topology library is a set of functions that
> interface with the query and getparam/setparam ioctls.
>
> The library's access point is the 'intel_init_engine_list()'
> function that, everytime is called, generates the list of active
> engines and returns them in a 'struct intel_engine_data'. The
> structure contains only the engines that are actively present in
> the GPU.
>
> The function can work in both the cases that the query and
> getparam ioctls are implemented or not by the running kernel. In
> case they are implemented, a query is made to the driver to fetch
> the list of active engines. In case they are not implemented, the
> list is taken from the 'intel_execution_engines2' array and
> stored only after checking their presence.
>
> The gem_engine_topology library provides some iteration helpers:
>
> - intel_get_current_engine(): provides the current engine in the
> iteration.
>
> - intel_get_current_physical_engine(): provides the current
> physical engine, if the current engine is a virtual engine,
> it moves forward until it finds a physical engine.
>
> - intel_next_engine() it just increments the counter so that it
> points to the next engine.
>
> Extend the 'for_each_engine_class_instance' so that it can loop
> using the new 'intel_init_engine_list()' and rename it to
> 'for_each_context_engine'.
>
> Move '__for_each_engine_class_instance' to gem_engine_topology.h
> and rename it to '__for_each_static_engine'.
>
> Update accordingly tests/perf_pmu.c to use correctly the new
> for_each loops.
>
> Signed-off-by: Andi Shyti <andi.shyti@intel.com>
> ---
> lib/Makefile.sources | 2 +
> lib/i915/gem_engine_topology.c | 256 +++++++++++++++++++++++++++++++++
> lib/i915/gem_engine_topology.h | 66 +++++++++
> lib/igt.h | 1 +
> lib/igt_gt.h | 2 +
> lib/meson.build | 1 +
> 6 files changed, 328 insertions(+)
> create mode 100644 lib/i915/gem_engine_topology.c
> create mode 100644 lib/i915/gem_engine_topology.h
>
> diff --git a/lib/Makefile.sources b/lib/Makefile.sources
> index e00347f945c5..41331c2f2b80 100644
> --- a/lib/Makefile.sources
> +++ b/lib/Makefile.sources
> @@ -13,6 +13,8 @@ lib_source_list = \
> i915/gem_ring.c \
> i915/gem_mman.c \
> i915/gem_mman.h \
> + i915/gem_engine_topology.c \
> + i915/gem_engine_topology.h \
> i915_3d.h \
> i915_reg.h \
> i915_pciids.h \
> diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
> new file mode 100644
> index 000000000000..51ee1c82bd65
> --- /dev/null
> +++ b/lib/i915/gem_engine_topology.c
> @@ -0,0 +1,256 @@
> +/*
> + * Copyright © 2019 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 "drmtest.h"
> +#include "ioctl_wrappers.h"
> +
> +#include "i915/gem_engine_topology.h"
> +
> +/*
> + * Limit what we support for simplicity due limitation in how much we
> + * can address via execbuf2.
> + */
> +#define SIZEOF_CTX_PARAM offsetof(struct i915_context_param_engines, \
> + class_instance[GEM_MAX_ENGINES])
> +#define SIZEOF_QUERY offsetof(struct drm_i915_query_engine_info, \
> + engines[GEM_MAX_ENGINES])
> +
> +static int __gem_query(int fd, struct drm_i915_query *q)
> +{
> + int err = 0;
> +
> + if (igt_ioctl(fd, DRM_IOCTL_I915_QUERY, q))
> + err = -errno;
> +
> + errno = 0;
> + return err;
> +}
> +
> +static void gem_query(int fd, struct drm_i915_query *q)
> +{
> + igt_assert_eq(__gem_query(fd, q), 0);
> +}
> +
> +static void query_engines(int fd,
> + struct drm_i915_query_engine_info *query_engines,
> + int length)
> +{
> + struct drm_i915_query_item item = { };
> + struct drm_i915_query query = { };
> +
> + item.query_id = DRM_I915_QUERY_ENGINE_INFO;
> + query.items_ptr = to_user_pointer(&item);
> + query.num_items = 1;
> + item.length = length;
> +
> + item.data_ptr = to_user_pointer(query_engines);
> +
> + gem_query(fd, &query);
> +}
> +
> +static void ctx_map_engines(int fd, struct intel_engine_data *ed,
> + struct drm_i915_gem_context_param *param)
> +{
> + struct i915_context_param_engines *engines =
> + (struct i915_context_param_engines*) param->value;
Cosmetics only: Our coding style is "(type *)var".
> + int i = 0;
> +
> + for (typeof(engines->class_instance[0]) *p =
> + &engines->class_instance[0];
> + i < ed->nengines; i++, p++)
More cosmetics: Indentation alignment looks wonky.
{
> + p->engine_class = ed->engines[i].class;
> + p->engine_instance = ed->engines[i].instance;
> + }
> +
> + param->size = offsetof(typeof(*engines), class_instance[i]);
> + engines->extensions = 0;
> +
> + gem_context_set_param(fd, param);
> +}
> +
> +static void init_engine(struct intel_execution_engine2 *e2,
> + int class, int instance, uint64_t flags)
> +{
> + const struct intel_execution_engine2 *__e2;
> + static const char *unknown_name = "unknown",
> + *virtual_name = "virtual";
> +
> + e2->class = class;
> + e2->instance = instance;
> + e2->flags = flags;
> +
> + /* engine is a virtual engine */
> + if (class == I915_ENGINE_CLASS_INVALID) {
> + e2->name = virtual_name;
> + e2->is_virtual = true;
> + return;
> + }
> +
> + __for_each_static_engine(__e2)
> + if (__e2->class == class && __e2->instance == instance)
> + break;
> +
> + if (__e2->name) {
> + e2->name = __e2->name;
> + } else {
> + igt_warn("found unknown engine (%d, %d)", class, instance);
> + e2->name = unknown_name;
> + }
> +
> + /* just to remark it */
> + e2->is_virtual = false;
> +}
> +
> +static void query_engine_list(int fd, struct intel_engine_data *ed)
> +{
> + uint8_t buff[SIZEOF_QUERY] = { };
> + struct drm_i915_query_engine_info *query_engine =
> + (struct drm_i915_query_engine_info *) buff;
> + int i;
> +
> + query_engines(fd, query_engine, SIZEOF_QUERY);
> +
> + for (i = 0; i < query_engine->num_engines; i++)
> + init_engine(&ed->engines[i],
> + query_engine->engines[i].engine_class,
> + query_engine->engines[i].engine_instance, i);
> +
> + ed->nengines = query_engine->num_engines;
> +}
> +
> +struct intel_execution_engine2
> +*intel_get_current_engine(struct intel_engine_data *ed)
> +{
> + if (!ed->n)
> + ed->current_engine = &ed->engines[0];
> + else if (ed->n >= ed->nengines)
> + ed->current_engine = NULL;
> +
> + return ed->current_engine;
> +}
> +
Why can this just return ed->current_engine? I am confused by the need
to check against ed->nengines both in the getter and in the next helper.
Just need to init ed->current_engine to the first one in
init_engine_list I think.
> +void intel_next_engine(struct intel_engine_data *ed)
> +{
> + if (ed->n + 1 < ed->nengines) {
> + ed->n++;
> + ed->current_engine = &ed->engines[ed->n];
> + } else {
> + ed->current_engine = NULL;
> + }
> +}
> +
> +struct intel_execution_engine2
> +*intel_get_current_physical_engine(struct intel_engine_data *ed)
> +{
> + struct intel_execution_engine2 *e;
> +
> + if (ed->n >= ed->nengines)
> + return NULL;
Can this be hit? intel_next_engine looks to be avoiding incrementing
past nengines - 1.
> +
> + if (igt_only_list_subtests())
> + intel_next_engine(ed);
In subtest listing mode there cannot be virtual engines in the list so I
think this branch is not needed.
> + else
> + for (e = intel_get_current_engine(ed);
> + e && e->is_virtual;
> + intel_next_engine(ed))
> + ;
> +
> + return e;
> +}
> +
> +struct intel_engine_data intel_init_engine_list(int fd, uint32_t ctx_id)
> +{
> + I915_DEFINE_CONTEXT_PARAM_ENGINES(engines, GEM_MAX_ENGINES);
> + struct intel_engine_data engine_data = { };
> + struct drm_i915_gem_context_param param = {
> + .param = I915_CONTEXT_PARAM_ENGINES,
> + .ctx_id = ctx_id,
> + .size = SIZEOF_CTX_PARAM,
> + .value = to_user_pointer(&engines),
> + };
> + int i;
> + unsigned int nengines;
> +
> + if (igt_only_list_subtests() || __gem_context_get_param(fd, ¶m)) {
> + /* if kernel does not support engine/context mapping */
> + const struct intel_execution_engine2 *e2;
> +
> + igt_debug("using pre-allocated engine list\n");
> +
> + __for_each_static_engine(e2) {
> + struct intel_execution_engine2 *__e2 =
> + &engine_data.engines[engine_data.nengines];
> +
> + if (!igt_only_list_subtests()) {
> + __e2->flags = gem_class_instance_to_eb_flags(fd,
> + e2->class, e2->instance);
> +
> + if (!gem_has_ring(fd, __e2->flags))
> + continue;
> + }
> +
> + __e2->name = e2->name;
> + __e2->instance = e2->instance;
> + __e2->class = e2->class;
> + __e2->is_virtual = false;
You could use init_engine here but granted it would have to do a
redundant name search so maybe not.
> +
> + engine_data.nengines++;
> + }
> + return engine_data;
> + }
> +
> + nengines = param.size > sizeof(struct i915_context_param_engines) ?
> + (param.size - sizeof(struct i915_context_param_engines)) /
> + sizeof(engines.class_instance[0]) :
> + 0;
> +
> + igt_assert_f(nengines <= GEM_MAX_ENGINES, "unsupported engine count\n");
> +
> + if (!param.size) {
> + /* else if context doesn't have mapped engines */
> + query_engine_list(fd, &engine_data);
> + ctx_map_engines(fd, &engine_data, ¶m);
> +
> + } else {
> + /* context has a list of mapped engines */
> +
> + for (i = 0; i < nengines; i++)
> + init_engine(&engine_data.engines[i],
> + engines.class_instance[i].engine_class,
> + engines.class_instance[i].engine_instance,
> + i);
> +
> + engine_data.nengines = i;
> + }
> +
> + return engine_data;
> +}
> +
> +bool gem_has_engine_topology(int fd)
> +{
> + struct drm_i915_gem_context_param param = {
> + .param = I915_CONTEXT_PARAM_ENGINES,
> + };
> +
> + return !__gem_context_get_param(fd, ¶m);
> +}
> diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
> new file mode 100644
> index 000000000000..b0285b80f673
> --- /dev/null
> +++ b/lib/i915/gem_engine_topology.h
> @@ -0,0 +1,66 @@
> +/*
> + * Copyright © 2019 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.
> + */
> +
> +#ifndef GEM_ENGINE_TOPOLOGY_H
> +#define GEM_ENGINE_TOPOLOGY_H
> +
> +#include "igt_gt.h"
> +#include "i915_drm.h"
> +
> +#define GEM_MAX_ENGINES I915_EXEC_RING_MASK + 1
> +
> +struct intel_engine_data {
> + uint32_t nengines;
> + uint32_t n;
> + int error;
> + struct intel_execution_engine2 *current_engine;
> + struct intel_execution_engine2 engines[GEM_MAX_ENGINES];
> +};
> +
> +bool gem_has_engine_topology(int fd);
> +struct intel_engine_data intel_init_engine_list(int fd, uint32_t ctx_id);
> +
> +/* iteration functions */
> +struct intel_execution_engine2
> +*intel_get_current_engine(struct intel_engine_data *ed);
> +
> +struct intel_execution_engine2
> +*intel_get_current_physical_engine(struct intel_engine_data *ed);
> +
> +void intel_next_engine(struct intel_engine_data *ed);
> +
> +#define __for_each_static_engine(e__) \
> + for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
> +
> +#define for_each_context_engine(fd__, ctx__, e__) \
> + for (struct intel_engine_data i__ = intel_init_engine_list(fd__, ctx__); \
> + ((e__) = intel_get_current_engine(&i__)); \
> + intel_next_engine(&i__))
> +
> +/* needs to replace "for_each_physical_engine" when conflicts are fixed */
> +#define __for_each_physical_engine(fd__, e__) \
> + for (struct intel_engine_data i__ = intel_init_engine_list(fd__, 0); \
> + ((e__) = intel_get_current_physical_engine(&i__)); \
> + intel_next_engine(&i__))
> +
> +#endif /* GEM_ENGINE_TOPOLOGY_H */
> diff --git a/lib/igt.h b/lib/igt.h
> index 6654a659c062..03f19ca2dfb6 100644
> --- a/lib/igt.h
> +++ b/lib/igt.h
> @@ -53,5 +53,6 @@
> #include "media_spin.h"
> #include "rendercopy.h"
> #include "i915/gem_mman.h"
> +#include "i915/gem_engine_topology.h"
>
> #endif /* IGT_H */
> diff --git a/lib/igt_gt.h b/lib/igt_gt.h
> index 475c0b3c3cc6..52b2f1ea95a5 100644
> --- a/lib/igt_gt.h
> +++ b/lib/igt_gt.h
> @@ -95,6 +95,8 @@ extern const struct intel_execution_engine2 {
> const char *name;
> int class;
> int instance;
> + uint64_t flags;
> + bool is_virtual;
> } intel_execution_engines2[];
>
> unsigned int
> diff --git a/lib/meson.build b/lib/meson.build
> index 89de06e6924a..93c01daa4222 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -5,6 +5,7 @@ lib_sources = [
> 'i915/gem_submission.c',
> 'i915/gem_ring.c',
> 'i915/gem_mman.c',
> + 'i915/gem_engine_topology.c',
> 'igt_color_encoding.c',
> 'igt_debugfs.c',
> 'igt_device.c',
>
Regards,
Tvrtko
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 4/7] lib/i915: add gem_engine_topology library and for_each loop definition
2019-04-05 8:42 ` Tvrtko Ursulin
@ 2019-04-05 9:00 ` Andi Shyti
2019-04-05 9:16 ` Tvrtko Ursulin
0 siblings, 1 reply; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 9:00 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: IGT dev, Andi Shyti
Hi Tvrtko,
> > + struct i915_context_param_engines *engines =
> > + (struct i915_context_param_engines*) param->value;
>
> Cosmetics only: Our coding style is "(type *)var".
>
> > + for (typeof(engines->class_instance[0]) *p =
> > + &engines->class_instance[0];
> > + i < ed->nengines; i++, p++)
>
> More cosmetics: Indentation alignment looks wonky.
working at the edge of the 80 characters provides always
cosmetic challenges, I'll fix the above.
> > +struct intel_execution_engine2
> > +*intel_get_current_engine(struct intel_engine_data *ed)
> > +{
> > + if (!ed->n)
> > + ed->current_engine = &ed->engines[0];
> > + else if (ed->n >= ed->nengines)
> > + ed->current_engine = NULL;
> > +
> > + return ed->current_engine;
> > +}
> > +
>
> Why can this just return ed->current_engine? I am confused by the need to
> check against ed->nengines both in the getter and in the next helper. Just
> need to init ed->current_engine to the first one in init_engine_list I
> think.
In the previous patch there was an unrefined mistake:
ed->current_engine was initialized in the
'intel_init_engine_list()' function.
But because there everything is allocated in stack, the
'&ed->engines[0]' is also in stack that get freed when the
function returns, with the result that I lose reference.
For this, I would need the pointer to be assigned somewhere that
works with the addresses provided by the caller and this looks
like the best place for it (indeed I removed the assignement from
intel_init_engine_list()).
> > +struct intel_execution_engine2
> > +*intel_get_current_physical_engine(struct intel_engine_data *ed)
> > +{
> > + struct intel_execution_engine2 *e;
> > +
> > + if (ed->n >= ed->nengines)
> > + return NULL;
>
> Can this be hit? intel_next_engine looks to be avoiding incrementing past
> nengines - 1.
yes, you're right, I didn't want to hit the for loop for this
case that can be checked here, it's redundant, but it looks more
readable. I'll remove it.
> > +
> > + if (igt_only_list_subtests())
> > + intel_next_engine(ed);
>
> In subtest listing mode there cannot be virtual engines in the list so I
> think this branch is not needed.
Yes, indeed, if we have the list of engines at this point, it's
only physical. I'll remove it.
> > + __e2->name = e2->name;
> > + __e2->instance = e2->instance;
> > + __e2->class = e2->class;
> > + __e2->is_virtual = false;
>
> You could use init_engine here but granted it would have to do a redundant
> name search so maybe not.
yes, this is how it is was done at first, I put it outside for
the reason you mentioned :)
Thanks,
Andi
> Regards,
>
> Tvrtko
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 4/7] lib/i915: add gem_engine_topology library and for_each loop definition
2019-04-05 9:00 ` Andi Shyti
@ 2019-04-05 9:16 ` Tvrtko Ursulin
0 siblings, 0 replies; 18+ messages in thread
From: Tvrtko Ursulin @ 2019-04-05 9:16 UTC (permalink / raw)
To: Andi Shyti; +Cc: IGT dev
On 05/04/2019 10:00, Andi Shyti wrote:
> Hi Tvrtko,
>
>>> + struct i915_context_param_engines *engines =
>>> + (struct i915_context_param_engines*) param->value;
>>
>> Cosmetics only: Our coding style is "(type *)var".
>>
>>> + for (typeof(engines->class_instance[0]) *p =
>>> + &engines->class_instance[0];
>>> + i < ed->nengines; i++, p++)
>>
>> More cosmetics: Indentation alignment looks wonky.
>
> working at the edge of the 80 characters provides always
> cosmetic challenges, I'll fix the above.
>
>>> +struct intel_execution_engine2
>>> +*intel_get_current_engine(struct intel_engine_data *ed)
>>> +{
>>> + if (!ed->n)
>>> + ed->current_engine = &ed->engines[0];
>>> + else if (ed->n >= ed->nengines)
>>> + ed->current_engine = NULL;
>>> +
>>> + return ed->current_engine;
>>> +}
>>> +
>>
>> Why can this just return ed->current_engine? I am confused by the need to
>> check against ed->nengines both in the getter and in the next helper. Just
>> need to init ed->current_engine to the first one in init_engine_list I
>> think.
>
> In the previous patch there was an unrefined mistake:
> ed->current_engine was initialized in the
> 'intel_init_engine_list()' function.
>
> But because there everything is allocated in stack, the
> '&ed->engines[0]' is also in stack that get freed when the
> function returns, with the result that I lose reference.
>
> For this, I would need the pointer to be assigned somewhere that
> works with the addresses provided by the caller and this looks
> like the best place for it (indeed I removed the assignement from
> intel_init_engine_list()).
You are right, yep.
>
>>> +struct intel_execution_engine2
>>> +*intel_get_current_physical_engine(struct intel_engine_data *ed)
>>> +{
>>> + struct intel_execution_engine2 *e;
>>> +
>>> + if (ed->n >= ed->nengines)
>>> + return NULL;
>>
>> Can this be hit? intel_next_engine looks to be avoiding incrementing past
>> nengines - 1.
>
> yes, you're right, I didn't want to hit the for loop for this
> case that can be checked here, it's redundant, but it looks more
> readable. I'll remove it.
>
>>> +
>>> + if (igt_only_list_subtests())
>>> + intel_next_engine(ed);
>>
>> In subtest listing mode there cannot be virtual engines in the list so I
>> think this branch is not needed.
>
> Yes, indeed, if we have the list of engines at this point, it's
> only physical. I'll remove it.
>
>>> + __e2->name = e2->name;
>>> + __e2->instance = e2->instance;
>>> + __e2->class = e2->class;
>>> + __e2->is_virtual = false;
>>
>> You could use init_engine here but granted it would have to do a redundant
>> name search so maybe not.
>
> yes, this is how it is was done at first, I put it outside for
> the reason you mentioned :)
That's fine. Okay then, just one or two details to update.
Regards,
Tvrtko
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread
* [igt-dev] [PATCH v17 5/7] lib: igt_gt: add eb flags to class helper
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
` (3 preceding siblings ...)
2019-04-05 1:07 ` [igt-dev] [PATCH v17 4/7] lib/i915: add gem_engine_topology library and for_each loop definition Andi Shyti
@ 2019-04-05 1:07 ` Andi Shyti
2019-04-05 1:07 ` [igt-dev] [PATCH v17 6/7] lib: igt_gt: make gem_engine_can_store_dword() check engine class Andi Shyti
` (2 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 1:07 UTC (permalink / raw)
To: IGT dev; +Cc: Andi Shyti
From: Andi Shyti <andi.shyti@intel.com>
we have a "class/instance to eb flags" helper but not the
opposite, add it.
Signed-off-by: Andi Shyti <andi.shyti@intel.com>
---
lib/igt_gt.c | 16 ++++++++++++++++
lib/igt_gt.h | 2 ++
2 files changed, 18 insertions(+)
diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 5999524326d0..37a010a05ecd 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -586,6 +586,22 @@ const struct intel_execution_engine2 intel_execution_engines2[] = {
{ }
};
+int gem_eb_to_class(unsigned int flags)
+{
+ switch (flags & 0x3f) {
+ case I915_EXEC_RENDER:
+ return I915_ENGINE_CLASS_RENDER;
+ case I915_EXEC_BLT:
+ return I915_ENGINE_CLASS_COPY;
+ case I915_EXEC_BSD:
+ return I915_ENGINE_CLASS_VIDEO;
+ case I915_EXEC_VEBOX:
+ return I915_ENGINE_CLASS_VIDEO_ENHANCE;
+ default:
+ igt_assert(0);
+ }
+}
+
unsigned int
gem_class_instance_to_eb_flags(int gem_fd,
enum drm_i915_gem_engine_class class,
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index 52b2f1ea95a5..b13062ef7d33 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -99,6 +99,8 @@ extern const struct intel_execution_engine2 {
bool is_virtual;
} intel_execution_engines2[];
+int gem_eb_to_class(unsigned int flags);
+
unsigned int
gem_class_instance_to_eb_flags(int gem_fd,
enum drm_i915_gem_engine_class class,
--
2.20.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 18+ messages in thread* [igt-dev] [PATCH v17 6/7] lib: igt_gt: make gem_engine_can_store_dword() check engine class
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
` (4 preceding siblings ...)
2019-04-05 1:07 ` [igt-dev] [PATCH v17 5/7] lib: igt_gt: add eb flags to class helper Andi Shyti
@ 2019-04-05 1:07 ` Andi Shyti
2019-04-05 1:07 ` [igt-dev] [PATCH v17 7/7] test: perf_pmu: use the gem_engine_topology library Andi Shyti
2019-04-05 2:06 ` [igt-dev] ✗ Fi.CI.BAT: failure for series starting with [v17,1/7] lib/igt_gt: remove unnecessary argument Patchwork
7 siblings, 0 replies; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 1:07 UTC (permalink / raw)
To: IGT dev; +Cc: Andi Shyti
From: Andi Shyti <andi.shyti@intel.com>
Engines referred by class and instance are getting more populare,
gem_engine_can_store_dword() should handle the situation.
Signed-off-by: Andi Shyti <andi.shyti@intel.com>
---
lib/igt_gt.c | 11 ++++++++---
lib/igt_gt.h | 1 +
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 37a010a05ecd..e4d77285dc77 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -556,7 +556,7 @@ const struct intel_execution_engine intel_execution_engines[] = {
{ NULL, 0, 0 }
};
-bool gem_can_store_dword(int fd, unsigned int engine)
+bool gem_class_can_store_dword(int fd, int class)
{
uint16_t devid = intel_get_drm_devid(fd);
const struct intel_device_info *info = intel_get_device_info(devid);
@@ -568,8 +568,8 @@ bool gem_can_store_dword(int fd, unsigned int engine)
if (gen == 3 && (info->is_grantsdale || info->is_alviso))
return false; /* only supports physical addresses */
- if (gen == 6 && ((engine & 0x3f) == I915_EXEC_BSD))
- return false; /* kills the machine! */
+ if (gen == 6 && class == I915_ENGINE_CLASS_VIDEO)
+ return false;
if (info->is_broadwater)
return false; /* Not sure yet... */
@@ -577,6 +577,11 @@ bool gem_can_store_dword(int fd, unsigned int engine)
return true;
}
+bool gem_can_store_dword(int fd, unsigned int engine)
+{
+ return gem_class_can_store_dword(fd, gem_eb_to_class(engine));
+}
+
const struct intel_execution_engine2 intel_execution_engines2[] = {
{ "rcs0", I915_ENGINE_CLASS_RENDER, 0 },
{ "bcs0", I915_ENGINE_CLASS_COPY, 0 },
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index b13062ef7d33..af4cc38a1ef7 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -90,6 +90,7 @@ bool gem_ring_is_physical_engine(int fd, unsigned int ring);
bool gem_ring_has_physical_engine(int fd, unsigned int ring);
bool gem_can_store_dword(int fd, unsigned int engine);
+bool gem_class_can_store_dword(int fd, int class);
extern const struct intel_execution_engine2 {
const char *name;
--
2.20.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 18+ messages in thread* [igt-dev] [PATCH v17 7/7] test: perf_pmu: use the gem_engine_topology library
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
` (5 preceding siblings ...)
2019-04-05 1:07 ` [igt-dev] [PATCH v17 6/7] lib: igt_gt: make gem_engine_can_store_dword() check engine class Andi Shyti
@ 2019-04-05 1:07 ` Andi Shyti
2019-04-05 8:50 ` Tvrtko Ursulin
2019-04-05 2:06 ` [igt-dev] ✗ Fi.CI.BAT: failure for series starting with [v17,1/7] lib/igt_gt: remove unnecessary argument Patchwork
7 siblings, 1 reply; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 1:07 UTC (permalink / raw)
To: IGT dev; +Cc: Andi Shyti
From: Andi Shyti <andi.shyti@intel.com>
Replace the legacy for_each_engine* defines with the ones
implemented in the gem_engine_topology library.
Use whenever possible gem_engine_can_store_dword() that checks
class instead of flags.
Now the __for_each_engine_class_instance and
for_each_engine_class_instance are unused, remove them.
Signed-off-by: Andi Shyti <andi.shyti@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
---
lib/igt_gt.h | 7 -------
tests/perf_pmu.c | 53 ++++++++++++++++++++++--------------------------
2 files changed, 24 insertions(+), 36 deletions(-)
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index af4cc38a1ef7..c2ca07e03738 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -119,11 +119,4 @@ void gem_require_engine(int gem_fd,
igt_require(gem_has_engine(gem_fd, class, instance));
}
-#define __for_each_engine_class_instance(e__) \
- for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
-
-#define for_each_engine_class_instance(fd__, e__) \
- for ((e__) = intel_execution_engines2; (e__)->name; (e__)++) \
- for_if (gem_has_engine((fd__), (e__)->class, (e__)->instance))
-
#endif /* IGT_GT_H */
diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
index 4f552bc2ae28..c954a0d54b72 100644
--- a/tests/perf_pmu.c
+++ b/tests/perf_pmu.c
@@ -158,11 +158,6 @@ static unsigned int measured_usleep(unsigned int usec)
return igt_nsec_elapsed(&ts);
}
-static unsigned int e2ring(int gem_fd, const struct intel_execution_engine2 *e)
-{
- return gem_class_instance_to_eb_flags(gem_fd, e->class, e->instance);
-}
-
#define TEST_BUSY (1)
#define FLAG_SYNC (2)
#define TEST_TRAILING_IDLE (4)
@@ -177,7 +172,7 @@ static igt_spin_t * __spin_poll(int fd, uint32_t ctx, unsigned long flags)
.engine = flags,
};
- if (gem_can_store_dword(fd, flags))
+ if (gem_class_can_store_dword(fd, flags))
opts.flags |= IGT_SPIN_POLL_RUN;
return __igt_spin_batch_factory(fd, &opts);
@@ -267,7 +262,7 @@ single(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags)
fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
if (flags & TEST_BUSY)
- spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
+ spin = spin_sync(gem_fd, 0, e->flags);
else
spin = NULL;
@@ -316,7 +311,7 @@ busy_start(int gem_fd, const struct intel_execution_engine2 *e)
*/
sleep(2);
- spin = __spin_sync(gem_fd, 0, e2ring(gem_fd, e));
+ spin = __spin_sync(gem_fd, 0, e->flags);
fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
@@ -359,11 +354,11 @@ busy_double_start(int gem_fd, const struct intel_execution_engine2 *e)
* re-submission in execlists mode. Make sure busyness is correctly
* reported with the engine busy, and after the engine went idle.
*/
- spin[0] = __spin_sync(gem_fd, 0, e2ring(gem_fd, e));
+ spin[0] = __spin_sync(gem_fd, 0, e->flags);
usleep(500e3);
spin[1] = __igt_spin_batch_new(gem_fd,
.ctx = ctx,
- .engine = e2ring(gem_fd, e));
+ .engine = e->flags);
/*
* Open PMU as fast as possible after the second spin batch in attempt
@@ -434,8 +429,8 @@ busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
i = 0;
fd[0] = -1;
- for_each_engine_class_instance(gem_fd, e_) {
- if (e == e_)
+ __for_each_physical_engine(gem_fd, e_) {
+ if (e->class == e_->class && e->instance == e_->instance)
busy_idx = i;
fd[i++] = open_group(I915_PMU_ENGINE_BUSY(e_->class,
@@ -445,7 +440,7 @@ busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
igt_assert_eq(i, num_engines);
- spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
+ spin = spin_sync(gem_fd, 0, e->flags);
pmu_read_multi(fd[0], num_engines, tval[0]);
slept = measured_usleep(batch_duration_ns / 1000);
if (flags & TEST_TRAILING_IDLE)
@@ -478,7 +473,7 @@ __submit_spin_batch(int gem_fd, igt_spin_t *spin,
struct drm_i915_gem_execbuffer2 eb = spin->execbuf;
eb.flags &= ~(0x3f | I915_EXEC_BSD_MASK);
- eb.flags |= e2ring(gem_fd, e) | I915_EXEC_NO_RELOC;
+ eb.flags |= e->flags | I915_EXEC_NO_RELOC;
eb.batch_start_offset += offset;
gem_execbuf(gem_fd, &eb);
@@ -497,13 +492,13 @@ most_busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
unsigned int idle_idx, i;
i = 0;
- for_each_engine_class_instance(gem_fd, e_) {
- if (e == e_)
+ __for_each_physical_engine(gem_fd, e_) {
+ if (e->class == e_->class && e->instance == e_->instance)
idle_idx = i;
else if (spin)
__submit_spin_batch(gem_fd, spin, e_, 64);
else
- spin = __spin_poll(gem_fd, 0, e2ring(gem_fd, e_));
+ spin = __spin_poll(gem_fd, 0, e->flags);
val[i++] = I915_PMU_ENGINE_BUSY(e_->class, e_->instance);
}
@@ -554,11 +549,11 @@ all_busy_check_all(int gem_fd, const unsigned int num_engines,
unsigned int i;
i = 0;
- for_each_engine_class_instance(gem_fd, e) {
+ __for_each_physical_engine(gem_fd, e) {
if (spin)
__submit_spin_batch(gem_fd, spin, e, 64);
else
- spin = __spin_poll(gem_fd, 0, e2ring(gem_fd, e));
+ spin = __spin_poll(gem_fd, 0, e->flags);
val[i++] = I915_PMU_ENGINE_BUSY(e->class, e->instance);
}
@@ -602,7 +597,7 @@ no_sema(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags)
open_group(I915_PMU_ENGINE_WAIT(e->class, e->instance), fd);
if (flags & TEST_BUSY)
- spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
+ spin = spin_sync(gem_fd, 0, e->flags);
else
spin = NULL;
@@ -689,7 +684,7 @@ sema_wait(int gem_fd, const struct intel_execution_engine2 *e,
eb.buffer_count = 2;
eb.buffers_ptr = to_user_pointer(obj);
- eb.flags = e2ring(gem_fd, e);
+ eb.flags = e->flags;
/**
* Start the semaphore wait PMU and after some known time let the above
@@ -845,7 +840,7 @@ event_wait(int gem_fd, const struct intel_execution_engine2 *e)
eb.buffer_count = 1;
eb.buffers_ptr = to_user_pointer(&obj);
- eb.flags = e2ring(gem_fd, e) | I915_EXEC_SECURE;
+ eb.flags = e->flags | I915_EXEC_SECURE;
for_each_pipe_with_valid_output(&data.display, p, output) {
struct igt_helper_process waiter = { };
@@ -936,7 +931,7 @@ multi_client(int gem_fd, const struct intel_execution_engine2 *e)
*/
fd[1] = open_pmu(config);
- spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
+ spin = spin_sync(gem_fd, 0, e->flags);
val[0] = val[1] = __pmu_read_single(fd[0], &ts[0]);
slept[1] = measured_usleep(batch_duration_ns / 1000);
@@ -1465,7 +1460,7 @@ test_enable_race(int gem_fd, const struct intel_execution_engine2 *e)
eb.buffer_count = 1;
eb.buffers_ptr = to_user_pointer(&obj);
- eb.flags = e2ring(gem_fd, e);
+ eb.flags = e->flags;
/*
* This test is probabilistic so run in a few times to increase the
@@ -1570,7 +1565,7 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e,
igt_spin_t *spin;
/* Allocate our spin batch and idle it. */
- spin = igt_spin_batch_new(gem_fd, .engine = e2ring(gem_fd, e));
+ spin = igt_spin_batch_new(gem_fd, .engine = e->flags);
igt_spin_batch_end(spin);
gem_sync(gem_fd, spin->handle);
@@ -1674,7 +1669,7 @@ igt_main
I915_PMU_LAST - __I915_PMU_OTHER(0) + 1;
unsigned int num_engines = 0;
int fd = -1;
- const struct intel_execution_engine2 *e;
+ struct intel_execution_engine2 *e;
unsigned int i;
igt_fixture {
@@ -1683,7 +1678,7 @@ igt_main
igt_require_gem(fd);
igt_require(i915_type_id() > 0);
- for_each_engine_class_instance(fd, e)
+ __for_each_physical_engine(fd, e)
num_engines++;
}
@@ -1693,7 +1688,7 @@ igt_main
igt_subtest("invalid-init")
invalid_init();
- __for_each_engine_class_instance(e) {
+ __for_each_physical_engine(fd, e) {
const unsigned int pct[] = { 2, 50, 98 };
/**
@@ -1897,7 +1892,7 @@ igt_main
gem_quiescent_gpu(fd);
}
- __for_each_engine_class_instance(e) {
+ __for_each_physical_engine(fd, e) {
igt_subtest_group {
igt_fixture {
gem_require_engine(render_fd,
--
2.20.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 7/7] test: perf_pmu: use the gem_engine_topology library
2019-04-05 1:07 ` [igt-dev] [PATCH v17 7/7] test: perf_pmu: use the gem_engine_topology library Andi Shyti
@ 2019-04-05 8:50 ` Tvrtko Ursulin
2019-04-05 9:09 ` Andi Shyti
0 siblings, 1 reply; 18+ messages in thread
From: Tvrtko Ursulin @ 2019-04-05 8:50 UTC (permalink / raw)
To: Andi Shyti, IGT dev
On 05/04/2019 02:07, Andi Shyti wrote:
> From: Andi Shyti <andi.shyti@intel.com>
>
> Replace the legacy for_each_engine* defines with the ones
> implemented in the gem_engine_topology library.
>
> Use whenever possible gem_engine_can_store_dword() that checks
> class instead of flags.
>
> Now the __for_each_engine_class_instance and
> for_each_engine_class_instance are unused, remove them.
>
> Signed-off-by: Andi Shyti <andi.shyti@intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> ---
> lib/igt_gt.h | 7 -------
> tests/perf_pmu.c | 53 ++++++++++++++++++++++--------------------------
> 2 files changed, 24 insertions(+), 36 deletions(-)
>
> diff --git a/lib/igt_gt.h b/lib/igt_gt.h
> index af4cc38a1ef7..c2ca07e03738 100644
> --- a/lib/igt_gt.h
> +++ b/lib/igt_gt.h
> @@ -119,11 +119,4 @@ void gem_require_engine(int gem_fd,
> igt_require(gem_has_engine(gem_fd, class, instance));
> }
>
> -#define __for_each_engine_class_instance(e__) \
> - for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
> -
> -#define for_each_engine_class_instance(fd__, e__) \
> - for ((e__) = intel_execution_engines2; (e__)->name; (e__)++) \
> - for_if (gem_has_engine((fd__), (e__)->class, (e__)->instance))
> -
> #endif /* IGT_GT_H */
> diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
> index 4f552bc2ae28..c954a0d54b72 100644
> --- a/tests/perf_pmu.c
> +++ b/tests/perf_pmu.c
> @@ -158,11 +158,6 @@ static unsigned int measured_usleep(unsigned int usec)
> return igt_nsec_elapsed(&ts);
> }
>
> -static unsigned int e2ring(int gem_fd, const struct intel_execution_engine2 *e)
> -{
> - return gem_class_instance_to_eb_flags(gem_fd, e->class, e->instance);
> -}
> -
> #define TEST_BUSY (1)
> #define FLAG_SYNC (2)
> #define TEST_TRAILING_IDLE (4)
> @@ -177,7 +172,7 @@ static igt_spin_t * __spin_poll(int fd, uint32_t ctx, unsigned long flags)
> .engine = flags,
> };
>
> - if (gem_can_store_dword(fd, flags))
> + if (gem_class_can_store_dword(fd, flags))
flags is not a class here but either legacy eb flags or engine map index.
I think you can refactor so this function (and the chain of callers)
takes a pointer to intel_execution_engine2 and then use class and flags
as needed.
The rest looks okay on a quick read through.
Regards,
Tvrtko
> opts.flags |= IGT_SPIN_POLL_RUN;
>
> return __igt_spin_batch_factory(fd, &opts);
> @@ -267,7 +262,7 @@ single(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags)
> fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
>
> if (flags & TEST_BUSY)
> - spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
> + spin = spin_sync(gem_fd, 0, e->flags);
> else
> spin = NULL;
>
> @@ -316,7 +311,7 @@ busy_start(int gem_fd, const struct intel_execution_engine2 *e)
> */
> sleep(2);
>
> - spin = __spin_sync(gem_fd, 0, e2ring(gem_fd, e));
> + spin = __spin_sync(gem_fd, 0, e->flags);
>
> fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
>
> @@ -359,11 +354,11 @@ busy_double_start(int gem_fd, const struct intel_execution_engine2 *e)
> * re-submission in execlists mode. Make sure busyness is correctly
> * reported with the engine busy, and after the engine went idle.
> */
> - spin[0] = __spin_sync(gem_fd, 0, e2ring(gem_fd, e));
> + spin[0] = __spin_sync(gem_fd, 0, e->flags);
> usleep(500e3);
> spin[1] = __igt_spin_batch_new(gem_fd,
> .ctx = ctx,
> - .engine = e2ring(gem_fd, e));
> + .engine = e->flags);
>
> /*
> * Open PMU as fast as possible after the second spin batch in attempt
> @@ -434,8 +429,8 @@ busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
>
> i = 0;
> fd[0] = -1;
> - for_each_engine_class_instance(gem_fd, e_) {
> - if (e == e_)
> + __for_each_physical_engine(gem_fd, e_) {
> + if (e->class == e_->class && e->instance == e_->instance)
> busy_idx = i;
>
> fd[i++] = open_group(I915_PMU_ENGINE_BUSY(e_->class,
> @@ -445,7 +440,7 @@ busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
>
> igt_assert_eq(i, num_engines);
>
> - spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
> + spin = spin_sync(gem_fd, 0, e->flags);
> pmu_read_multi(fd[0], num_engines, tval[0]);
> slept = measured_usleep(batch_duration_ns / 1000);
> if (flags & TEST_TRAILING_IDLE)
> @@ -478,7 +473,7 @@ __submit_spin_batch(int gem_fd, igt_spin_t *spin,
> struct drm_i915_gem_execbuffer2 eb = spin->execbuf;
>
> eb.flags &= ~(0x3f | I915_EXEC_BSD_MASK);
> - eb.flags |= e2ring(gem_fd, e) | I915_EXEC_NO_RELOC;
> + eb.flags |= e->flags | I915_EXEC_NO_RELOC;
> eb.batch_start_offset += offset;
>
> gem_execbuf(gem_fd, &eb);
> @@ -497,13 +492,13 @@ most_busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
> unsigned int idle_idx, i;
>
> i = 0;
> - for_each_engine_class_instance(gem_fd, e_) {
> - if (e == e_)
> + __for_each_physical_engine(gem_fd, e_) {
> + if (e->class == e_->class && e->instance == e_->instance)
> idle_idx = i;
> else if (spin)
> __submit_spin_batch(gem_fd, spin, e_, 64);
> else
> - spin = __spin_poll(gem_fd, 0, e2ring(gem_fd, e_));
> + spin = __spin_poll(gem_fd, 0, e->flags);
>
> val[i++] = I915_PMU_ENGINE_BUSY(e_->class, e_->instance);
> }
> @@ -554,11 +549,11 @@ all_busy_check_all(int gem_fd, const unsigned int num_engines,
> unsigned int i;
>
> i = 0;
> - for_each_engine_class_instance(gem_fd, e) {
> + __for_each_physical_engine(gem_fd, e) {
> if (spin)
> __submit_spin_batch(gem_fd, spin, e, 64);
> else
> - spin = __spin_poll(gem_fd, 0, e2ring(gem_fd, e));
> + spin = __spin_poll(gem_fd, 0, e->flags);
>
> val[i++] = I915_PMU_ENGINE_BUSY(e->class, e->instance);
> }
> @@ -602,7 +597,7 @@ no_sema(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags)
> open_group(I915_PMU_ENGINE_WAIT(e->class, e->instance), fd);
>
> if (flags & TEST_BUSY)
> - spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
> + spin = spin_sync(gem_fd, 0, e->flags);
> else
> spin = NULL;
>
> @@ -689,7 +684,7 @@ sema_wait(int gem_fd, const struct intel_execution_engine2 *e,
>
> eb.buffer_count = 2;
> eb.buffers_ptr = to_user_pointer(obj);
> - eb.flags = e2ring(gem_fd, e);
> + eb.flags = e->flags;
>
> /**
> * Start the semaphore wait PMU and after some known time let the above
> @@ -845,7 +840,7 @@ event_wait(int gem_fd, const struct intel_execution_engine2 *e)
>
> eb.buffer_count = 1;
> eb.buffers_ptr = to_user_pointer(&obj);
> - eb.flags = e2ring(gem_fd, e) | I915_EXEC_SECURE;
> + eb.flags = e->flags | I915_EXEC_SECURE;
>
> for_each_pipe_with_valid_output(&data.display, p, output) {
> struct igt_helper_process waiter = { };
> @@ -936,7 +931,7 @@ multi_client(int gem_fd, const struct intel_execution_engine2 *e)
> */
> fd[1] = open_pmu(config);
>
> - spin = spin_sync(gem_fd, 0, e2ring(gem_fd, e));
> + spin = spin_sync(gem_fd, 0, e->flags);
>
> val[0] = val[1] = __pmu_read_single(fd[0], &ts[0]);
> slept[1] = measured_usleep(batch_duration_ns / 1000);
> @@ -1465,7 +1460,7 @@ test_enable_race(int gem_fd, const struct intel_execution_engine2 *e)
>
> eb.buffer_count = 1;
> eb.buffers_ptr = to_user_pointer(&obj);
> - eb.flags = e2ring(gem_fd, e);
> + eb.flags = e->flags;
>
> /*
> * This test is probabilistic so run in a few times to increase the
> @@ -1570,7 +1565,7 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e,
> igt_spin_t *spin;
>
> /* Allocate our spin batch and idle it. */
> - spin = igt_spin_batch_new(gem_fd, .engine = e2ring(gem_fd, e));
> + spin = igt_spin_batch_new(gem_fd, .engine = e->flags);
> igt_spin_batch_end(spin);
> gem_sync(gem_fd, spin->handle);
>
> @@ -1674,7 +1669,7 @@ igt_main
> I915_PMU_LAST - __I915_PMU_OTHER(0) + 1;
> unsigned int num_engines = 0;
> int fd = -1;
> - const struct intel_execution_engine2 *e;
> + struct intel_execution_engine2 *e;
> unsigned int i;
>
> igt_fixture {
> @@ -1683,7 +1678,7 @@ igt_main
> igt_require_gem(fd);
> igt_require(i915_type_id() > 0);
>
> - for_each_engine_class_instance(fd, e)
> + __for_each_physical_engine(fd, e)
> num_engines++;
> }
>
> @@ -1693,7 +1688,7 @@ igt_main
> igt_subtest("invalid-init")
> invalid_init();
>
> - __for_each_engine_class_instance(e) {
> + __for_each_physical_engine(fd, e) {
> const unsigned int pct[] = { 2, 50, 98 };
>
> /**
> @@ -1897,7 +1892,7 @@ igt_main
> gem_quiescent_gpu(fd);
> }
>
> - __for_each_engine_class_instance(e) {
> + __for_each_physical_engine(fd, e) {
> igt_subtest_group {
> igt_fixture {
> gem_require_engine(render_fd,
>
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [igt-dev] [PATCH v17 7/7] test: perf_pmu: use the gem_engine_topology library
2019-04-05 8:50 ` Tvrtko Ursulin
@ 2019-04-05 9:09 ` Andi Shyti
2019-04-05 9:22 ` Tvrtko Ursulin
0 siblings, 1 reply; 18+ messages in thread
From: Andi Shyti @ 2019-04-05 9:09 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: IGT dev, Andi Shyti
> > @@ -177,7 +172,7 @@ static igt_spin_t * __spin_poll(int fd, uint32_t ctx, unsigned long flags)
> > .engine = flags,
> > };
> > - if (gem_can_store_dword(fd, flags))
> > + if (gem_class_can_store_dword(fd, flags))
>
> flags is not a class here but either legacy eb flags or engine map index.
>
> I think you can refactor so this function (and the chain of callers) takes a
> pointer to intel_execution_engine2 and then use class and flags as needed.
It looks more logical, indeed to have the engine in it, but at
some point you call
spin = spin_sync(gem_fd, 0, I915_EXEC_RENDER);
In the previous patchset I had created two branches of spin_sync,
one that took flags and one that took intel_execution_engine2,
but it looked to much of useless code.
In this case I could either create a dummy engine to make things
work with intel_execution_engine2 or just use flags and minimise
the changes.
In this patch there is still the problem of 4/5 subtests failing,
but we can discuss that offline and, as you noticed, the
igt_dummyload commit lost in the meanders of rebasing.
Thanks,
Andi
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [igt-dev] [PATCH v17 7/7] test: perf_pmu: use the gem_engine_topology library
2019-04-05 9:09 ` Andi Shyti
@ 2019-04-05 9:22 ` Tvrtko Ursulin
0 siblings, 0 replies; 18+ messages in thread
From: Tvrtko Ursulin @ 2019-04-05 9:22 UTC (permalink / raw)
To: Andi Shyti; +Cc: IGT dev, Andi Shyti
On 05/04/2019 10:09, Andi Shyti wrote:
>>> @@ -177,7 +172,7 @@ static igt_spin_t * __spin_poll(int fd, uint32_t ctx, unsigned long flags)
>>> .engine = flags,
>>> };
>>> - if (gem_can_store_dword(fd, flags))
>>> + if (gem_class_can_store_dword(fd, flags))
>>
>> flags is not a class here but either legacy eb flags or engine map index.
>>
>> I think you can refactor so this function (and the chain of callers) takes a
>> pointer to intel_execution_engine2 and then use class and flags as needed.
>
> It looks more logical, indeed to have the engine in it, but at
> some point you call
>
> spin = spin_sync(gem_fd, 0, I915_EXEC_RENDER);
>
> In the previous patchset I had created two branches of spin_sync,
> one that took flags and one that took intel_execution_engine2,
> but it looked to much of useless code.
>
> In this case I could either create a dummy engine to make things
> work with intel_execution_engine2 or just use flags and minimise
> the changes.
I think it will have to take the engine since it needs both class and
flags. Or you can make it take those parameters separately? Latter I
guess makes it easier to convert the frequency test. But you could also
lookup the RCS in there with the __for_each_physical_engine loop. You
can do as you prefer. What looks tidier overall.
> In this patch there is still the problem of 4/5 subtests failing,
> but we can discuss that offline and, as you noticed, the
> igt_dummyload commit lost in the meanders of rebasing.
It could be some detail in the missing patch so will see when you post it.
Or the broken logic in __spin_poll is affecting it? I never tested with
some engines using a pollable spinner and some not, only all or none.
Regards,
Tvrtko
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread
* [igt-dev] ✗ Fi.CI.BAT: failure for series starting with [v17,1/7] lib/igt_gt: remove unnecessary argument
2019-04-05 1:07 [igt-dev] [PATCH v17 0/7] new engine discovery interface Andi Shyti
` (6 preceding siblings ...)
2019-04-05 1:07 ` [igt-dev] [PATCH v17 7/7] test: perf_pmu: use the gem_engine_topology library Andi Shyti
@ 2019-04-05 2:06 ` Patchwork
7 siblings, 0 replies; 18+ messages in thread
From: Patchwork @ 2019-04-05 2:06 UTC (permalink / raw)
To: Andi Shyti; +Cc: igt-dev
== Series Details ==
Series: series starting with [v17,1/7] lib/igt_gt: remove unnecessary argument
URL : https://patchwork.freedesktop.org/series/59033/
State : failure
== Summary ==
IGT patchset build failed on latest successful build
8770e24fe4008404da769c16b7edac6142225ad7 i915/pm_backlight: Do not turn off DPMS before system suspend
251/266 testcase check: amdgpu/amd_basic OK 0.11 s
252/266 testcase check: amdgpu/amd_cs_nop OK 0.07 s
253/266 testcase check: amdgpu/amd_prime OK 0.10 s
254/266 runner OK 1.19 s
255/266 runner_json OK 0.07 s
256/266 assembler: test/mov OK 0.08 s
257/266 assembler: test/frc OK 0.05 s
258/266 assembler: test/regtype OK 0.06 s
259/266 assembler: test/rndd OK 0.05 s
260/266 assembler: test/rndu OK 0.07 s
261/266 assembler: test/rnde OK 0.07 s
262/266 assembler: test/rnde-intsrc OK 0.06 s
263/266 assembler: test/rndz OK 0.04 s
264/266 assembler: test/lzd OK 0.06 s
265/266 assembler: test/not OK 0.05 s
266/266 assembler: test/immediate OK 0.05 s
OK: 265
FAIL: 1
SKIP: 0
TIMEOUT: 0
The output from the failed tests:
248/266 testcase check: perf_pmu FAIL 0.18 s (exit status 1)
--- command ---
/home/cidrm/igt-gpu-tools/tests/igt_command_line.sh perf_pmu
--- stdout ---
tests/perf_pmu:
Checking invalid option handling...
Checking valid option handling...
Checking subtest enumeration...
FAIL: tests/perf_pmu
--- stderr ---
Received signal SIGSEGV.
Stack trace:
#0 [fatal_sig_handler+0xd5]
#1 [killpg+0x40]
#2 [__real_main1666+0x1eb]
#3 [main+0x44]
#4 [__libc_start_main+0xe7]
#5 [_start+0x2a]
-------
Full log written to /home/cidrm/igt-gpu-tools/build/meson-logs/testlog.txt
FAILED: meson-test
/usr/bin/python3 -u /usr/bin/meson test --no-rebuild --print-errorlogs
ninja: build stopped: subcommand failed.
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 18+ messages in thread