Re: [Intel-gfx] [PATCH i-g-t] tests/drm_fdinfo: Test virtual engines
Thanks for adding these tests. I ran these with the kernel patch I had posted for GuC support and updated the patch to work with virtual engines - https://patchwork.freedesktop.org/series/105085/#rev3 I have listed some changes I had to do in the below patch. With those (or similar changes), this is: Reviewed-by: Umesh Nerlige Ramappa On Thu, Jun 16, 2022 at 02:32:03PM +0100, Tvrtko Ursulin wrote: From: Tvrtko Ursulin We need some coverage of the virtual engines. Signed-off-by: Tvrtko Ursulin Cc: Umesh Nerlige Ramappa --- tests/i915/drm_fdinfo.c | 284 +++- 1 file changed, 282 insertions(+), 2 deletions(-) diff --git a/tests/i915/drm_fdinfo.c b/tests/i915/drm_fdinfo.c index 3475d35b23b9..0a42370d54ce 100644 --- a/tests/i915/drm_fdinfo.c +++ b/tests/i915/drm_fdinfo.c @@ -27,6 +27,7 @@ #include "igt_device.h" #include "igt_drm_fdinfo.h" #include "i915/gem.h" +#include "i915/gem_vm.h" #include "intel_ctx.h" IGT_TEST_DESCRIPTION("Test the i915 drm fdinfo data"); @@ -90,10 +91,10 @@ static igt_spin_t *__spin_poll(int fd, uint64_t ahnd, const intel_ctx_t *ctx, struct igt_spin_factory opts = { .ahnd = ahnd, .ctx = ctx, - .engine = e->flags, + .engine = e ? e->flags : 0, }; - if (gem_class_can_store_dword(fd, e->class)) + if (!e || gem_class_can_store_dword(fd, e->class)) opts.flags |= IGT_SPIN_POLL_RUN; return __igt_spin_factory(fd, &opts); @@ -440,6 +441,265 @@ all_busy_check_all(int gem_fd, const intel_ctx_t *ctx, gem_quiescent_gpu(gem_fd); } +static struct i915_engine_class_instance * +list_engines(const intel_ctx_cfg_t *cfg, +unsigned int class, unsigned int *out) +{ + struct i915_engine_class_instance *ci; + unsigned int count = 0, i; + + ci = malloc(cfg->num_engines * sizeof(*ci)); + igt_assert(ci); + + for (i = 0; i < cfg->num_engines; i++) { + if (class == cfg->engines[i].engine_class) + ci[count++] = cfg->engines[i]; + } + + if (!count) { + free(ci); + ci = NULL; + } + + *out = count; + return ci; +} + +static size_t sizeof_load_balance(int count) +{ + return offsetof(struct i915_context_engines_load_balance, + engines[count]); +} + +static size_t sizeof_param_engines(int count) +{ + return offsetof(struct i915_context_param_engines, + engines[count]); +} + +#define alloca0(sz) ({ size_t sz__ = (sz); memset(alloca(sz__), 0, sz__); }) + +static int __set_load_balancer(int i915, uint32_t ctx, + const struct i915_engine_class_instance *ci, + unsigned int count, + void *ext) +{ + struct i915_context_engines_load_balance *balancer = + alloca0(sizeof_load_balance(count)); + struct i915_context_param_engines *engines = + alloca0(sizeof_param_engines(count + 1)); + struct drm_i915_gem_context_param p = { + .ctx_id = ctx, + .param = I915_CONTEXT_PARAM_ENGINES, + .size = sizeof_param_engines(count + 1), + .value = to_user_pointer(engines) + }; + + balancer->base.name = I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE; + balancer->base.next_extension = to_user_pointer(ext); + + igt_assert(count); + balancer->num_siblings = count; + memcpy(balancer->engines, ci, count * sizeof(*ci)); + + engines->extensions = to_user_pointer(balancer); + engines->engines[0].engine_class = + I915_ENGINE_CLASS_INVALID; + engines->engines[0].engine_instance = + I915_ENGINE_CLASS_INVALID_NONE; + memcpy(engines->engines + 1, ci, count * sizeof(*ci)); + + return __gem_context_set_param(i915, &p); +} + +static void set_load_balancer(int i915, uint32_t ctx, + const struct i915_engine_class_instance *ci, + unsigned int count, + void *ext) +{ + igt_assert_eq(__set_load_balancer(i915, ctx, ci, count, ext), 0); +} + static void context_unban(int i915, uint32_t context_id) { struct drm_i915_gem_context_param param = { .ctx_id = context_id, .param = I915_CONTEXT_PARAM_BANNABLE, .value = 0, }; gem_context_set_param(i915, ¶m); } +static void +virtual(int i915, const intel_ctx_cfg_t *base_cfg, unsigned int flags) +{ + intel_ctx_cfg_t cfg = {}; + + cfg.vm = gem_vm_create(i915); + + for (int class = 0; class < 32; class++) { + struct i915_engine_class_instance *ci; + unsigned int count; + + if (!gem_class_can_store_dword(i915, class)) + continue; + + ci = list_engin
[Intel-gfx] [PATCH i-g-t] tests/drm_fdinfo: Test virtual engines
From: Tvrtko Ursulin We need some coverage of the virtual engines. Signed-off-by: Tvrtko Ursulin Cc: Umesh Nerlige Ramappa --- tests/i915/drm_fdinfo.c | 284 +++- 1 file changed, 282 insertions(+), 2 deletions(-) diff --git a/tests/i915/drm_fdinfo.c b/tests/i915/drm_fdinfo.c index 3475d35b23b9..0a42370d54ce 100644 --- a/tests/i915/drm_fdinfo.c +++ b/tests/i915/drm_fdinfo.c @@ -27,6 +27,7 @@ #include "igt_device.h" #include "igt_drm_fdinfo.h" #include "i915/gem.h" +#include "i915/gem_vm.h" #include "intel_ctx.h" IGT_TEST_DESCRIPTION("Test the i915 drm fdinfo data"); @@ -90,10 +91,10 @@ static igt_spin_t *__spin_poll(int fd, uint64_t ahnd, const intel_ctx_t *ctx, struct igt_spin_factory opts = { .ahnd = ahnd, .ctx = ctx, - .engine = e->flags, + .engine = e ? e->flags : 0, }; - if (gem_class_can_store_dword(fd, e->class)) + if (!e || gem_class_can_store_dword(fd, e->class)) opts.flags |= IGT_SPIN_POLL_RUN; return __igt_spin_factory(fd, &opts); @@ -440,6 +441,265 @@ all_busy_check_all(int gem_fd, const intel_ctx_t *ctx, gem_quiescent_gpu(gem_fd); } +static struct i915_engine_class_instance * +list_engines(const intel_ctx_cfg_t *cfg, +unsigned int class, unsigned int *out) +{ + struct i915_engine_class_instance *ci; + unsigned int count = 0, i; + + ci = malloc(cfg->num_engines * sizeof(*ci)); + igt_assert(ci); + + for (i = 0; i < cfg->num_engines; i++) { + if (class == cfg->engines[i].engine_class) + ci[count++] = cfg->engines[i]; + } + + if (!count) { + free(ci); + ci = NULL; + } + + *out = count; + return ci; +} + +static size_t sizeof_load_balance(int count) +{ + return offsetof(struct i915_context_engines_load_balance, + engines[count]); +} + +static size_t sizeof_param_engines(int count) +{ + return offsetof(struct i915_context_param_engines, + engines[count]); +} + +#define alloca0(sz) ({ size_t sz__ = (sz); memset(alloca(sz__), 0, sz__); }) + +static int __set_load_balancer(int i915, uint32_t ctx, + const struct i915_engine_class_instance *ci, + unsigned int count, + void *ext) +{ + struct i915_context_engines_load_balance *balancer = + alloca0(sizeof_load_balance(count)); + struct i915_context_param_engines *engines = + alloca0(sizeof_param_engines(count + 1)); + struct drm_i915_gem_context_param p = { + .ctx_id = ctx, + .param = I915_CONTEXT_PARAM_ENGINES, + .size = sizeof_param_engines(count + 1), + .value = to_user_pointer(engines) + }; + + balancer->base.name = I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE; + balancer->base.next_extension = to_user_pointer(ext); + + igt_assert(count); + balancer->num_siblings = count; + memcpy(balancer->engines, ci, count * sizeof(*ci)); + + engines->extensions = to_user_pointer(balancer); + engines->engines[0].engine_class = + I915_ENGINE_CLASS_INVALID; + engines->engines[0].engine_instance = + I915_ENGINE_CLASS_INVALID_NONE; + memcpy(engines->engines + 1, ci, count * sizeof(*ci)); + + return __gem_context_set_param(i915, &p); +} + +static void set_load_balancer(int i915, uint32_t ctx, + const struct i915_engine_class_instance *ci, + unsigned int count, + void *ext) +{ + igt_assert_eq(__set_load_balancer(i915, ctx, ci, count, ext), 0); +} + +static void +virtual(int i915, const intel_ctx_cfg_t *base_cfg, unsigned int flags) +{ + intel_ctx_cfg_t cfg = {}; + + cfg.vm = gem_vm_create(i915); + + for (int class = 0; class < 32; class++) { + struct i915_engine_class_instance *ci; + unsigned int count; + + if (!gem_class_can_store_dword(i915, class)) + continue; + + ci = list_engines(base_cfg, class, &count); + if (!ci) + continue; + + for (unsigned int pass = 0; pass < count; pass++) { + const intel_ctx_t *ctx; + unsigned long slept; + uint64_t ahnd, val; + igt_spin_t *spin; + + igt_assert(sizeof(*ci) == sizeof(int)); + igt_permute_array(ci, count, igt_exchange_int); + + igt_debug("class %u, pass %u/%u...\n", class, pass, count); + + ctx = intel_ctx_create(i915, &cfg); + ahnd = get_reloc_ahnd(i915, ctx->id); + +