Re: [Intel-gfx] [PATCH i-g-t] tests/drm_fdinfo: Test virtual engines

2022-06-16 Thread Umesh Nerlige Ramappa
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

2022-06-16 Thread Tvrtko Ursulin
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);
+
+