[igt-dev] [PATCH i-g-t 04/20] lib/i915/perf: Derive topology info for xe devices
Ashutosh Dixit
ashutosh.dixit at intel.com
Thu Jul 20 23:17:40 UTC 2023
Derive topology info for xe devices and feed it into
intel_perf_for_devinfo.
Signed-off-by: Ashutosh Dixit <ashutosh.dixit at intel.com>
---
lib/i915/perf.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++-
lib/i915/perf.h | 1 +
2 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/lib/i915/perf.c b/lib/i915/perf.c
index 5b08c983918a..0bb1aa59045c 100644
--- a/lib/i915/perf.c
+++ b/lib/i915/perf.c
@@ -38,8 +38,10 @@
#include <i915_drm.h>
#include "drmtest.h"
+#include "igt_aux.h"
#include "i915_pciids.h"
#include "intel_chipset.h"
+#include "ioctl_wrappers.h"
#include "linux_scaffold.h"
#include "perf.h"
#include "xe/xe_query.h"
@@ -609,6 +611,108 @@ intel_sysfs_attr_id_to_name(int sysfs_dirfd, intel_sysfs_attr_id id, int gt)
intel_sysfs_attr_name[0][id];
}
+struct drm_i915_query_topology_info *
+xe_fill_i915_topology_info(int drm_fd)
+{
+ struct drm_i915_query_topology_info i915_topinfo = {};
+ struct drm_i915_query_topology_info *i915_topo;
+ struct drm_xe_query_topology_mask *xe_topo;
+ int total_size, pos = 0;
+ u8 *ptr;
+ struct drm_xe_device_query query = {
+ .extensions = 0,
+ .query = DRM_XE_DEVICE_QUERY_GT_TOPOLOGY,
+ .size = 0,
+ .data = 0,
+ };
+
+ /* Fixed fields, see fill_topology_info() and intel_sseu_set_info() in i915 */
+ i915_topinfo.max_slices = 1; /* always 1 */
+ if (IS_PONTEVECCHIO(xe_dev_id(drm_fd))) {
+ i915_topinfo.max_subslices = 64;
+ i915_topinfo.max_eus_per_subslice = 8;
+ } else if (intel_graphics_ver(xe_dev_id(drm_fd)) >= IP_VER(12, 50)) {
+ i915_topinfo.max_subslices = 32;
+ i915_topinfo.max_eus_per_subslice = 16;
+ } else if (intel_graphics_ver(xe_dev_id(drm_fd)) >= IP_VER(12, 0)) {
+ i915_topinfo.max_subslices = 6;
+ i915_topinfo.max_eus_per_subslice = 16;
+ } else {
+ igt_assert(0);
+ }
+ i915_topinfo.subslice_offset = 1; /* always 1 */
+ i915_topinfo.subslice_stride = DIV_ROUND_UP(i915_topinfo.max_subslices, 8);
+ i915_topinfo.eu_offset = i915_topinfo.subslice_offset + i915_topinfo.subslice_stride;
+ i915_topinfo.eu_stride = DIV_ROUND_UP(i915_topinfo.max_eus_per_subslice, 8);
+
+ /* Allocate and start filling the struct to return */
+ total_size = sizeof(i915_topinfo) + i915_topinfo.eu_offset +
+ i915_topinfo.max_subslices * i915_topinfo.eu_stride;
+ i915_topo = malloc(total_size);
+ igt_assert(i915_topo);
+
+ memcpy(i915_topo, &i915_topinfo, sizeof(i915_topinfo));
+ ptr = (u8 *)i915_topo + sizeof(i915_topinfo);
+ *ptr++ = 0x1; /* slice mask */
+
+ /* Get xe topology masks */
+ igt_assert_eq(igt_ioctl(drm_fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+ igt_assert_neq(query.size, 0);
+
+ xe_topo = malloc(query.size);
+ igt_assert(xe_topo);
+
+ query.data = to_user_pointer(xe_topo);
+ igt_assert_eq(igt_ioctl(drm_fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+ igt_debug("Topology size: %d\n", query.size);
+
+ while (query.size >= sizeof(struct drm_xe_query_topology_mask)) {
+ struct drm_xe_query_topology_mask *topo =
+ (struct drm_xe_query_topology_mask *)((unsigned char *)xe_topo + pos);
+ int i, sz = sizeof(struct drm_xe_query_topology_mask) + topo->num_bytes;
+ u64 geom_mask, compute_mask;
+
+ igt_debug(" gt_id: %d type: %d n:%d [%d] ",
+ topo->gt_id, topo->type, topo->num_bytes, sz);
+ for (int j = 0; j < topo->num_bytes; j++)
+ igt_debug(" %02x", topo->mask[j]);
+ igt_debug("\n");
+
+ /* i915 only returns topology for gt 0, do the same here */
+ if (topo->gt_id)
+ continue;
+
+ /* Follow the same order as in xe query_gt_topology() */
+ switch (topo->type) {
+ case XE_TOPO_DSS_GEOMETRY:
+ igt_assert_lte(i915_topo->subslice_stride, 8); /* Fit in u64 mask */
+ memcpy(&geom_mask, topo->mask, i915_topo->subslice_stride);
+ break;
+ case XE_TOPO_DSS_COMPUTE:
+ memcpy(&compute_mask, topo->mask, i915_topo->subslice_stride);
+ geom_mask |= compute_mask;
+ memcpy(ptr, &geom_mask, i915_topo->subslice_stride);
+ ptr += i915_topo->subslice_stride;
+ break;
+ case XE_TOPO_EU_PER_DSS:
+ for (i = 0; i < i915_topo->max_subslices; i++) {
+ memcpy(ptr, topo->mask, i915_topo->eu_stride);
+ ptr += i915_topo->eu_stride;
+ }
+ break;
+ default:
+ igt_assert(0);
+ }
+
+ query.size -= sz;
+ pos += sz;
+ }
+
+ free(xe_topo);
+
+ return i915_topo;
+}
+
static struct intel_perf *
xe_perf_for_fd(int drm_fd, int gt)
{
@@ -617,6 +721,7 @@ xe_perf_for_fd(int drm_fd, int gt)
u32 timestamp_frequency;
u64 gt_min_freq;
u64 gt_max_freq;
+ struct drm_i915_query_topology_info *topology;
struct intel_perf *ret;
int sysfs_dir_fd = open_master_sysfs_dir(drm_fd);
char path_min[64], path_max[64];
@@ -645,15 +750,23 @@ xe_perf_for_fd(int drm_fd, int gt)
device_id = intel_get_drm_devid(drm_fd);
timestamp_frequency = xe_gts(drm_fd)->gts[0].oa_timestamp_freq;
+ topology = xe_fill_i915_topology_info(drm_fd);
+ if (!topology) {
+ igt_warn("xe_fill_i915_topology_info failed\n");
+ return NULL;
+ }
+
ret = intel_perf_for_devinfo(device_id,
device_revision,
timestamp_frequency,
gt_min_freq * 1000000,
gt_max_freq * 1000000,
- NULL);
+ topology);
if (!ret)
igt_warn("intel_perf_for_devinfo failed\n");
+ free(topology);
+
return ret;
}
diff --git a/lib/i915/perf.h b/lib/i915/perf.h
index 8a71ac635e78..f3df578ddc5f 100644
--- a/lib/i915/perf.h
+++ b/lib/i915/perf.h
@@ -318,6 +318,7 @@ intel_perf_devinfo_eu_available(const struct intel_perf_devinfo *devinfo,
return (devinfo->eu_masks[subslice_offset + eu / 8] & (1U << eu % 8)) != 0;
}
+struct drm_i915_query_topology_info *xe_fill_i915_topology_info(int drm_fd);
struct intel_perf *intel_perf_for_fd(int drm_fd, int gt);
struct intel_perf *intel_perf_for_devinfo(uint32_t device_id,
uint32_t revision,
--
2.41.0
More information about the igt-dev
mailing list