[igt-dev] [PATCH i-g-t 4/6] lib/i915/gem_engine_topology: Add helper to list engines
priyanka.dandamudi at intel.com
priyanka.dandamudi at intel.com
Thu Apr 21 14:52:09 UTC 2022
From: Chris Wilson <chris.p.wilson at intel.com>
Add helpers to check the region of an engine and
list the engines for a gt of a given class.
Cc: Bommu Krishnaiah <krishnaiah.bommu at intel.com>
Cc: Petri Latvala <petri.latvala at intel.com>
Signed-off-by: Chris Wilson <chris.p.wilson at intel.com>
Signed-off-by: Priyanka Dandamudi <priyanka.dandamudi at intel.com>
---
lib/i915/gem_engine_topology.c | 118 +++++++++++++++++++++++++++++----
lib/i915/gem_engine_topology.h | 8 +++
2 files changed, 113 insertions(+), 13 deletions(-)
diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
index ca3333c2..9029a491 100644
--- a/lib/i915/gem_engine_topology.c
+++ b/lib/i915/gem_engine_topology.c
@@ -25,6 +25,7 @@
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
+#include <limits.h>
#include "drmtest.h"
#include "igt_sysfs.h"
@@ -89,17 +90,30 @@
#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)
+static int __i915_query(int fd, struct drm_i915_query *q)
{
int err = 0;
- if (igt_ioctl(fd, DRM_IOCTL_I915_QUERY, q))
+ if (igt_ioctl(fd, DRM_IOCTL_I915_QUERY, q)) {
err = -errno;
-
+ igt_assume(err);
+ }
errno = 0;
+
return err;
}
+static int
+__i915_query_items(int fd, struct drm_i915_query_item *items, uint32_t n_items)
+{
+ struct drm_i915_query q = {
+ .num_items = n_items,
+ .items_ptr = to_user_pointer(items),
+ };
+
+ return __i915_query(fd, &q);
+}
+
/**
* __gem_query_engines:
* @fd: open i915 drm file descriptor
@@ -112,17 +126,13 @@ int __gem_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);
+ struct drm_i915_query_item item = {
+ .query_id = DRM_I915_QUERY_ENGINE_INFO,
+ .data_ptr = to_user_pointer(query_engines),
+ .length = length,
+ };
- return __gem_query(fd, &query);
+ return __i915_query_items(fd, &item, 1);
}
static const char *class_names[] = {
@@ -133,6 +143,16 @@ static const char *class_names[] = {
[I915_ENGINE_CLASS_COMPUTE] = "ccs",
};
+const char *gem_engine_class_to_str(int class)
+{
+ const char *str = NULL;
+
+ if (class < ARRAY_SIZE(class_names))
+ str = class_names[class];
+
+ return str ?: "unk";
+}
+
static void init_engine(struct intel_execution_engine2 *e2,
uint16_t class, uint16_t instance, uint64_t flags)
{
@@ -350,6 +370,78 @@ struct intel_execution_engine2 gem_eb_flags_to_engine(unsigned int flags)
return e2__;
}
+static int has_region(int i915,
+ const struct i915_engine_class_instance *engine,
+ int closest_gt)
+{
+ int min_distance = INT_MAX;
+
+ for (int gt = 0;; gt++) {
+ struct drm_i915_query_distance_info info = {
+ .region.memory_class = I915_MEMORY_CLASS_DEVICE,
+ .region.memory_instance = gt,
+ .engine = *engine,
+ };
+ struct drm_i915_query_item item = {
+ .query_id = DRM_I915_QUERY_DISTANCE_INFO,
+ .data_ptr = to_user_pointer(&info),
+ .length = sizeof(info)
+ };
+ int err;
+
+ err = __i915_query_items(i915, &item, 1);
+ if (err < 0 || item.length < 0)
+ break;
+
+ if (info.distance == 0)
+ return gt;
+
+ if (info.distance < min_distance) {
+ min_distance = info.distance;
+ closest_gt = gt;
+ }
+ }
+
+ return closest_gt;
+}
+
+struct i915_engine_class_instance *
+gem_list_engines(int i915,
+ uint32_t gt_mask,
+ uint32_t class_mask,
+ unsigned int *out)
+{
+ struct i915_engine_class_instance *engines;
+ struct drm_i915_query_engine_info *info;
+ const int size = 256 << 10; /* enough for 8 classes of 256 engines */
+ unsigned int max = 0, count = 0;
+
+ info = calloc(1, size);
+ if (!__gem_query_engines(i915, info, size))
+ max = info->num_engines;
+
+ engines = (struct i915_engine_class_instance *)info;
+ for (unsigned int i = 0; i < max; i++) {
+ const struct i915_engine_class_instance *e =
+ &info->engines[i].engine;
+
+ if (!((class_mask >> e->engine_class) & 1))
+ continue;
+ if (!((gt_mask >> has_region(i915, e, 0)) & 1))
+ continue;
+
+ engines[count++] = *e;
+ }
+
+ if (!count) {
+ free(engines);
+ engines = NULL;
+ }
+
+ *out = count;
+ return engines;
+}
+
bool gem_engine_is_equal(const struct intel_execution_engine2 *e1,
const struct intel_execution_engine2 *e2)
{
diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
index 987f2bf9..760b6ab3 100644
--- a/lib/i915/gem_engine_topology.h
+++ b/lib/i915/gem_engine_topology.h
@@ -61,6 +61,14 @@ intel_get_current_physical_engine(struct intel_engine_data *ed);
void intel_next_engine(struct intel_engine_data *ed);
+const char *gem_engine_class_to_str(int engine_class);
+
+struct i915_engine_class_instance *
+gem_list_engines(int i915,
+ uint32_t gt_mask,
+ uint32_t class_mask,
+ unsigned int *count);
+
bool gem_engine_is_equal(const struct intel_execution_engine2 *e1,
const struct intel_execution_engine2 *e2);
--
2.25.1
More information about the igt-dev
mailing list