* [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT
@ 2025-01-31 14:27 nishit.sharma
2025-01-31 17:11 ` ✗ GitLab.Pipeline: warning for " Patchwork
2025-02-05 22:26 ` [PATCH i-g-t] " Matt Roper
0 siblings, 2 replies; 8+ messages in thread
From: nishit.sharma @ 2025-01-31 14:27 UTC (permalink / raw)
To: igt-dev, nishit.sharma, zbigniew.kempczynski, matthew.d.roper
From: Nishit Sharma <nishit.sharma@intel.com>
Added functionality to get Tile ID, GT ID, GT belongs to which tile ID
in multi-tile/single-tile platforms. Added functionality to check if any
tile_ID information not provided by driver. E.g.tile available in platforms in order tile0,
tile1...tileX in serial order, If tile1 tile2 tile4...tileX populated
than will get Warning tile3 not available.
Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
lib/igt_sysfs.c | 3 +-
tests/intel/xe_multi_tile.c | 191 ++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
3 files changed, 194 insertions(+), 1 deletion(-)
create mode 100644 tests/intel/xe_multi_tile.c
diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
index 00d5822fd..37f1716e2 100644
--- a/lib/igt_sysfs.c
+++ b/lib/igt_sysfs.c
@@ -234,7 +234,8 @@ char *xe_sysfs_gt_path(int xe_device, int gt, char *path, int pathlen)
if (IS_PONTEVECCHIO(intel_get_drm_devid(xe_device)))
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile%d/gt%d",
- major(st.st_rdev), minor(st.st_rdev), gt, gt);
+ major(st.st_rdev), minor(st.st_rdev),
+ xe_gt_get_tile_id(xe_device, gt), gt);
else
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile0/gt%d",
major(st.st_rdev), minor(st.st_rdev), gt);
diff --git a/tests/intel/xe_multi_tile.c b/tests/intel/xe_multi_tile.c
new file mode 100644
index 000000000..7ca40f1fe
--- /dev/null
+++ b/tests/intel/xe_multi_tile.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ *
+ * Authors:
+ * Nishit Sharma <nishit.sharma@intel.com>
+ */
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "igt.h"
+#include "igt_sysfs.h"
+
+#include "xe_drm.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+
+#define MAX_TILES 8
+#define MAX_SLICES 2
+
+struct xe_gt_info {
+ /** @type: GT type: Main or Media */
+ uint16_t type;
+
+ /** @tile_id: Tile ID where this GT lives (Information only) */
+ uint16_t tile_id;
+
+ /** @gt_id: Unique ID of this GT within the PCI Device */
+ uint16_t gt_id;
+};
+
+/** @info: tile-gt info */
+struct xe_tile_info {
+ uint8_t tile_count;
+ uint8_t gt_count;
+ uint8_t mis_tile:1;
+ uint8_t mis_tile_id;
+ struct xe_gt_info gt_info[];
+};
+
+/**
+ * TEST: Test to get tile_id by iterating gt on xe
+ * Category: Core
+ * Mega feature: General Core features
+ * Sub-category: mapping tile/s with slices available
+ * Functionality: gt operation
+ */
+
+/**
+ * SUBTEST: show-tile-info
+ * SUBTEST: gt-configuration
+ * Description: Test iniitialize xe_tile_info structure with tile_id
+ * Test category: functionality test
+ *
+ */
+struct drm_xe_query_gt_list *xe_gt_list(int fd)
+{
+ struct drm_xe_query_gt_list *gt_list;
+ struct drm_xe_device_query query = {
+ .extensions = 0,
+ .query = DRM_XE_DEVICE_QUERY_GT_LIST,
+ .size = 0,
+ .data = 0,
+ };
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+ igt_assert_neq(query.size, 0);
+
+ gt_list = malloc(query.size);
+ igt_assert(gt_list);
+
+ query.data = to_user_pointer(gt_list);
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+
+ return gt_list;
+}
+
+static void igt_get_gt_info(int fd, struct xe_tile_info *tile_info)
+{
+ uint8_t iteration = 0;
+ uint8_t gt_id = 0;
+
+ igt_info("GT iteration\n");
+
+ for (int tile_id = 0; tile_id < tile_info->tile_count; tile_id++) {
+ for (gt_id += iteration; gt_id < tile_info->gt_count; gt_id++) {
+ if (tile_id == tile_info->gt_info[gt_id].tile_id) {
+ igt_info("GT :gt%d belongs to :tile%d\n",
+ tile_info->gt_info[gt_id].gt_id,
+ tile_info->gt_info[gt_id].tile_id);
+ iteration++;
+ }
+ else {
+ igt_info("GT :gt%d belongs to :tile%d\n",
+ tile_info->gt_info[gt_id].gt_id,
+ tile_info->gt_info[gt_id].tile_id);
+ continue;
+ }
+ }
+ }
+}
+
+static void igt_check_if_missingtile(int fd, struct xe_tile_info *tile_info)
+{
+ if (tile_info->mis_tile == true)
+ igt_warn("Missing :tile%d\n", tile_info->mis_tile_id);
+}
+
+static void igt_check_if_multitile(int fd, struct xe_tile_info *tile_info)
+{
+ igt_info("Check for Multi-tile support in Platform\n");
+
+ igt_skip_on_f(tile_info->tile_count == 0,
+ "No Tile :%d found in platform\n",
+ tile_info->tile_count);
+
+ if (tile_info->tile_count == 1)
+ igt_info("Single tile :tile%d found in platform\n",
+ tile_info->tile_count);
+ else {
+ igt_info("Tile count :%d in Multi-Tile platform\n",
+ tile_info->tile_count);
+
+ for (int tile_id = 0; tile_id < tile_info->tile_count; tile_id++)
+ igt_info("Tile :tile%d available in platform\n", tile_id);
+ }
+}
+
+static void igt_get_tile_info(int fd, struct drm_xe_query_gt_list *gt_list,
+ struct xe_tile_info *tile_info)
+{
+ uint8_t tile_mis_count = -1;
+ int prev_tile = -1, tile_id;
+
+ tile_info->tile_count = 0;
+ tile_info->mis_tile = false;
+ for (int index = 0; index < gt_list->num_gt; index++) {
+ tile_id = gt_list->gt_list[index].tile_id;
+ if (prev_tile != tile_id) {
+ if (++tile_mis_count != tile_id) {
+ tile_info->mis_tile = true;
+ tile_info->mis_tile_id = tile_mis_count;
+ tile_mis_count = tile_id;
+ }
+ prev_tile = tile_id;
+ tile_info->tile_count++;
+ tile_info->gt_info[index].tile_id = prev_tile;
+ tile_info->gt_info[index].gt_id = index;
+ }
+ else {
+ tile_info->gt_info[index].tile_id = tile_id;
+ tile_info->gt_info[index].gt_id = index;
+ }
+ tile_info->gt_info[index].type = xe_is_media_gt(fd, index);
+ }
+ tile_info->gt_count = gt_list->num_gt;
+}
+
+igt_main
+{
+ int fd;
+ struct xe_engine_list_entry *en;
+ struct drm_xe_engine_class_instance *hwe;
+ struct drm_xe_query_gt_list *gt_list;
+ struct xe_tile_info *tile_info;
+
+ tile_info = malloc(sizeof(*tile_info));
+ igt_assert(tile_info);
+
+ igt_fixture {
+ fd = drm_open_driver(DRIVER_XE);
+ xe_device_get(fd);
+ }
+
+ igt_subtest("multi-tile-info") {
+ gt_list = xe_gt_list(fd);
+
+ igt_get_tile_info(fd, gt_list, tile_info);
+ igt_check_if_multitile(fd, tile_info);
+ igt_check_if_missingtile(fd, tile_info);
+ igt_get_gt_info(fd, tile_info);
+ }
+
+ igt_fixture {
+ drm_close_driver(fd);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index 2724c7a9a..2cc01aa0c 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -292,6 +292,7 @@ intel_xe_progs = [
'xe_exec_reset',
'xe_exec_sip',
'xe_exec_store',
+ 'xe_multi_tile',
'xe_exec_threads',
'xe_exercise_blt',
'xe_fault_injection',
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* ✗ GitLab.Pipeline: warning for tests/intel/xe_multi_tile: Multi-Tile support in IGT
2025-01-31 14:27 [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT nishit.sharma
@ 2025-01-31 17:11 ` Patchwork
2025-02-05 22:26 ` [PATCH i-g-t] " Matt Roper
1 sibling, 0 replies; 8+ messages in thread
From: Patchwork @ 2025-01-31 17:11 UTC (permalink / raw)
To: nishit.sharma; +Cc: igt-dev
== Series Details ==
Series: tests/intel/xe_multi_tile: Multi-Tile support in IGT
URL : https://patchwork.freedesktop.org/series/144187/
State : warning
== Summary ==
Pipeline status: FAILED.
see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1355975 for the overview.
build:tests-debian-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/70348891):
[1/859] Generating version.h with a custom command.
[2/8] Linking target runner/runner_test.
[3/8] Linking target assembler/intel-gen4asm.
[4/8] Generating i915_tests.html with a custom command.
[5/8] Generating kms_tests.html with a custom command.
[6/8] Generating xe_tests.rst with a custom command.
FAILED: docs/testplan/xe_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/xe_test_config.json --rest docs/testplan/xe_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: igt@xe_multi_tile@show-tile-info Description documentation is missing
ERROR: Missing documentation for igt@xe_multi_tile@multi-tile-info
ERROR: Unneeded documentation for igt@xe_multi_tile@gt-configuration
ERROR: Unneeded documentation for igt@xe_multi_tile@show-tile-info
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1738343362:step_script
section_start:1738343362:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1738343363:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-debian-meson-arm64 has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/70348894):
section_start:1738343296:get_sources
Getting source from Git repository
$ /host/bin/curl -s -L --cacert /host/ca-certificates.crt --retry 4 -f --retry-delay 60 https://gitlab.freedesktop.org/freedesktop/helm-gitlab-infra/-/raw/main/runner-gating/runner-gating.sh | sh -s -- pre_get_sources_script
Checking if the user of the pipeline is allowed...
Checking if the job's project is part of a well-known group...
Thank you for contributing to freedesktop.org
Fetching changes...
Reinitialized existing Git repository in /builds/gfx-ci/igt-ci-tags/.git/
Checking out 106274bd as detached HEAD (ref is intel/IGTPW_12528)...
Skipping Git submodules setup
section_end:1738343313:get_sources
section_start:1738343313:step_script
Executing "step_script" stage of the job script
Using docker image sha256:7360075a71dacfc66f0b49b3271b9a459904dbe51c5760efac48fe52da27946c for registry.freedesktop.org/gfx-ci/igt-ci-tags/build-debian-arm64:commit-106274bd62425413b5147a712379f0d8fbd646d9 with digest registry.freedesktop.org/gfx-ci/igt-ci-tags/build-debian-arm64@sha256:df8438cd0e218646c3bdc2eb6abccb43c4e884bfd40a1a4dd0365f1f8031d21f ...
section_end:1738343316:step_script
section_start:1738343316:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1738343317:cleanup_file_variables
ERROR: Job failed (system failure): Error response from daemon: no such image: docker.io/library/sha256:7360075a71dacfc66f0b49b3271b9a459904dbe51c5760efac48fe52da27946c: image not known (docker.go:650:0s)
build:tests-fedora has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/70348886):
[1/861] Generating version.h with a custom command.
[2/7] Linking target runner/runner_test.
[3/7] Generating intel-ci-tests with a custom command.
[4/7] Generating i915_tests.html with a custom command.
[5/7] Generating kms_tests.html with a custom command.
[6/7] Generating xe_tests.rst with a custom command.
FAILED: docs/testplan/xe_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/xe_test_config.json --rest docs/testplan/xe_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: igt@xe_multi_tile@show-tile-info Description documentation is missing
ERROR: Missing documentation for igt@xe_multi_tile@multi-tile-info
ERROR: Unneeded documentation for igt@xe_multi_tile@gt-configuration
ERROR: Unneeded documentation for igt@xe_multi_tile@show-tile-info
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1738343401:step_script
section_start:1738343401:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1738343402:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-clang has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/70348890):
ninja: Entering directory `build'
[1/861] Generating version.h with a custom command.
[2/6] Generating i915_tests.html with a custom command.
[3/6] Generating intel-ci-tests with a custom command.
[4/6] Generating kms_tests.html with a custom command.
[5/6] Generating xe_tests.rst with a custom command.
FAILED: docs/testplan/xe_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/xe_test_config.json --rest docs/testplan/xe_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: igt@xe_multi_tile@show-tile-info Description documentation is missing
ERROR: Missing documentation for igt@xe_multi_tile@multi-tile-info
ERROR: Unneeded documentation for igt@xe_multi_tile@gt-configuration
ERROR: Unneeded documentation for igt@xe_multi_tile@show-tile-info
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1738343425:step_script
section_start:1738343425:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1738343425:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-no-libdrm-nouveau has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/70348889):
[1/809] Generating version.h with a custom command.
[2/7] Linking target runner/runner_test.
[3/7] Generating intel-ci-tests with a custom command.
[4/7] Generating i915_tests.html with a custom command.
[5/7] Generating kms_tests.html with a custom command.
[6/7] Generating xe_tests.rst with a custom command.
FAILED: docs/testplan/xe_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/xe_test_config.json --rest docs/testplan/xe_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: igt@xe_multi_tile@show-tile-info Description documentation is missing
ERROR: Missing documentation for igt@xe_multi_tile@multi-tile-info
ERROR: Unneeded documentation for igt@xe_multi_tile@gt-configuration
ERROR: Unneeded documentation for igt@xe_multi_tile@show-tile-info
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1738343366:step_script
section_start:1738343366:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1738343368:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-no-libunwind has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/70348887):
[1/861] Generating version.h with a custom command.
[2/7] Linking target runner/runner_test.
[3/7] Generating intel-ci-tests with a custom command.
[4/7] Generating kms_tests.html with a custom command.
[5/7] Generating i915_tests.html with a custom command.
[6/7] Generating xe_tests.rst with a custom command.
FAILED: docs/testplan/xe_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/xe_test_config.json --rest docs/testplan/xe_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: igt@xe_multi_tile@show-tile-info Description documentation is missing
ERROR: Missing documentation for igt@xe_multi_tile@multi-tile-info
ERROR: Unneeded documentation for igt@xe_multi_tile@gt-configuration
ERROR: Unneeded documentation for igt@xe_multi_tile@show-tile-info
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1738343410:step_script
section_start:1738343410:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1738343411:cleanup_file_variables
ERROR: Job failed: exit code 1
build:tests-fedora-oldest-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/70348888):
[1/861] Generating version.h with a custom command.
[2/7] Linking target runner/runner_test.
[3/7] Generating intel-ci-tests with a custom command.
[4/7] Generating i915_tests.html with a custom command.
[5/7] Generating kms_tests.html with a custom command.
[6/7] Generating xe_tests.rst with a custom command.
FAILED: docs/testplan/xe_tests.rst
/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py --config /builds/gfx-ci/igt-ci-tags/tests/intel/xe_test_config.json --rest docs/testplan/xe_tests.rst --check-testlist --igt-build-path /builds/gfx-ci/igt-ci-tags/build
Warning: igt@xe_multi_tile@show-tile-info Description documentation is missing
ERROR: Missing documentation for igt@xe_multi_tile@multi-tile-info
ERROR: Unneeded documentation for igt@xe_multi_tile@gt-configuration
ERROR: Unneeded documentation for igt@xe_multi_tile@show-tile-info
Please refer: docs/test_documentation.md for more details
ninja: build stopped: subcommand failed.
section_end:1738343407:step_script
section_start:1738343407:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1738343408:cleanup_file_variables
ERROR: Job failed: exit code 1
== Logs ==
For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1355975
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT
2025-01-31 14:27 [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT nishit.sharma
2025-01-31 17:11 ` ✗ GitLab.Pipeline: warning for " Patchwork
@ 2025-02-05 22:26 ` Matt Roper
1 sibling, 0 replies; 8+ messages in thread
From: Matt Roper @ 2025-02-05 22:26 UTC (permalink / raw)
To: nishit.sharma; +Cc: igt-dev, zbigniew.kempczynski
On Fri, Jan 31, 2025 at 02:27:12PM +0000, nishit.sharma@intel.com wrote:
> From: Nishit Sharma <nishit.sharma@intel.com>
>
> Added functionality to get Tile ID, GT ID, GT belongs to which tile ID
> in multi-tile/single-tile platforms. Added functionality to check if any
> tile_ID information not provided by driver. E.g.tile available in platforms in order tile0,
> tile1...tileX in serial order, If tile1 tile2 tile4...tileX populated
> than will get Warning tile3 not available.
>
> Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
> ---
> lib/igt_sysfs.c | 3 +-
> tests/intel/xe_multi_tile.c | 191 ++++++++++++++++++++++++++++++++++++
> tests/meson.build | 1 +
> 3 files changed, 194 insertions(+), 1 deletion(-)
> create mode 100644 tests/intel/xe_multi_tile.c
>
> diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
> index 00d5822fd..37f1716e2 100644
> --- a/lib/igt_sysfs.c
> +++ b/lib/igt_sysfs.c
> @@ -234,7 +234,8 @@ char *xe_sysfs_gt_path(int xe_device, int gt, char *path, int pathlen)
>
> if (IS_PONTEVECCHIO(intel_get_drm_devid(xe_device)))
> snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile%d/gt%d",
> - major(st.st_rdev), minor(st.st_rdev), gt, gt);
> + major(st.st_rdev), minor(st.st_rdev),
> + xe_gt_get_tile_id(xe_device, gt), gt);
> else
> snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile0/gt%d",
> major(st.st_rdev), minor(st.st_rdev), gt);
The fix for the library code should probably be a separate commit from
the new test being added since this will presumably change/fix existing
code.
> diff --git a/tests/intel/xe_multi_tile.c b/tests/intel/xe_multi_tile.c
> new file mode 100644
> index 000000000..7ca40f1fe
> --- /dev/null
> +++ b/tests/intel/xe_multi_tile.c
> @@ -0,0 +1,191 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2025 Intel Corporation
> + *
> + * Authors:
> + * Nishit Sharma <nishit.sharma@intel.com>
> + */
> +
> +#include <dirent.h>
> +#include <fcntl.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +
> +#include "igt.h"
> +#include "igt_sysfs.h"
> +
> +#include "xe_drm.h"
> +#include "xe/xe_ioctl.h"
> +#include "xe/xe_query.h"
> +
> +#define MAX_TILES 8
> +#define MAX_SLICES 2
> +
> +struct xe_gt_info {
> + /** @type: GT type: Main or Media */
> + uint16_t type;
> +
> + /** @tile_id: Tile ID where this GT lives (Information only) */
> + uint16_t tile_id;
> +
> + /** @gt_id: Unique ID of this GT within the PCI Device */
> + uint16_t gt_id;
> +};
> +
> +/** @info: tile-gt info */
> +struct xe_tile_info {
> + uint8_t tile_count;
> + uint8_t gt_count;
> + uint8_t mis_tile:1;
> + uint8_t mis_tile_id;
> + struct xe_gt_info gt_info[];
> +};
> +
> +/**
> + * TEST: Test to get tile_id by iterating gt on xe
> + * Category: Core
> + * Mega feature: General Core features
> + * Sub-category: mapping tile/s with slices available
> + * Functionality: gt operation
> + */
> +
> +/**
> + * SUBTEST: show-tile-info
> + * SUBTEST: gt-configuration
These don't seem to match the name of the subtest in the code
("multi-tile-info").
> + * Description: Test iniitialize xe_tile_info structure with tile_id
This doesn't really seem like a meaningful description since
'xe_tile_info' is just an internal structure used inside this test.
What is the actual goal/motivation here. Are you trying to verify that
the Xe query interface returns data correctly? Are you trying to
confirm that some kind of hardware behavior is sane? Are you trying to
confirm that different interfaces give consistent information (e.g.,
query ioctl vs sysfs)? It's hard to give feedback on the test when it
isn't clear what the primary goal is.
> + * Test category: functionality test
> + *
> + */
> +struct drm_xe_query_gt_list *xe_gt_list(int fd)
> +{
> + struct drm_xe_query_gt_list *gt_list;
> + struct drm_xe_device_query query = {
> + .extensions = 0,
> + .query = DRM_XE_DEVICE_QUERY_GT_LIST,
> + .size = 0,
> + .data = 0,
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
> + igt_assert_neq(query.size, 0);
> +
> + gt_list = malloc(query.size);
> + igt_assert(gt_list);
> +
> + query.data = to_user_pointer(gt_list);
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
> +
> + return gt_list;
> +}
Isn't this function basically the same as xe_query_gt_list_new()? Can't
we just call that instead?
> +
> +static void igt_get_gt_info(int fd, struct xe_tile_info *tile_info)
> +{
> + uint8_t iteration = 0;
> + uint8_t gt_id = 0;
> +
> + igt_info("GT iteration\n");
> +
> + for (int tile_id = 0; tile_id < tile_info->tile_count; tile_id++) {
> + for (gt_id += iteration; gt_id < tile_info->gt_count; gt_id++) {
> + if (tile_id == tile_info->gt_info[gt_id].tile_id) {
> + igt_info("GT :gt%d belongs to :tile%d\n",
> + tile_info->gt_info[gt_id].gt_id,
> + tile_info->gt_info[gt_id].tile_id);
> + iteration++;
> + }
> + else {
> + igt_info("GT :gt%d belongs to :tile%d\n",
> + tile_info->gt_info[gt_id].gt_id,
> + tile_info->gt_info[gt_id].tile_id);
> + continue;
> + }
> + }
> + }
> +}
Was this function supposed to do/return something? With a name like
this I expected it to return information to the caller, but it seems
like this just loops and prints some debug logging. If we removed this
function completely it wouldn't actually affect the test in any way.
> +
> +static void igt_check_if_missingtile(int fd, struct xe_tile_info *tile_info)
> +{
> + if (tile_info->mis_tile == true)
> + igt_warn("Missing :tile%d\n", tile_info->mis_tile_id);
> +}
> +
> +static void igt_check_if_multitile(int fd, struct xe_tile_info *tile_info)
> +{
> + igt_info("Check for Multi-tile support in Platform\n");
> +
> + igt_skip_on_f(tile_info->tile_count == 0,
> + "No Tile :%d found in platform\n",
> + tile_info->tile_count);
> +
> + if (tile_info->tile_count == 1)
> + igt_info("Single tile :tile%d found in platform\n",
> + tile_info->tile_count);
> + else {
> + igt_info("Tile count :%d in Multi-Tile platform\n",
> + tile_info->tile_count);
> +
> + for (int tile_id = 0; tile_id < tile_info->tile_count; tile_id++)
> + igt_info("Tile :tile%d available in platform\n", tile_id);
> + }
> +}
It seems like this is a lot of unnecessary debug logging; all we really
need is a skip at the callsite rather than a whole dedicated function to
do the same thing.
> +
> +static void igt_get_tile_info(int fd, struct drm_xe_query_gt_list *gt_list,
> + struct xe_tile_info *tile_info)
> +{
> + uint8_t tile_mis_count = -1;
> + int prev_tile = -1, tile_id;
> +
> + tile_info->tile_count = 0;
> + tile_info->mis_tile = false;
> + for (int index = 0; index < gt_list->num_gt; index++) {
> + tile_id = gt_list->gt_list[index].tile_id;
> + if (prev_tile != tile_id) {
> + if (++tile_mis_count != tile_id) {
> + tile_info->mis_tile = true;
> + tile_info->mis_tile_id = tile_mis_count;
> + tile_mis_count = tile_id;
> + }
> + prev_tile = tile_id;
> + tile_info->tile_count++;
> + tile_info->gt_info[index].tile_id = prev_tile;
> + tile_info->gt_info[index].gt_id = index;
> + }
> + else {
> + tile_info->gt_info[index].tile_id = tile_id;
> + tile_info->gt_info[index].gt_id = index;
> + }
> + tile_info->gt_info[index].type = xe_is_media_gt(fd, index);
> + }
> + tile_info->gt_count = gt_list->num_gt;
> +}
> +
> +igt_main
> +{
> + int fd;
> + struct xe_engine_list_entry *en;
> + struct drm_xe_engine_class_instance *hwe;
> + struct drm_xe_query_gt_list *gt_list;
> + struct xe_tile_info *tile_info;
> +
> + tile_info = malloc(sizeof(*tile_info));
> + igt_assert(tile_info);
> +
> + igt_fixture {
> + fd = drm_open_driver(DRIVER_XE);
> + xe_device_get(fd);
> + }
> +
> + igt_subtest("multi-tile-info") {
As noted above, this doesn't really seem to match what the test is
doing. It appears the goal of this test is to make sure that all tiles
have consecutive IDs, at least as far as we can see from the query
interface.
> + gt_list = xe_gt_list(fd);
> +
> + igt_get_tile_info(fd, gt_list, tile_info);
> + igt_check_if_multitile(fd, tile_info);
> + igt_check_if_missingtile(fd, tile_info);
> + igt_get_gt_info(fd, tile_info);
As noted above, this function doesn't do anything; we could just drop
it.
> + }
> +
Depending on what your goal is, should there be other tests here as
well? E.g., should we confirm that the query interface is consistent
with sysfs (no tile IDs reported in one that don't appear in the other)?
Is there anything else we should be checking?
Matt
> + igt_fixture {
> + drm_close_driver(fd);
> + }
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index 2724c7a9a..2cc01aa0c 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -292,6 +292,7 @@ intel_xe_progs = [
> 'xe_exec_reset',
> 'xe_exec_sip',
> 'xe_exec_store',
> + 'xe_multi_tile',
> 'xe_exec_threads',
> 'xe_exercise_blt',
> 'xe_fault_injection',
> --
> 2.34.1
>
--
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT
@ 2025-02-14 12:03 nishit.sharma
0 siblings, 0 replies; 8+ messages in thread
From: nishit.sharma @ 2025-02-14 12:03 UTC (permalink / raw)
To: igt-dev, nishit.sharma, matthew.d.roper
From: Nishit Sharma <nishit.sharma@intel.com>
Added functionality to check Multi-Tile available in system or not. Belonging to each Tile%d
GT%d gathered. Checked GT%d belongs to which tile%d in multi-tile/single-tile platforms.
Added functionality to check if any tile%d not provided by driver or missed.
E.g.tile available in platforms in order tile0, tile1...tileX in serial order, If
tile1 tile2 tile4...tileX populated than will get Warning tile3 not available.
Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
include/drm-uapi/xe_drm.h | 169 ++++++++++++--
lib/igt_sysfs.c | 3 +-
lib/xe/xe_query.h | 50 ++++-
tests/intel/xe_multi_tile.c | 433 ++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
5 files changed, 621 insertions(+), 35 deletions(-)
create mode 100644 tests/intel/xe_multi_tile.c
diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index 56163eb91..8b0869ce2 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -3,8 +3,8 @@
* Copyright © 2023 Intel Corporation
*/
-#ifndef _XE_DRM_H_
-#define _XE_DRM_H_
+#ifndef _UAPI_XE_DRM_H_
+#define _UAPI_XE_DRM_H_
#include "drm.h"
@@ -118,6 +118,12 @@ extern "C" {
#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
#define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
+enum xe_gt_type {
+ XE_GT_TYPE_UNINITIALIZED,
+ XE_GT_TYPE_MAIN,
+ XE_GT_TYPE_MEDIA,
+};
+
/**
* DOC: Xe IOCTL Extensions
*
@@ -227,6 +233,8 @@ struct drm_xe_ext_set_property {
* - %DRM_XE_ENGINE_CLASS_VM_BIND - Kernel only classes (not actual
* hardware engine class). Used for creating ordered queues of VM
* bind operations.
+ * - %DRM_XE_ENGINE_CLASS_EXT_DECODE - external decoder class
+ * - %DRM_XE_ENGINE_CLASS_EXT_ENCODE - external encoder class
*/
struct drm_xe_engine_class_instance {
#define DRM_XE_ENGINE_CLASS_RENDER 0
@@ -235,6 +243,8 @@ struct drm_xe_engine_class_instance {
#define DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE 3
#define DRM_XE_ENGINE_CLASS_COMPUTE 4
#define DRM_XE_ENGINE_CLASS_VM_BIND 5
+#define DRM_XE_ENGINE_CLASS_EXT_DECODE 6
+#define DRM_XE_ENGINE_CLASS_EXT_ENCODE 7
/** @engine_class: engine class id */
__u16 engine_class;
/** @engine_instance: engine instance id */
@@ -266,8 +276,8 @@ struct drm_xe_engine {
struct drm_xe_query_engines {
/** @num_engines: number of engines returned in @engines */
__u32 num_engines;
- /** @pad: MBZ */
- __u32 pad;
+ /** @num_ext_engines: num_ext_engines: number of engines returned at the end of @engines */
+ __u32 num_ext_engines;
/** @engines: The returned engines for this device */
struct drm_xe_engine engines[];
};
@@ -398,6 +408,7 @@ struct drm_xe_query_mem_regions {
* - %DRM_XE_QUERY_CONFIG_VA_BITS - Maximum bits of a virtual address
* - %DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY - Value of the highest
* available exec queue priority
+ * - %DRM_XE_QUERY_CONFIG_CXL_DEV_TYPE - CXL device type, 0 means CXL not supported
*/
struct drm_xe_query_config {
/** @num_params: number of parameters returned in info */
@@ -412,10 +423,96 @@ struct drm_xe_query_config {
#define DRM_XE_QUERY_CONFIG_MIN_ALIGNMENT 2
#define DRM_XE_QUERY_CONFIG_VA_BITS 3
#define DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY 4
+#define DRM_XE_QUERY_CONFIG_CXL_DEV_TYPE 5
/** @info: array of elements containing the config info */
__u64 info[];
};
+/**
+ * struct xe_gt - A "Graphics Technology" unit of the GPU
+ *
+ * A GT ("Graphics Technology") is the subset of a GPU primarily responsible
+ * for implementing the graphics, compute, and/or media IP.
+ *
+ */
+struct xe_gt {
+ /** @tile: Backpointer to GT's tile */
+ struct drm_xe_tile *tile;
+
+ /** @info: GT info */
+ struct {
+ /** @info.type: type of GT */
+ enum xe_gt_type type;
+ /** @info.id: Unique ID of this GT within the PCI Device */
+ __u8 id;
+
+ /**
+ * @gt_count: Number of GT/s available in tile
+ *
+ * */
+ __u8 gt_count;
+ } info;
+};
+
+/**
+ * struct drm_xe_tile - hardware tile structure
+ *
+ */
+struct drm_xe_tile {
+ /** @xe: Backpointer to tile's PCI device */
+ struct xe_device *xe;
+
+ /** @id: ID of the tile */
+ __u8 id;
+
+ /**
+ * @vram_id: ID of associated TTM VRAM region
+ *
+ * For multi-tile platforms not using unified vram, this is same
+ * as @id. Otherwise this is always 0 to denote a single unified
+ * vram region is in use.
+ */
+ __u8 vram_id;
+
+ /**
+ * @mis_tile: Flasg to check if tile ID missing or out of order
+ *
+ */
+ __u8 mis_tile:1;
+
+ /**
+ * @gt_count: Number of GT/s available in tile
+ *
+ * */
+ __u8 gt_count;
+
+ /**
+ * @primary_gt: Primary GT
+ */
+ struct xe_gt *primary_gt;
+
+ /**
+ * @media_gt: Media GT
+ *
+ * Only present on devices with media version >= 13.
+ */
+ struct xe_gt *media_gt;
+
+ /**
+ * @faked_gt: Faked GT
+ *
+ * Used for operations requiring GT on devices without GT at all.
+ * TODO: remove when FSW-10725 is done
+ */
+ struct xe_gt *faked_gt;
+
+ /**
+ * @gt_list: List of GT descriptors from driver
+ *
+ */
+ struct drm_xe_query_gt_list *gt_list;
+};
+
/**
* struct drm_xe_gt - describe an individual GT.
*
@@ -996,6 +1093,7 @@ struct drm_xe_vm_bind_op {
#define DRM_XE_VM_BIND_FLAG_IMMEDIATE (1 << 1)
#define DRM_XE_VM_BIND_FLAG_NULL (1 << 2)
#define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3)
+/* Bits 16-31 are reserved for prelim flags */
/** @flags: Bind flags */
__u32 flags;
@@ -1110,6 +1208,21 @@ struct drm_xe_exec_queue_create {
#define DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY 0
#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY 0
#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_TIMESLICE 1
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PREEMPTION_TIMEOUT 2
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PERSISTENCE 3
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_JOB_TIMEOUT 4
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_ACC_TRIGGER 5
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_ACC_NOTIFY 6
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_ACC_GRANULARITY 7
+/* Monitor 128KB contiguous region with 4K sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_128K 0
+/* Monitor 2MB contiguous region with 64KB sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_2M 1
+/* Monitor 16MB contiguous region with 512KB sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_16M 2
+/* Monitor 64MB contiguous region with 2M sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_64M 3
+#define DRM_XE_EXEC_QUEUE_EXTENSION_EXT_MEDIA_QUEUE 1
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
@@ -1123,7 +1236,13 @@ struct drm_xe_exec_queue_create {
/** @vm_id: VM to use for this exec queue */
__u32 vm_id;
- /** @flags: MBZ */
+ /*
+ * When creating exec queue in MSIX platforms, the user can request a unique MSIX interrupt
+ * for the irq handler. If there is no available MSIX, -EBUSY will be returned.
+ */
+#define DRM_XE_EXEC_QUEUE_CREATE_FLAG_UNIQUE_INTERRUPT_HINT (0x1 << 0)
+
+ /** @flags: create queue flags */
__u32 flags;
/** @exec_queue_id: Returned exec queue ID */
@@ -1254,6 +1373,25 @@ struct drm_xe_sync {
__u64 reserved[2];
};
+struct drm_xe_ext_media_queue_create {
+ /** @base: base user extension */
+ struct drm_xe_user_extension base;
+ /** @instance_mask: mask of all external decoders and encoders used by the queue */
+ __u64 instance_mask;
+ /** @csm_addr: control shared memory address */
+ __u64 csm_addr;
+ /** @csm_size: control shared memory size */
+ __u64 csm_size;
+ /** cb_base_addr: command buffer base address */
+ __u64 cb_base_addr;
+ /** cb_size: command buffer size */
+ __u64 cb_size;
+ /** doorbell_handle: doorbell handle */
+ __u64 doorbell_handle;
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+};
+
/**
* struct drm_xe_exec - Input of &DRM_IOCTL_XE_EXEC
*
@@ -1485,7 +1623,6 @@ struct drm_xe_oa_unit {
/** @capabilities: OA capabilities bit-mask */
__u64 capabilities;
#define DRM_XE_OA_CAPS_BASE (1 << 0)
-#define DRM_XE_OA_CAPS_SYNCS (1 << 1)
/** @oa_timestamp_freq: OA timestamp freq */
__u64 oa_timestamp_freq;
@@ -1635,22 +1772,6 @@ enum drm_xe_oa_property_id {
* to be disabled for the stream exec queue.
*/
DRM_XE_OA_PROPERTY_NO_PREEMPT,
-
- /**
- * @DRM_XE_OA_PROPERTY_NUM_SYNCS: Number of syncs in the sync array
- * specified in @DRM_XE_OA_PROPERTY_SYNCS
- */
- DRM_XE_OA_PROPERTY_NUM_SYNCS,
-
- /**
- * @DRM_XE_OA_PROPERTY_SYNCS: Pointer to struct @drm_xe_sync array
- * with array size specified via @DRM_XE_OA_PROPERTY_NUM_SYNCS. OA
- * configuration will wait till input fences signal. Output fences
- * will signal after the new OA configuration takes effect. For
- * @DRM_XE_SYNC_TYPE_USER_FENCE, @addr is a user pointer, similar
- * to the VM bind case.
- */
- DRM_XE_OA_PROPERTY_SYNCS,
};
/**
@@ -1713,8 +1834,10 @@ struct drm_xe_oa_stream_info {
__u64 reserved[3];
};
+#include "xe_drm_prelim.h"
+
#if defined(__cplusplus)
}
#endif
-#endif /* _XE_DRM_H_ */
+#endif /* _UAPI_XE_DRM_H_ */
diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
index 00d5822fd..37f1716e2 100644
--- a/lib/igt_sysfs.c
+++ b/lib/igt_sysfs.c
@@ -234,7 +234,8 @@ char *xe_sysfs_gt_path(int xe_device, int gt, char *path, int pathlen)
if (IS_PONTEVECCHIO(intel_get_drm_devid(xe_device)))
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile%d/gt%d",
- major(st.st_rdev), minor(st.st_rdev), gt, gt);
+ major(st.st_rdev), minor(st.st_rdev),
+ xe_gt_get_tile_id(xe_device, gt), gt);
else
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile0/gt%d",
major(st.st_rdev), minor(st.st_rdev), gt);
diff --git a/lib/xe/xe_query.h b/lib/xe/xe_query.h
index 30ea5ad41..e325608e0 100644
--- a/lib/xe/xe_query.h
+++ b/lib/xe/xe_query.h
@@ -15,27 +15,42 @@
#include "igt_aux.h"
#include "igt_list.h"
#include "igt_sizes.h"
-#include "intel_hwconfig_types.h"
#define XE_DEFAULT_ALIGNMENT SZ_4K
#define XE_DEFAULT_ALIGNMENT_64K SZ_64K
struct xe_device {
+#define XE_MAX_TILES_PER_DEVICE 4
/** @fd: xe fd */
int fd;
/** @config: xe configuration */
struct drm_xe_query_config *config;
- /** @hwconfig: xe hwconfig table data */
- uint32_t *hwconfig;
-
- /** @hwconfig_size: size of hwconfig in bytes */
- uint32_t hwconfig_size;
-
/** @gt_list: gt info */
struct drm_xe_query_gt_list *gt_list;
+ /** @tiles: device tiles */
+ struct drm_xe_tile tiles[XE_MAX_TILES_PER_DEVICE];
+
+ /** @info: device info */
+ struct drm_xe_tile_info {
+ /** @info.tile_count: Number of tiles */
+ uint8_t tile_count;
+ /** @info.gt_count: Total number of GTs for entire device */
+ uint8_t gt_count;
+ /** @tile_unvailable: Flag to check if tile is missing or out of order */
+ uint8_t tile_unavailable:1;
+ /** @mis_tile: Tile ID missing or out of order */
+ uint8_t mis_tile_id[XE_MAX_TILES_PER_DEVICE];
+ /** @mis_tile_count: missing TIle ID **/
+ uint8_t mis_tile_count;
+ /** @info.graphics_verx100: graphics IP version */
+ __u32 graphics_verx100;
+ /** @info.media_verx100: media IP version */
+ __u32 media_verx100;
+ } info;
+
/** @gt_list: bitmask of all memory regions */
uint64_t memory_regions;
@@ -75,20 +90,34 @@ struct xe_device {
++__class)
#define xe_for_each_gt(__fd, __gt) \
for (__gt = 0; __gt < xe_number_gt(__fd); ++__gt)
-
+#define xe_for_each_tile(tile__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
+ for_each_if((tile__) = &(xe__)->tiles[(id__)])
+#define xe_for_each_remote_tile(tile__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
+ for_each_if((tile__) = &(xe__)->tiles[(id__)])
+#define xe_for_each_device_gt(gt__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.gt_count; (id__)++) \
+ for_each_if((gt__) = xe_device_get_gt((xe__), (id__)))
#define xe_for_each_mem_region(__fd, __memreg, __r) \
for (uint64_t igt_unique(__i) = 0; igt_unique(__i) < igt_fls(__memreg); igt_unique(__i)++) \
for_if(__r = (__memreg & (1ull << igt_unique(__i))))
#define XE_IS_CLASS_SYSMEM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_SYSMEM)
#define XE_IS_CLASS_VRAM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_VRAM)
-
+#define MEDIA_VER(xe) ((xe)->info.media_verx100 / 100)
/*
* Max possible engine instance in drm_xe_engine_class_instance::engine_instance. Only
* used to declare arrays of drm_xe_engine_class_instance
*/
#define XE_MAX_ENGINE_INSTANCE 9
+/*
+ * Max possible GT per Tile
+ *
+ */
+#define XE_MAX_GT_PER_TILE 2
+
unsigned int xe_number_gt(int fd);
uint64_t all_memory_regions(int fd);
uint64_t system_memory(int fd);
@@ -115,13 +144,12 @@ uint16_t xe_dev_id(int fd);
int xe_supports_faults(int fd);
const char *xe_engine_class_string(uint32_t engine_class);
bool xe_has_engine_class(int fd, uint16_t engine_class);
-struct drm_xe_engine *xe_find_engine_by_class(int fd, uint16_t engine_class);
bool xe_has_media_gt(int fd);
bool xe_is_media_gt(int fd, int gt);
uint16_t xe_gt_get_tile_id(int fd, int gt);
-uint32_t *xe_hwconfig_lookup_value(int fd, enum intel_hwconfig attribute, uint32_t *len);
struct xe_device *xe_device_get(int fd);
void xe_device_put(int fd);
+struct xe_gt *xe_device_get_gt(struct xe_device *xe, uint8_t gt_id);
#endif /* XE_QUERY_H */
diff --git a/tests/intel/xe_multi_tile.c b/tests/intel/xe_multi_tile.c
new file mode 100644
index 000000000..2b3151b7e
--- /dev/null
+++ b/tests/intel/xe_multi_tile.c
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ *
+ * Authors:
+ * Nishit Sharma <nishit.sharma@intel.com>
+ */
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "igt.h"
+#include "igt_sysfs.h"
+
+#include "xe_drm.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+
+/**
+ * TEST: Test to verify if multi-tile support available in platform
+ * by verifying Tile IDs and filling internal structs
+ * required to process user requests like getting GT ID
+ * gt%d belongs to which Tile%d
+ * Category: Core
+ * Mega feature: General Core features
+ * Functionality: Tile/GT operations
+ */
+
+/**
+ * SUBTEST: multi-tile-info
+ * Description: Test gathers Tile_ID/s and GT_ID/s and set internal
+ * structures required for operations
+ * Test category: functionality test
+ *
+ */
+
+/*
+ * xe_gt_list: Get the list of gt%d, tile%d and count
+ * from driver using IOCTL
+ * @fd: GPU device descriptor
+ *
+ * Function gets the list of gt%d and tile%d available in device
+ * including other information such as gt count, graphics ip version
+ *
+ * Return: Returns drm_xe_query_gt_list pointer which have
+ * list of gt%d and tile%d available
+ */
+struct drm_xe_query_gt_list *xe_gt_list(int fd)
+{
+ struct drm_xe_query_gt_list *gt_list;
+ struct drm_xe_device_query query = {
+ .extensions = 0,
+ .query = DRM_XE_DEVICE_QUERY_GT_LIST,
+ .size = 0,
+ .data = 0,
+ };
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+ igt_assert_neq(query.size, 0);
+
+ gt_list = malloc(query.size);
+ igt_assert(gt_list);
+
+ query.data = to_user_pointer(gt_list);
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+
+ return gt_list;
+}
+/*
+ * xe_gt_alloc: Memory allocation for gt%d and initializing
+ * struct drm_xe_tile as per gt%d
+ * @tile *: Holds gt informations such as GT_ID and Tile_ID
+ *
+ * This allocates memory per GT available on tile and assigns corresponding tile address
+ * to corresponding gt
+ *
+ * Return: Returns gt structure
+ */
+struct xe_gt *xe_gt_alloc(struct drm_xe_tile *tile)
+{
+ struct xe_gt *gt;
+
+ gt = malloc(sizeof(*gt));
+ igt_assert(gt);
+
+ gt->tile = tile;
+ return gt;
+}
+/**
+ * xe_tile_init - Initialize the tile and allocates memmory for primary GT
+ * @tile: Tile to initialize
+ * @xe: Parent Xe device
+ * @id: Tile ID
+ *
+ * Initializes per-tile resources that don't require any interactions with the
+ * hardware or any knowledge about the Graphics/Media IP version.
+ *
+ * Returns: 0 on success, assert if no memory allocation.
+ */
+int xe_tile_init(struct drm_xe_tile *tile, struct xe_device *xe, uint8_t id)
+{
+ tile->xe = xe;
+ tile->id = id;
+
+ tile->primary_gt = xe_gt_alloc(tile);
+ igt_assert(tile->primary_gt);
+
+ return 0;
+}
+/**
+ * xe_device_get_root_tile: Returns address of root tile
+ * @xe: GPU Device strcuture which holds information about tile
+ * available in system
+ *
+ * Return: root tile address
+ */
+struct xe_tile *xe_device_get_root_tile(struct xe_device *xe)
+{
+ return &xe->tiles[0];
+}
+/**
+ * xe_tile_get_gt: Return xe_gt address
+ * @tile *: Tile associated with gt
+ * @gt_id: gt%d
+ *
+ * Returns: Based on gt_id passed xe_gt address returned which
+ * can be media_gt or primary gt
+ */
+struct xe_gt *xe_tile_get_gt(struct drm_xe_tile *tile, u8 gt_id)
+{
+ igt_assert_f(gt_id <= XE_MAX_GT_PER_TILE, "gt_id greater than defined XE_MAX_GT_PER_TILE");
+
+ return gt_id ? tile->media_gt : tile->primary_gt;
+}
+/**
+ * @xe_dev: GPU device address
+ * @gt_id: gt%d
+ *
+ * Returns: xe_gt address based on media version available in platform
+ */
+struct xe_gt *xe_device_get_gt(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ struct drm_xe_tile *root_tile = xe_device_get_root_tile(xe_dev);
+ struct xe_gt *gt;
+
+ if (MEDIA_VER(xe_dev) >= 13)
+ gt = xe_tile_get_gt(root_tile, gt_id);
+ else
+ gt = xe_dev->tiles[gt_id].primary_gt;
+
+ igt_assert(gt);
+
+ return gt;
+}
+/**
+ * @xe_dev: GPU device structure
+ * @gt_id: gt%d
+ *
+ * Check gt%d passed available on tile%d or not available
+ *
+ * Return: None
+ */
+static void igt_check_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ uint8_t id;
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ xe_for_each_device_gt(gt, xe_dev, id) {
+ tile = gt->tile;
+ if(gt_id == gt->info.id)
+ igt_info("GT ID :%d available in Tile :tile%d\n",
+ gt_id, tile->id);
+ else
+ igt_info("GT ID :%d not available in Tile :tile%d\n",
+ gt_id, tile->id);
+ }
+}
+/**
+ * @xe_dev: GPU device structure
+ * @gt_id: gt%d
+ *
+ * To query gt%d available in tile%d by iterating over list of tiles available
+ *
+ * Returns: 0
+ */
+static uint8_t igt_query_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ gt = tile->primary_gt;
+ igt_info("Inside GT Id :%d GT type :%d GT count :%d for Tile ID :%d GT count in Tile :%d\n",
+ gt->info.id, gt->info.type, gt->info.gt_count, tile->id, tile->gt_count);
+
+ if(MEDIA_VER(xe_dev) >= 13)
+ {
+ gt = tile->media_gt;
+ igt_info("Inside GT Id :%d GT type :%d GT count :%d for Tile ID :%d GT count in Tile :%d\n",
+ gt->info.id, gt->info.type, gt->info.gt_count, tile->id, tile->gt_count);
+ }
+ }
+
+ return 0;
+}
+/**
+ * igt_show_device_gt: To show gt availale on GPU device
+ * @xe_dev: GPU device structure
+ * @fd: GPU device descriptor
+ *
+ * Show GT%d available on device
+ *
+ * Return: None
+ */
+static void igt_show_device_gt(struct xe_device *xe_dev, int fd)
+{
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ uint8_t id;
+
+ xe_for_each_device_gt(gt, xe_dev, id) {
+ tile = gt->tile;
+ igt_info("GT Id :%d GT type :%d Tile ID :%d\n",
+ gt->info.id, gt->info.type, tile->id);
+ }
+}
+/**
+ * igt_gt_init_per_tile: Initialize xe_gt structure per gt%d and per tile%d
+ * Memory allocation for each tile and based on media version
+ * if available on device xe_gt structure initialized and assigned
+ * to tile%d
+ * @xe_dev: GPU device structure
+ * @fd: GPU device descriptor
+ *
+ * Returns: 0 in case of success or assert
+ */
+static uint8_t igt_gt_init_per_tile(struct xe_device *xe_dev, int fd)
+{
+ uint8_t gt_id = 0;
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt, *prev_gt = NULL, *new_gt;
+ int ip_version, media_version;
+ char name[100];
+
+ igt_info("per Tile initialization\n");
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ int err;
+ err = xe_tile_init(tile, xe_dev, gt_id);
+ igt_assert_eq(err, 0);
+ }
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ gt = tile->primary_gt;
+ new_gt = gt;
+ gt->info.id = xe_dev->info.gt_count++;
+ gt->info.type= XE_GT_TYPE_MAIN;
+ gt->info.gt_count++;
+ tile->gt_count++;
+
+ FILE *file = fopen("/sys/kernel/debug/dri/0/info", "r");
+ igt_assert(file);
+
+ while (fscanf(file, "%s %d", name, &ip_version) == 1) {
+ ip_version = -1;
+ }
+ while (fscanf(file, "%s %d", name, &media_version) == 1) {
+ media_version = -1;
+ }
+
+ fclose(file);
+
+ xe_dev->info.graphics_verx100 = ip_version;
+ xe_dev->info.media_verx100 = media_version;
+
+ if (MEDIA_VER(xe_dev) < 13)
+ continue;
+
+ /*
+ * Allocate and setup media GT for platforms with standalone
+ * media.
+ *
+ */
+ tile->media_gt = xe_gt_alloc(tile);
+ igt_assert(tile->media_gt);
+ gt->info.type = XE_GT_TYPE_MEDIA;
+ gt->info.id = xe_dev->info.gt_count++;
+ gt->info.gt_count++;
+ tile->gt_count++;
+ }
+
+ return 0;
+}
+/**
+ * igt_check_missing_tile_sysfs: Checking if tile missing or out of order in system
+ * @xe_device: fd of the device
+ * @fd: Device descriptor
+ *
+ * This opens the sysfs tile directory corresponding to device and tile for use
+ * The mis_tile_id[] contains tile%d which is checked with sysfs whether entry is present
+ * or not. E.g. After tile2 user get tile4, tile3 is missing which will be checked in sysfs path
+ *
+ * Returns: None
+ */
+static void igt_check_missing_tile_sysfs(struct xe_device *xe_dev,
+ int fd)
+{
+ char path[96];
+
+ igt_info("Checking missing tiles with sysfs\n");
+
+ for(int mis = 0; mis < xe_dev->info.mis_tile_count; mis++) {
+ xe_sysfs_tile_path(fd, xe_dev->info.mis_tile_id[mis], path, sizeof(path));
+ }
+
+ igt_assert_f(xe_dev->info.mis_tile_count < 0, "No Tile entry in sysfs found.");
+}
+/**
+ * igt_check_if_missingtile: Checking if tile missing by iterating over
+ * filled mis tile array
+ * @xe_dev: GPU device structure
+ * fd: GPU device descriptor
+ *
+ * Returns: None
+ */
+static void igt_check_if_missingtile(struct xe_device *xe_dev, int fd)
+{
+ igt_info("Checking missing/out of order tiles\n");
+
+ for(int i= 0; i < xe_dev->info.mis_tile_count; i++){
+ igt_warn("Tile :%d out of order/missing\n",
+ xe_dev->info.mis_tile_id[i]);
+ }
+}
+/**
+ * igt_get_tile_count: To get count of tile/s available in system,
+ * Getting missing tile and tle count if any
+ * @xe_dev: Device structure
+ * @fd: Device descriptor
+ * gt_list: list of gt%d and relavant information returned from Driver via IOCTL
+ *
+ * Return: Tile count
+ */
+static uint8_t igt_get_tile_count(struct xe_device *xe_dev, int fd,
+ struct drm_xe_query_gt_list *gt_list)
+{
+ int prev_tile = -1, tile_id;
+ uint8_t tile_mis_count = -1;
+
+ for(int index = 0; index < gt_list->num_gt; index++) {
+ tile_id = gt_list->gt_list[index].tile_id;
+ if(prev_tile != tile_id)
+ {
+ if(++tile_mis_count != tile_id) {
+ xe_dev->info.tile_unavailable = true;
+ xe_dev->info.mis_tile_id[xe_dev->info.mis_tile_count++] = tile_mis_count;
+ }
+ prev_tile = tile_id;
+ xe_dev->info.tile_count++;
+ }
+ xe_dev->info.tile_unavailable = false;
+ }
+
+ return xe_dev->info.tile_count;
+}
+
+igt_main
+{
+ int fd;
+ struct drm_xe_query_gt_list *gt_list;
+ struct xe_device *xe_dev;
+ struct drm_xe_tile *tile;
+ uint8_t gt_count;
+ uint8_t gt_arr[] = {0,1,2,3,4,5,6,7,8};
+
+ igt_fixture {
+ fd = drm_open_driver(DRIVER_XE);
+ xe_dev = xe_device_get(fd);
+ }
+
+ tile = malloc(sizeof(*tile));
+ igt_assert(tile);
+
+ igt_subtest("multi-tile-info") {
+ igt_require(IS_FS1(intel_get_drm_devid(fd)));
+ /** get gt information from driver using ioctl **/
+ gt_list = xe_gt_list(fd);
+ /** store pointer returned from driver which have gt information **/
+ tile->gt_list = gt_list;
+
+ /** Get tile count, initialize flag to check if any tile missing
+ * Fill internal struct
+ */
+ gt_count = igt_get_tile_count(xe_dev, fd, gt_list);
+ igt_assert_neq(gt_count, 0);
+ igt_info("Tiles :%d available in platform\n", gt_count);
+
+ /** check if multi-tile supported in platform */
+ igt_assert_f(xe_dev->info.tile_count > 1,
+ "Multi-Tile not supported in platform :%d\n",
+ xe_dev->info.tile_count);
+
+ /************* Per Tile Initilization ***********/
+ igt_assert_eq(igt_gt_init_per_tile(xe_dev, fd), 0);
+
+ /******** Condition to check if any tile missing/out of order *****/
+ if (xe_dev->info.tile_unavailable)
+ igt_check_if_missingtile(xe_dev, fd);
+
+ /******* Checking missing/out of order tile comparing with sysfs ***/
+ if (xe_dev->info.tile_unavailable)
+ igt_check_missing_tile_sysfs(xe_dev, fd);
+
+ /****** Display GT information on GPU Device *******/
+ igt_show_device_gt(xe_dev, fd);
+
+ /****** Query GT per Tile *****/
+ igt_query_gt_per_tile(xe_dev, fd);
+
+ /***** Checking GT exist, if exist on which tile or doesn't exist ******/
+ for(int gt_id = 0; gt_id < sizeof(gt_arr); gt_id++)
+ igt_check_gt_per_tile(xe_dev, gt_id);
+ }
+
+ igt_fixture {
+ drm_close_driver(fd);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index 2724c7a9a..2cc01aa0c 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -292,6 +292,7 @@ intel_xe_progs = [
'xe_exec_reset',
'xe_exec_sip',
'xe_exec_store',
+ 'xe_multi_tile',
'xe_exec_threads',
'xe_exercise_blt',
'xe_fault_injection',
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT
@ 2025-02-15 1:11 nishit.sharma
2025-02-17 14:20 ` Kamil Konieczny
0 siblings, 1 reply; 8+ messages in thread
From: nishit.sharma @ 2025-02-15 1:11 UTC (permalink / raw)
To: igt-dev, nishit.sharma, matthew.d.roper
From: Nishit Sharma <nishit.sharma@intel.com>
Added functionality to check Multi-Tile available in system or not. Belonging to each Tile%d
GT%d gathered. Checked GT%d belongs to which tile%d in multi-tile/single-tile platforms.
Added functionality to check if any tile%d not provided by driver or missed.
E.g.tile available in platforms in order tile0, tile1...tileX in serial order, If
tile1 tile2 tile4...tileX populated than will get Warning tile3 not available.
Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
include/drm-uapi/xe_drm.h | 169 ++++++++++++--
lib/igt_sysfs.c | 3 +-
lib/xe/xe_query.h | 50 ++++-
tests/intel/xe_multi_tile.c | 432 ++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
5 files changed, 620 insertions(+), 35 deletions(-)
create mode 100644 tests/intel/xe_multi_tile.c
diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index 56163eb91..8b0869ce2 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -3,8 +3,8 @@
* Copyright © 2023 Intel Corporation
*/
-#ifndef _XE_DRM_H_
-#define _XE_DRM_H_
+#ifndef _UAPI_XE_DRM_H_
+#define _UAPI_XE_DRM_H_
#include "drm.h"
@@ -118,6 +118,12 @@ extern "C" {
#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
#define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
+enum xe_gt_type {
+ XE_GT_TYPE_UNINITIALIZED,
+ XE_GT_TYPE_MAIN,
+ XE_GT_TYPE_MEDIA,
+};
+
/**
* DOC: Xe IOCTL Extensions
*
@@ -227,6 +233,8 @@ struct drm_xe_ext_set_property {
* - %DRM_XE_ENGINE_CLASS_VM_BIND - Kernel only classes (not actual
* hardware engine class). Used for creating ordered queues of VM
* bind operations.
+ * - %DRM_XE_ENGINE_CLASS_EXT_DECODE - external decoder class
+ * - %DRM_XE_ENGINE_CLASS_EXT_ENCODE - external encoder class
*/
struct drm_xe_engine_class_instance {
#define DRM_XE_ENGINE_CLASS_RENDER 0
@@ -235,6 +243,8 @@ struct drm_xe_engine_class_instance {
#define DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE 3
#define DRM_XE_ENGINE_CLASS_COMPUTE 4
#define DRM_XE_ENGINE_CLASS_VM_BIND 5
+#define DRM_XE_ENGINE_CLASS_EXT_DECODE 6
+#define DRM_XE_ENGINE_CLASS_EXT_ENCODE 7
/** @engine_class: engine class id */
__u16 engine_class;
/** @engine_instance: engine instance id */
@@ -266,8 +276,8 @@ struct drm_xe_engine {
struct drm_xe_query_engines {
/** @num_engines: number of engines returned in @engines */
__u32 num_engines;
- /** @pad: MBZ */
- __u32 pad;
+ /** @num_ext_engines: num_ext_engines: number of engines returned at the end of @engines */
+ __u32 num_ext_engines;
/** @engines: The returned engines for this device */
struct drm_xe_engine engines[];
};
@@ -398,6 +408,7 @@ struct drm_xe_query_mem_regions {
* - %DRM_XE_QUERY_CONFIG_VA_BITS - Maximum bits of a virtual address
* - %DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY - Value of the highest
* available exec queue priority
+ * - %DRM_XE_QUERY_CONFIG_CXL_DEV_TYPE - CXL device type, 0 means CXL not supported
*/
struct drm_xe_query_config {
/** @num_params: number of parameters returned in info */
@@ -412,10 +423,96 @@ struct drm_xe_query_config {
#define DRM_XE_QUERY_CONFIG_MIN_ALIGNMENT 2
#define DRM_XE_QUERY_CONFIG_VA_BITS 3
#define DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY 4
+#define DRM_XE_QUERY_CONFIG_CXL_DEV_TYPE 5
/** @info: array of elements containing the config info */
__u64 info[];
};
+/**
+ * struct xe_gt - A "Graphics Technology" unit of the GPU
+ *
+ * A GT ("Graphics Technology") is the subset of a GPU primarily responsible
+ * for implementing the graphics, compute, and/or media IP.
+ *
+ */
+struct xe_gt {
+ /** @tile: Backpointer to GT's tile */
+ struct drm_xe_tile *tile;
+
+ /** @info: GT info */
+ struct {
+ /** @info.type: type of GT */
+ enum xe_gt_type type;
+ /** @info.id: Unique ID of this GT within the PCI Device */
+ __u8 id;
+
+ /**
+ * @gt_count: Number of GT/s available in tile
+ *
+ * */
+ __u8 gt_count;
+ } info;
+};
+
+/**
+ * struct drm_xe_tile - hardware tile structure
+ *
+ */
+struct drm_xe_tile {
+ /** @xe: Backpointer to tile's PCI device */
+ struct xe_device *xe;
+
+ /** @id: ID of the tile */
+ __u8 id;
+
+ /**
+ * @vram_id: ID of associated TTM VRAM region
+ *
+ * For multi-tile platforms not using unified vram, this is same
+ * as @id. Otherwise this is always 0 to denote a single unified
+ * vram region is in use.
+ */
+ __u8 vram_id;
+
+ /**
+ * @mis_tile: Flasg to check if tile ID missing or out of order
+ *
+ */
+ __u8 mis_tile:1;
+
+ /**
+ * @gt_count: Number of GT/s available in tile
+ *
+ * */
+ __u8 gt_count;
+
+ /**
+ * @primary_gt: Primary GT
+ */
+ struct xe_gt *primary_gt;
+
+ /**
+ * @media_gt: Media GT
+ *
+ * Only present on devices with media version >= 13.
+ */
+ struct xe_gt *media_gt;
+
+ /**
+ * @faked_gt: Faked GT
+ *
+ * Used for operations requiring GT on devices without GT at all.
+ * TODO: remove when FSW-10725 is done
+ */
+ struct xe_gt *faked_gt;
+
+ /**
+ * @gt_list: List of GT descriptors from driver
+ *
+ */
+ struct drm_xe_query_gt_list *gt_list;
+};
+
/**
* struct drm_xe_gt - describe an individual GT.
*
@@ -996,6 +1093,7 @@ struct drm_xe_vm_bind_op {
#define DRM_XE_VM_BIND_FLAG_IMMEDIATE (1 << 1)
#define DRM_XE_VM_BIND_FLAG_NULL (1 << 2)
#define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3)
+/* Bits 16-31 are reserved for prelim flags */
/** @flags: Bind flags */
__u32 flags;
@@ -1110,6 +1208,21 @@ struct drm_xe_exec_queue_create {
#define DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY 0
#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY 0
#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_TIMESLICE 1
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PREEMPTION_TIMEOUT 2
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PERSISTENCE 3
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_JOB_TIMEOUT 4
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_ACC_TRIGGER 5
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_ACC_NOTIFY 6
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_ACC_GRANULARITY 7
+/* Monitor 128KB contiguous region with 4K sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_128K 0
+/* Monitor 2MB contiguous region with 64KB sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_2M 1
+/* Monitor 16MB contiguous region with 512KB sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_16M 2
+/* Monitor 64MB contiguous region with 2M sub-granularity */
+#define DRM_XE_ACC_GRANULARITY_64M 3
+#define DRM_XE_EXEC_QUEUE_EXTENSION_EXT_MEDIA_QUEUE 1
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
@@ -1123,7 +1236,13 @@ struct drm_xe_exec_queue_create {
/** @vm_id: VM to use for this exec queue */
__u32 vm_id;
- /** @flags: MBZ */
+ /*
+ * When creating exec queue in MSIX platforms, the user can request a unique MSIX interrupt
+ * for the irq handler. If there is no available MSIX, -EBUSY will be returned.
+ */
+#define DRM_XE_EXEC_QUEUE_CREATE_FLAG_UNIQUE_INTERRUPT_HINT (0x1 << 0)
+
+ /** @flags: create queue flags */
__u32 flags;
/** @exec_queue_id: Returned exec queue ID */
@@ -1254,6 +1373,25 @@ struct drm_xe_sync {
__u64 reserved[2];
};
+struct drm_xe_ext_media_queue_create {
+ /** @base: base user extension */
+ struct drm_xe_user_extension base;
+ /** @instance_mask: mask of all external decoders and encoders used by the queue */
+ __u64 instance_mask;
+ /** @csm_addr: control shared memory address */
+ __u64 csm_addr;
+ /** @csm_size: control shared memory size */
+ __u64 csm_size;
+ /** cb_base_addr: command buffer base address */
+ __u64 cb_base_addr;
+ /** cb_size: command buffer size */
+ __u64 cb_size;
+ /** doorbell_handle: doorbell handle */
+ __u64 doorbell_handle;
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+};
+
/**
* struct drm_xe_exec - Input of &DRM_IOCTL_XE_EXEC
*
@@ -1485,7 +1623,6 @@ struct drm_xe_oa_unit {
/** @capabilities: OA capabilities bit-mask */
__u64 capabilities;
#define DRM_XE_OA_CAPS_BASE (1 << 0)
-#define DRM_XE_OA_CAPS_SYNCS (1 << 1)
/** @oa_timestamp_freq: OA timestamp freq */
__u64 oa_timestamp_freq;
@@ -1635,22 +1772,6 @@ enum drm_xe_oa_property_id {
* to be disabled for the stream exec queue.
*/
DRM_XE_OA_PROPERTY_NO_PREEMPT,
-
- /**
- * @DRM_XE_OA_PROPERTY_NUM_SYNCS: Number of syncs in the sync array
- * specified in @DRM_XE_OA_PROPERTY_SYNCS
- */
- DRM_XE_OA_PROPERTY_NUM_SYNCS,
-
- /**
- * @DRM_XE_OA_PROPERTY_SYNCS: Pointer to struct @drm_xe_sync array
- * with array size specified via @DRM_XE_OA_PROPERTY_NUM_SYNCS. OA
- * configuration will wait till input fences signal. Output fences
- * will signal after the new OA configuration takes effect. For
- * @DRM_XE_SYNC_TYPE_USER_FENCE, @addr is a user pointer, similar
- * to the VM bind case.
- */
- DRM_XE_OA_PROPERTY_SYNCS,
};
/**
@@ -1713,8 +1834,10 @@ struct drm_xe_oa_stream_info {
__u64 reserved[3];
};
+#include "xe_drm_prelim.h"
+
#if defined(__cplusplus)
}
#endif
-#endif /* _XE_DRM_H_ */
+#endif /* _UAPI_XE_DRM_H_ */
diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
index 00d5822fd..37f1716e2 100644
--- a/lib/igt_sysfs.c
+++ b/lib/igt_sysfs.c
@@ -234,7 +234,8 @@ char *xe_sysfs_gt_path(int xe_device, int gt, char *path, int pathlen)
if (IS_PONTEVECCHIO(intel_get_drm_devid(xe_device)))
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile%d/gt%d",
- major(st.st_rdev), minor(st.st_rdev), gt, gt);
+ major(st.st_rdev), minor(st.st_rdev),
+ xe_gt_get_tile_id(xe_device, gt), gt);
else
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile0/gt%d",
major(st.st_rdev), minor(st.st_rdev), gt);
diff --git a/lib/xe/xe_query.h b/lib/xe/xe_query.h
index 30ea5ad41..e325608e0 100644
--- a/lib/xe/xe_query.h
+++ b/lib/xe/xe_query.h
@@ -15,27 +15,42 @@
#include "igt_aux.h"
#include "igt_list.h"
#include "igt_sizes.h"
-#include "intel_hwconfig_types.h"
#define XE_DEFAULT_ALIGNMENT SZ_4K
#define XE_DEFAULT_ALIGNMENT_64K SZ_64K
struct xe_device {
+#define XE_MAX_TILES_PER_DEVICE 4
/** @fd: xe fd */
int fd;
/** @config: xe configuration */
struct drm_xe_query_config *config;
- /** @hwconfig: xe hwconfig table data */
- uint32_t *hwconfig;
-
- /** @hwconfig_size: size of hwconfig in bytes */
- uint32_t hwconfig_size;
-
/** @gt_list: gt info */
struct drm_xe_query_gt_list *gt_list;
+ /** @tiles: device tiles */
+ struct drm_xe_tile tiles[XE_MAX_TILES_PER_DEVICE];
+
+ /** @info: device info */
+ struct drm_xe_tile_info {
+ /** @info.tile_count: Number of tiles */
+ uint8_t tile_count;
+ /** @info.gt_count: Total number of GTs for entire device */
+ uint8_t gt_count;
+ /** @tile_unvailable: Flag to check if tile is missing or out of order */
+ uint8_t tile_unavailable:1;
+ /** @mis_tile: Tile ID missing or out of order */
+ uint8_t mis_tile_id[XE_MAX_TILES_PER_DEVICE];
+ /** @mis_tile_count: missing TIle ID **/
+ uint8_t mis_tile_count;
+ /** @info.graphics_verx100: graphics IP version */
+ __u32 graphics_verx100;
+ /** @info.media_verx100: media IP version */
+ __u32 media_verx100;
+ } info;
+
/** @gt_list: bitmask of all memory regions */
uint64_t memory_regions;
@@ -75,20 +90,34 @@ struct xe_device {
++__class)
#define xe_for_each_gt(__fd, __gt) \
for (__gt = 0; __gt < xe_number_gt(__fd); ++__gt)
-
+#define xe_for_each_tile(tile__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
+ for_each_if((tile__) = &(xe__)->tiles[(id__)])
+#define xe_for_each_remote_tile(tile__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
+ for_each_if((tile__) = &(xe__)->tiles[(id__)])
+#define xe_for_each_device_gt(gt__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.gt_count; (id__)++) \
+ for_each_if((gt__) = xe_device_get_gt((xe__), (id__)))
#define xe_for_each_mem_region(__fd, __memreg, __r) \
for (uint64_t igt_unique(__i) = 0; igt_unique(__i) < igt_fls(__memreg); igt_unique(__i)++) \
for_if(__r = (__memreg & (1ull << igt_unique(__i))))
#define XE_IS_CLASS_SYSMEM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_SYSMEM)
#define XE_IS_CLASS_VRAM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_VRAM)
-
+#define MEDIA_VER(xe) ((xe)->info.media_verx100 / 100)
/*
* Max possible engine instance in drm_xe_engine_class_instance::engine_instance. Only
* used to declare arrays of drm_xe_engine_class_instance
*/
#define XE_MAX_ENGINE_INSTANCE 9
+/*
+ * Max possible GT per Tile
+ *
+ */
+#define XE_MAX_GT_PER_TILE 2
+
unsigned int xe_number_gt(int fd);
uint64_t all_memory_regions(int fd);
uint64_t system_memory(int fd);
@@ -115,13 +144,12 @@ uint16_t xe_dev_id(int fd);
int xe_supports_faults(int fd);
const char *xe_engine_class_string(uint32_t engine_class);
bool xe_has_engine_class(int fd, uint16_t engine_class);
-struct drm_xe_engine *xe_find_engine_by_class(int fd, uint16_t engine_class);
bool xe_has_media_gt(int fd);
bool xe_is_media_gt(int fd, int gt);
uint16_t xe_gt_get_tile_id(int fd, int gt);
-uint32_t *xe_hwconfig_lookup_value(int fd, enum intel_hwconfig attribute, uint32_t *len);
struct xe_device *xe_device_get(int fd);
void xe_device_put(int fd);
+struct xe_gt *xe_device_get_gt(struct xe_device *xe, uint8_t gt_id);
#endif /* XE_QUERY_H */
diff --git a/tests/intel/xe_multi_tile.c b/tests/intel/xe_multi_tile.c
new file mode 100644
index 000000000..e76091b3f
--- /dev/null
+++ b/tests/intel/xe_multi_tile.c
@@ -0,0 +1,432 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ *
+ * Authors:
+ * Nishit Sharma <nishit.sharma@intel.com>
+ */
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "igt.h"
+#include "igt_sysfs.h"
+
+#include "xe_drm.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+
+/**
+ * TEST: Test to verify if multi-tile support available in platform
+ * by verifying Tile IDs and filling internal structs
+ * required to process user requests like getting GT ID
+ * gt%d belongs to which Tile%d
+ * Category: Core
+ * Mega feature: General Core features
+ * Functionality: Tile/GT operations
+ */
+
+/**
+ * SUBTEST: multi-tile-info
+ * Description: Test gathers Tile_ID/s and GT_ID/s and set internal
+ * structures required for operations
+ * Test category: functionality test
+ *
+ */
+
+/*
+ * xe_gt_list: Get the list of gt%d, tile%d and count
+ * from driver using IOCTL
+ * @fd: GPU device descriptor
+ *
+ * Function gets the list of gt%d and tile%d available in device
+ * including other information such as gt count, graphics ip version
+ *
+ * Return: Returns drm_xe_query_gt_list pointer which have
+ * list of gt%d and tile%d available
+ */
+struct drm_xe_query_gt_list *xe_gt_list(int fd)
+{
+ struct drm_xe_query_gt_list *gt_list;
+ struct drm_xe_device_query query = {
+ .extensions = 0,
+ .query = DRM_XE_DEVICE_QUERY_GT_LIST,
+ .size = 0,
+ .data = 0,
+ };
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+ igt_assert_neq(query.size, 0);
+
+ gt_list = malloc(query.size);
+ igt_assert(gt_list);
+
+ query.data = to_user_pointer(gt_list);
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+
+ return gt_list;
+}
+/*
+ * xe_gt_alloc: Memory allocation for gt%d and initializing
+ * struct drm_xe_tile as per gt%d
+ * @tile *: Holds gt informations such as GT_ID and Tile_ID
+ *
+ * This allocates memory per GT available on tile and assigns corresponding tile address
+ * to corresponding gt
+ *
+ * Return: Returns gt structure
+ */
+struct xe_gt *xe_gt_alloc(struct drm_xe_tile *tile)
+{
+ struct xe_gt *gt;
+
+ gt = malloc(sizeof(*gt));
+ igt_assert(gt);
+
+ gt->tile = tile;
+ return gt;
+}
+/**
+ * xe_tile_init - Initialize the tile and allocates memmory for primary GT
+ * @tile: Tile to initialize
+ * @xe: Parent Xe device
+ * @id: Tile ID
+ *
+ * Initializes per-tile resources that don't require any interactions with the
+ * hardware or any knowledge about the Graphics/Media IP version.
+ *
+ * Returns: 0 on success, assert if no memory allocation.
+ */
+int xe_tile_init(struct drm_xe_tile *tile, struct xe_device *xe, uint8_t id)
+{
+ tile->xe = xe;
+ tile->id = id;
+
+ tile->primary_gt = xe_gt_alloc(tile);
+ igt_assert(tile->primary_gt);
+
+ return 0;
+}
+/**
+ * xe_device_get_root_tile: Returns address of root tile
+ * @xe: GPU Device strcuture which holds information about tile
+ * available in system
+ *
+ * Return: root tile address
+ */
+struct xe_tile *xe_device_get_root_tile(struct xe_device *xe)
+{
+ return &xe->tiles[0];
+}
+/**
+ * xe_tile_get_gt: Return xe_gt address
+ * @tile *: Tile associated with gt
+ * @gt_id: gt%d
+ *
+ * Returns: Based on gt_id passed xe_gt address returned which
+ * can be media_gt or primary gt
+ */
+struct xe_gt *xe_tile_get_gt(struct drm_xe_tile *tile, u8 gt_id)
+{
+ igt_assert_f(gt_id <= XE_MAX_GT_PER_TILE, "gt_id greater than defined XE_MAX_GT_PER_TILE");
+
+ return gt_id ? tile->media_gt : tile->primary_gt;
+}
+/**
+ * @xe_dev: GPU device address
+ * @gt_id: gt%d
+ *
+ * Returns: xe_gt address based on media version available in platform
+ */
+struct xe_gt *xe_device_get_gt(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ struct drm_xe_tile *root_tile = xe_device_get_root_tile(xe_dev);
+ struct xe_gt *gt;
+
+ if (MEDIA_VER(xe_dev) >= 13)
+ gt = xe_tile_get_gt(root_tile, gt_id);
+ else
+ gt = xe_dev->tiles[gt_id].primary_gt;
+
+ igt_assert(gt);
+
+ return gt;
+}
+/**
+ * @xe_dev: GPU device structure
+ * @gt_id: gt%d
+ *
+ * Check gt%d passed available on tile%d or not available
+ *
+ * Return: None
+ */
+static void igt_check_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ uint8_t id;
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ xe_for_each_device_gt(gt, xe_dev, id) {
+ tile = gt->tile;
+ if(gt_id == gt->info.id)
+ igt_info("GT ID :%d available in Tile :tile%d\n",
+ gt_id, tile->id);
+ else
+ igt_info("GT ID :%d not available in Tile :tile%d\n",
+ gt_id, tile->id);
+ }
+}
+/**
+ * @xe_dev: GPU device structure
+ * @gt_id: gt%d
+ *
+ * To query gt%d available in tile%d by iterating over list of tiles available
+ *
+ * Returns: 0
+ */
+static uint8_t igt_query_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ gt = tile->primary_gt;
+ igt_info("Inside GT Id :%d GT type :%d GT count :%d for Tile ID :%d GT count in Tile :%d\n",
+ gt->info.id, gt->info.type, gt->info.gt_count, tile->id, tile->gt_count);
+
+ if(MEDIA_VER(xe_dev) >= 13)
+ {
+ gt = tile->media_gt;
+ igt_info("Inside GT Id :%d GT type :%d GT count :%d for Tile ID :%d GT count in Tile :%d\n",
+ gt->info.id, gt->info.type, gt->info.gt_count, tile->id, tile->gt_count);
+ }
+ }
+
+ return 0;
+}
+/**
+ * igt_show_device_gt: To show gt availale on GPU device
+ * @xe_dev: GPU device structure
+ * @fd: GPU device descriptor
+ *
+ * Show GT%d available on device
+ *
+ * Return: None
+ */
+static void igt_show_device_gt(struct xe_device *xe_dev, int fd)
+{
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ uint8_t id;
+
+ xe_for_each_device_gt(gt, xe_dev, id) {
+ tile = gt->tile;
+ igt_info("GT Id :%d GT type :%d Tile ID :%d\n",
+ gt->info.id, gt->info.type, tile->id);
+ }
+}
+/**
+ * igt_gt_init_per_tile: Initialize xe_gt structure per gt%d and per tile%d
+ * Memory allocation for each tile and based on media version
+ * if available on device xe_gt structure initialized and assigned
+ * to tile%d
+ * @xe_dev: GPU device structure
+ * @fd: GPU device descriptor
+ *
+ * Returns: 0 in case of success or assert
+ */
+static uint8_t igt_gt_init_per_tile(struct xe_device *xe_dev, int fd)
+{
+ uint8_t gt_id = 0;
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt, *prev_gt = NULL, *new_gt;
+ int ip_version, media_version;
+ char name[100];
+
+ igt_info("per Tile initialization\n");
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ int err;
+ err = xe_tile_init(tile, xe_dev, gt_id);
+ igt_assert_eq(err, 0);
+ }
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ gt = tile->primary_gt;
+ new_gt = gt;
+ gt->info.id = xe_dev->info.gt_count++;
+ gt->info.type= XE_GT_TYPE_MAIN;
+ gt->info.gt_count++;
+ tile->gt_count++;
+
+ FILE *file = fopen("/sys/kernel/debug/dri/0/info", "r");
+ igt_assert(file);
+
+ while (fscanf(file, "%s %d", name, &ip_version) == 1) {
+ ip_version = -1;
+ }
+ while (fscanf(file, "%s %d", name, &media_version) == 1) {
+ media_version = -1;
+ }
+
+ fclose(file);
+
+ xe_dev->info.graphics_verx100 = ip_version;
+ xe_dev->info.media_verx100 = media_version;
+
+ if (MEDIA_VER(xe_dev) < 13)
+ continue;
+
+ /*
+ * Allocate and setup media GT for platforms with standalone
+ * media.
+ *
+ */
+ tile->media_gt = xe_gt_alloc(tile);
+ igt_assert(tile->media_gt);
+ gt->info.type = XE_GT_TYPE_MEDIA;
+ gt->info.id = xe_dev->info.gt_count++;
+ gt->info.gt_count++;
+ tile->gt_count++;
+ }
+
+ return 0;
+}
+/**
+ * igt_check_missing_tile_sysfs: Checking if tile missing or out of order in system
+ * @xe_device: fd of the device
+ * @fd: Device descriptor
+ *
+ * This opens the sysfs tile directory corresponding to device and tile for use
+ * The mis_tile_id[] contains tile%d which is checked with sysfs whether entry is present
+ * or not. E.g. After tile2 user get tile4, tile3 is missing which will be checked in sysfs path
+ *
+ * Returns: None
+ */
+static void igt_check_missing_tile_sysfs(struct xe_device *xe_dev,
+ int fd)
+{
+ char path[96];
+
+ igt_info("Checking missing tiles with sysfs\n");
+
+ for(int mis = 0; mis < xe_dev->info.mis_tile_count; mis++) {
+ xe_sysfs_tile_path(fd, xe_dev->info.mis_tile_id[mis], path, sizeof(path));
+ }
+
+ igt_assert_f(xe_dev->info.mis_tile_count < 0, "No Tile entry in sysfs found.");
+}
+/**
+ * igt_check_if_missingtile: Checking if tile missing by iterating over
+ * filled mis tile array
+ * @xe_dev: GPU device structure
+ * fd: GPU device descriptor
+ *
+ * Returns: None
+ */
+static void igt_check_if_missingtile(struct xe_device *xe_dev, int fd)
+{
+ igt_info("Checking missing/out of order tiles\n");
+
+ for(int i= 0; i < xe_dev->info.mis_tile_count; i++){
+ igt_warn("Tile :%d out of order/missing\n",
+ xe_dev->info.mis_tile_id[i]);
+ }
+}
+/**
+ * igt_get_tile_count: To get count of tile/s available in system,
+ * Getting missing tile and tle count if any
+ * @xe_dev: Device structure
+ * @fd: Device descriptor
+ * gt_list: list of gt%d and relavant information returned from Driver via IOCTL
+ *
+ * Return: Tile count
+ */
+static uint8_t igt_get_tile_count(struct xe_device *xe_dev, int fd,
+ struct drm_xe_query_gt_list *gt_list)
+{
+ int prev_tile = -1, tile_id;
+ uint8_t tile_mis_count = -1;
+
+ for(int index = 0; index < gt_list->num_gt; index++) {
+ tile_id = gt_list->gt_list[index].tile_id;
+ if(prev_tile != tile_id)
+ {
+ if(++tile_mis_count != tile_id) {
+ xe_dev->info.tile_unavailable = true;
+ xe_dev->info.mis_tile_id[xe_dev->info.mis_tile_count++] = tile_mis_count;
+ }
+ prev_tile = tile_id;
+ xe_dev->info.tile_count++;
+ }
+ xe_dev->info.tile_unavailable = false;
+ }
+
+ return xe_dev->info.tile_count;
+}
+
+igt_main
+{
+ int fd;
+ struct drm_xe_query_gt_list *gt_list;
+ struct xe_device *xe_dev;
+ struct drm_xe_tile *tile;
+ uint8_t gt_count;
+ uint8_t gt_arr[] = {0,1,2,3,4,5,6,7,8};
+
+ igt_fixture {
+ fd = drm_open_driver(DRIVER_XE);
+ xe_dev = xe_device_get(fd);
+ }
+
+ tile = malloc(sizeof(*tile));
+ igt_assert(tile);
+
+ igt_subtest("multi-tile-info") {
+ /** get gt information from driver using ioctl **/
+ gt_list = xe_gt_list(fd);
+ /** store pointer returned from driver which have gt information **/
+ tile->gt_list = gt_list;
+
+ /** Get tile count, initialize flag to check if any tile missing
+ * Fill internal struct
+ */
+ gt_count = igt_get_tile_count(xe_dev, fd, gt_list);
+ igt_assert_neq(gt_count, 0);
+ igt_info("Tiles :%d available in platform\n", gt_count);
+
+ /** check if multi-tile supported in platform */
+ igt_assert_f(xe_dev->info.tile_count > 1,
+ "Multi-Tile not supported in platform :%d\n",
+ xe_dev->info.tile_count);
+
+ /************* Per Tile Initilization ***********/
+ igt_assert_eq(igt_gt_init_per_tile(xe_dev, fd), 0);
+
+ /******** Condition to check if any tile missing/out of order *****/
+ if (xe_dev->info.tile_unavailable)
+ igt_check_if_missingtile(xe_dev, fd);
+
+ /******* Checking missing/out of order tile comparing with sysfs ***/
+ if (xe_dev->info.tile_unavailable)
+ igt_check_missing_tile_sysfs(xe_dev, fd);
+
+ /****** Display GT information on GPU Device *******/
+ igt_show_device_gt(xe_dev, fd);
+
+ /****** Query GT per Tile *****/
+ igt_query_gt_per_tile(xe_dev, fd);
+
+ /***** Checking GT exist, if exist on which tile or doesn't exist ******/
+ for(int gt_id = 0; gt_id < sizeof(gt_arr); gt_id++)
+ igt_check_gt_per_tile(xe_dev, gt_id);
+ }
+
+ igt_fixture {
+ drm_close_driver(fd);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index 2724c7a9a..2cc01aa0c 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -292,6 +292,7 @@ intel_xe_progs = [
'xe_exec_reset',
'xe_exec_sip',
'xe_exec_store',
+ 'xe_multi_tile',
'xe_exec_threads',
'xe_exercise_blt',
'xe_fault_injection',
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT
2025-02-15 1:11 nishit.sharma
@ 2025-02-17 14:20 ` Kamil Konieczny
0 siblings, 0 replies; 8+ messages in thread
From: Kamil Konieczny @ 2025-02-17 14:20 UTC (permalink / raw)
To: nishit.sharma; +Cc: igt-dev, matthew.d.roper
Hi nishit.sharma,
On 2025-02-15 at 01:11:55 +0000, nishit.sharma@intel.com wrote:
> From: Nishit Sharma <nishit.sharma@intel.com>
only few nits, first please keep description to 65 columns
(or max 80).
>
> Added functionality to check Multi-Tile available in system or not. Belonging to each Tile%d
> GT%d gathered. Checked GT%d belongs to which tile%d in multi-tile/single-tile platforms.
> Added functionality to check if any tile%d not provided by driver or missed.
> E.g.tile available in platforms in order tile0, tile1...tileX in serial order, If
> tile1 tile2 tile4...tileX populated than will get Warning tile3 not available.
>
> Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
> ---
> include/drm-uapi/xe_drm.h | 169 ++++++++++++--
Change for drm-uapi should go in separate patch, see git log.
> lib/igt_sysfs.c | 3 +-
> lib/xe/xe_query.h | 50 ++++-
> tests/intel/xe_multi_tile.c | 432 ++++++++++++++++++++++++++++++++++++
> tests/meson.build | 1 +
> 5 files changed, 620 insertions(+), 35 deletions(-)
> create mode 100644 tests/intel/xe_multi_tile.c
>
> diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
> index 56163eb91..8b0869ce2 100644
> --- a/include/drm-uapi/xe_drm.h
> +++ b/include/drm-uapi/xe_drm.h
> @@ -3,8 +3,8 @@
> * Copyright © 2023 Intel Corporation
> */
>
> -#ifndef _XE_DRM_H_
> -#define _XE_DRM_H_
> +#ifndef _UAPI_XE_DRM_H_
> +#define _UAPI_XE_DRM_H_
This shouldn't change, see README.md about how to bring uapi
changes into igt.
Regards,
Kamil
>
> #include "drm.h"
>
> @@ -118,6 +118,12 @@ extern "C" {
> #define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
> #define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
>
[...cut...]
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT
@ 2025-02-28 9:22 nishit.sharma
2025-03-07 23:19 ` Matt Roper
0 siblings, 1 reply; 8+ messages in thread
From: nishit.sharma @ 2025-02-28 9:22 UTC (permalink / raw)
To: igt-dev, nishit.sharma, matthew.d.roper
From: Nishit Sharma <nishit.sharma@intel.com>
Added functionality to check Multi-Tile available in platform or not. GT%d exposed
related to each Tile%d. Functionality added to check if any tile%d not provided by
driver or missed E.g.tile available in platforms in order tile0, tile1...tileX in
serial order, If tile1 tile2 tile4...tileX populated than will get Warning tile3 not available.
Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
include/drm-uapi/xe_drm.h | 88 ++++++++
lib/igt_sysfs.c | 3 +-
lib/xe/xe_query.h | 38 +++-
tests/intel/xe_multi_tile.c | 423 ++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
5 files changed, 551 insertions(+), 2 deletions(-)
create mode 100644 tests/intel/xe_multi_tile.c
diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index 08e263b3b..5e2a54353 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -188,6 +188,94 @@ struct drm_xe_user_extension {
__u32 pad;
};
+enum xe_gt_type {
+ XE_GT_TYPE_UNINITIALIZED,
+ XE_GT_TYPE_MAIN,
+ XE_GT_TYPE_MEDIA,
+};
+
+/**
+ * struct xe_gt - A "Graphics Technology" unit of the GPU
+ *
+ * A GT ("Graphics Technology") is the subset of a GPU primarily responsible
+ * for implementing the graphics, compute, and/or media IP.
+ *
+ */
+struct xe_gt {
+ /** @tile: Backpointer to GT's tile */
+ struct drm_xe_tile *tile;
+
+ /** @info: GT info */
+ struct {
+ /** @info.type: type of GT */
+ enum xe_gt_type type;
+
+ /** @info.id: Unique ID of this GT within the PCI Device */
+
+ __u8 id;
+
+ /**
+ * @gt_count: Number of GT/s available in tile
+ *
+ * */
+ __u8 gt_count;
+ } info;
+};
+
+/**
+ * struct drm_xe_tile - hardware tile structure
+ *
+ * Tile structure contains info like tile ID, vram id, flag to check any tile
+ * missing or out of order, gt count per tile
+ *
+ */
+struct drm_xe_tile {
+ /** @xe: Backpointer to tile's PCI device */
+ struct xe_device *xe;
+
+ /** @id: ID of the tile */
+ __u8 id;
+
+ /**
+ * @vram_id: ID of associated TTM VRAM region
+ *
+ * For multi-tile platforms not using unified vram, this is same
+ * as @id. Otherwise this is always 0 to denote a single unified
+ * vram region is in use.
+ */
+ __u8 vram_id;
+
+ /**
+ * @mis_tile: Flasg to check if tile ID missing or out of order
+ *
+ */
+ __u8 mis_tile:1;
+
+ /**
+ * @gt_count: Number of GT/s available in tile
+ *
+ * */
+ __u8 gt_count;
+
+ /**
+ * @primary_gt: Primary GT
+ */
+ struct xe_gt *primary_gt;
+
+ /**
+ * @media_gt: Media GT
+ *
+ * Only present on devices with media version >= 13.
+ */
+ struct xe_gt *media_gt;
+
+ /**
+ * @gt_list: List of GT descriptors from driver
+ *
+ */
+ struct drm_xe_query_gt_list *gt_list;
+};
+
/**
* struct drm_xe_ext_set_property - Generic set property extension
*
diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
index 2e4c2ee63..6fb70ccc9 100644
--- a/lib/igt_sysfs.c
+++ b/lib/igt_sysfs.c
@@ -235,7 +235,8 @@ char *xe_sysfs_gt_path(int xe_device, int gt, char *path, int pathlen)
if (IS_PONTEVECCHIO(intel_get_drm_devid(xe_device)))
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile%d/gt%d",
- major(st.st_rdev), minor(st.st_rdev), gt, gt);
+ major(st.st_rdev), minor(st.st_rdev),
+ xe_gt_get_tile_id(xe_device, gt), gt);
else
snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile0/gt%d",
major(st.st_rdev), minor(st.st_rdev), gt);
diff --git a/lib/xe/xe_query.h b/lib/xe/xe_query.h
index a84a6bfa5..34fea94d1 100644
--- a/lib/xe/xe_query.h
+++ b/lib/xe/xe_query.h
@@ -21,6 +21,7 @@
#define XE_DEFAULT_ALIGNMENT_64K SZ_64K
struct xe_device {
+#define XE_MAX_TILES_PER_DEVICE 4
/** @fd: xe fd */
int fd;
@@ -36,6 +37,27 @@ struct xe_device {
/** @gt_list: gt info */
struct drm_xe_query_gt_list *gt_list;
+ /** @tiles: device tiles */
+ struct drm_xe_tile tiles[XE_MAX_TILES_PER_DEVICE];
+
+ /** @info: device info */
+ struct drm_xe_tile_info {
+ /** @info.tile_count: Number of tiles */
+ uint8_t tile_count;
+ /** @info.gt_count: Total number of GTs for entire device */
+ uint8_t gt_count;
+ /** @tile_unvailable: Flag to check if tile is missing or out of order */
+ uint8_t tile_unavailable:1;
+ /** @mis_tile: Tile ID missing or out of order */
+ uint8_t mis_tile_id[XE_MAX_TILES_PER_DEVICE];
+ /** @mis_tile_count: missing TIle ID **/
+ uint8_t mis_tile_count;
+ /** @info.graphics_verx100: graphics IP version */
+ __u32 graphics_verx100;
+ /** @info.media_verx100: media IP version */
+ __u32 media_verx100;
+ } info;
+
/** @gt_list: bitmask of all memory regions */
uint64_t memory_regions;
@@ -75,13 +97,22 @@ struct xe_device {
++__class)
#define xe_for_each_gt(__fd, __gt) \
for (__gt = 0; __gt < xe_number_gt(__fd); ++__gt)
-
+#define xe_for_each_tile(tile__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
+ for_each_if((tile__) = &(xe__)->tiles[(id__)])
+#define xe_for_each_remote_tile(tile__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
+ for_each_if((tile__) = &(xe__)->tiles[(id__)])
+#define xe_for_each_device_gt(gt__, xe__, id__) \
+ for ((id__) = 0; (id__) < (xe__)->info.gt_count; (id__)++) \
+ for_each_if((gt__) = xe_device_get_gt((xe__), (id__)))
#define xe_for_each_mem_region(__fd, __memreg, __r) \
for (uint64_t igt_unique(__i) = 0; igt_unique(__i) < igt_fls(__memreg); igt_unique(__i)++) \
for_if(__r = (__memreg & (1ull << igt_unique(__i))))
#define XE_IS_CLASS_SYSMEM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_SYSMEM)
#define XE_IS_CLASS_VRAM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_VRAM)
+#define MEDIA_VER(xe) ((xe)->info.media_verx100 / 100)
/*
* Max possible engine instance in drm_xe_engine_class_instance::engine_instance. Only
@@ -89,6 +120,11 @@ struct xe_device {
*/
#define XE_MAX_ENGINE_INSTANCE 9
+/*
+ * Max possible GT per Tile
+ */
+#define XE_MAX_GT_PER_TILE 2
+
unsigned int xe_number_gt(int fd);
uint64_t all_memory_regions(int fd);
uint64_t system_memory(int fd);
diff --git a/tests/intel/xe_multi_tile.c b/tests/intel/xe_multi_tile.c
new file mode 100644
index 000000000..c5b2e0472
--- /dev/null
+++ b/tests/intel/xe_multi_tile.c
@@ -0,0 +1,423 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2025 Intel Corporation
+ *
+ * Authors:
+ * Nishit Sharma <nishit.sharma@intel.com>
+ */
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "igt.h"
+#include "igt_sysfs.h"
+
+#include "xe_drm.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+
+/**
+ * TEST: Test to verify if multi-tile support available in platform
+ * Category: Core
+ * Mega feature: General Core features
+ * Sub-category: Tile/GT operations
+ * Functionality: multi-tile
+ * Test category: functionality test
+ */
+
+/**
+ * SUBTEST: multi-tile-info
+ * Description: Test gathers Tile_ID/s and GT_ID/s, update internal struct
+ */
+
+struct xe_gt *xe_gt_alloc(struct drm_xe_tile *tile);
+int xe_tile_init(struct drm_xe_tile *tile, struct xe_device *xe, uint8_t id);
+struct drm_xe_tile *xe_device_get_root_tile(struct xe_device *xe);
+struct xe_gt *xe_tile_get_gt(struct drm_xe_tile *tile, u8 gt_id);
+struct xe_gt *xe_device_get_gt(struct xe_device *xe_dev, uint8_t gt_id);
+
+/*
+ * xe_gt_list: Get the list of gt%d, tile%d and count from driver
+ * @fd: GPU device descriptor
+ *
+ * Function gets the count of gt available in device
+ * including other information such as gt count, graphics ip version
+ *
+ * Return: Returns drm_xe_query_gt_list pointer
+ */
+struct drm_xe_query_gt_list *xe_gt_list(int fd)
+{
+ struct drm_xe_query_gt_list *gt_list;
+ struct drm_xe_device_query query = {
+ .extensions = 0,
+ .query = DRM_XE_DEVICE_QUERY_GT_LIST,
+ .size = 0,
+ .data = 0,
+ };
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+ igt_assert_neq(query.size, 0);
+
+ gt_list = malloc(query.size);
+ igt_assert(gt_list);
+
+ query.data = to_user_pointer(gt_list);
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
+
+ return gt_list;
+}
+/*
+ * xe_gt_alloc: Memory allocation for gt struct and initializing
+ * struct drm_xe_tile as per gt
+ * @tile *: Tile structure
+ *
+ * This allocates memory per GT available on tile and assigns corresponding tile address
+ * to corresponding gt
+ *
+ * Return: Returns gt structure pointer
+ */
+struct xe_gt *xe_gt_alloc(struct drm_xe_tile *tile)
+{
+ struct xe_gt *gt;
+
+ gt = malloc(sizeof(*gt));
+ igt_assert(gt);
+
+ gt->tile = tile;
+ return gt;
+}
+/**
+ * xe_tile_init - Initialize the tile structure and allocates memmory for primary GT
+ * @tile: Tile to initialize
+ * @xe: Parent Xe device
+ * @id: Tile ID
+ *
+ * Initializes per-tile resources.
+ *
+ * Returns: 0 on success, assert if no memory allocation.
+ */
+int xe_tile_init(struct drm_xe_tile *tile, struct xe_device *xe, uint8_t id)
+{
+ tile->xe = xe;
+ tile->id = id;
+
+ tile->primary_gt = xe_gt_alloc(tile);
+ igt_assert(tile->primary_gt);
+
+ return 0;
+}
+/**
+ * xe_device_get_root_tile: Returns address of root tile
+ * @xe: GPU Device structure which holds information about tile
+ * available in system
+ *
+ * Return: root tile address
+ */
+struct drm_xe_tile *xe_device_get_root_tile(struct xe_device *xe)
+{
+ return &xe->tiles[0];
+}
+/**
+ * xe_tile_get_gt: Return address gt struct
+ * @tile *: Tile associated with gt
+ * @gt_id: gt%d
+ *
+ * Returns: Based on gt_id passed xe_gt address returned which
+ * can be media_gt or primary gt
+ */
+struct xe_gt *xe_tile_get_gt(struct drm_xe_tile *tile, u8 gt_id)
+{
+ igt_assert_f(gt_id <= XE_MAX_GT_PER_TILE, "gt_id greater than defined XE_MAX_GT_PER_TILE");
+
+ return gt_id ? tile->media_gt : tile->primary_gt;
+}
+/**
+ * @xe_dev: GPU Device structure which holds information about tile
+ * @gt_id: gt%d
+ *
+ * Returns: gt struct address based on media version available in platform
+ */
+struct xe_gt *xe_device_get_gt(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ struct drm_xe_tile *root_tile = xe_device_get_root_tile(xe_dev);
+ struct xe_gt *gt;
+
+ if (MEDIA_VER(xe_dev) >= 13)
+ gt = xe_tile_get_gt(root_tile, gt_id);
+ else
+ gt = xe_dev->tiles[gt_id].primary_gt;
+
+ igt_assert(gt);
+
+ return gt;
+}
+/**
+ * @xe_dev: GPU Device structure which holds information about tile
+ * @gt_id: gt%d
+ *
+ * Check gt%d passed available or not on tile%d
+ *
+ * Return: None
+ */
+static void igt_check_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ uint8_t id;
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ xe_for_each_device_gt(gt, xe_dev, id) {
+ tile = gt->tile;
+ if(gt_id == gt->info.id)
+ {
+ igt_info("GT ID :%d available in Tile :tile%d\n",
+ gt_id, tile->id);
+ }
+ }
+}
+/**
+ * @xe_dev: GPU Device structure which holds information about tile
+ * @gt_id: gt%d
+ *
+ * To query gt%d available in tile%d by iterating over list of tiles available
+ *
+ * Returns: None
+ */
+static void igt_query_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
+{
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ gt = tile->primary_gt;
+
+ if(MEDIA_VER(xe_dev) >= 12)
+ gt = tile->media_gt;
+
+ igt_info("Inside GT Id :%d GT type :%d GT count :%d for Tile ID :%d GT count in Tile :%d\n",
+ gt->info.id, gt->info.type, gt->info.gt_count, tile->id, tile->gt_count);
+ }
+}
+/**
+ * igt_show_device_gt: To show gt availale on GPU device
+ * @xe_dev: GPU Device structure which holds information about tile
+ * @fd: GPU device descriptor
+ *
+ * Show GT%d available on device
+ *
+ * Return: None
+ */
+static void igt_show_device_gt(struct xe_device *xe_dev, int fd)
+{
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+
+ uint8_t id;
+
+ xe_for_each_device_gt(gt, xe_dev, id) {
+ tile = gt->tile;
+ igt_info("GT Id :%d GT type :%d Tile ID :%d\n",
+ gt->info.id, gt->info.type, tile->id);
+ }
+}
+/**
+ * igt_gt_init_per_tile: Initialize xe_gt structure per gt%d and per tile%d
+ * @xe_dev: GPU Device structure which holds information about tile
+ * @fd: GPU device descriptor
+ *
+ * Returns: 0 in case of success or assert
+ */
+static uint8_t igt_gt_init_per_tile(struct xe_device *xe_dev, int fd)
+{
+ uint8_t gt_id = 0;
+ struct drm_xe_tile *tile;
+ struct xe_gt *gt;
+ int ip_version, media_version;
+ char name[100];
+ FILE *file;
+
+ igt_info("per Tile initialization\n");
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ int err;
+ err = xe_tile_init(tile, xe_dev, gt_id);
+ igt_assert_eq(err, 0);
+ }
+
+ xe_for_each_tile(tile, xe_dev, gt_id) {
+ gt = tile->primary_gt;
+ //new_gt = gt;
+ gt->info.id = xe_dev->info.gt_count++;
+ gt->info.type= XE_GT_TYPE_MAIN;
+ gt->info.gt_count++;
+ tile->gt_count++;
+
+ file = fopen("/sys/kernel/debug/dri/0/info", "r");
+ igt_assert(file);
+
+ while (fscanf(file, "%s %d", name, &ip_version) == 1) {
+ ip_version = -1;
+ }
+ while (fscanf(file, "%s %d", name, &media_version) == 1) {
+ media_version = -1;
+ }
+
+ fclose(file);
+
+ xe_dev->info.graphics_verx100 = ip_version;
+ xe_dev->info.media_verx100 = media_version;
+
+ if (MEDIA_VER(xe_dev) < 13)
+ continue;
+
+ /*
+ * Allocate and setup media GT for platforms with standalone
+ * media.
+ *
+ */
+ tile->media_gt = xe_gt_alloc(tile);
+ igt_assert(tile->media_gt);
+ gt->info.type = XE_GT_TYPE_MEDIA;
+ gt->info.id = xe_dev->info.gt_count++;
+ gt->info.gt_count++;
+ tile->gt_count++;
+ }
+
+ return 0;
+}
+/**
+ * igt_check_missing_tile_sysfs: Checking if tile missing or out of order in system
+ * @xe_device: GPU Device structure which holds information about tile
+ * @fd: Device descriptor
+ *
+ * This opens the sysfs tile directory corresponding to device and tile for use
+ * The mis_tile_id[] contains tile%d which is checked with sysfs whether entry is present
+ * or not. E.g. After tile2 user get tile4, tile3 is missing which will be checked in sysfs path
+ *
+ * Returns: None
+ */
+static void igt_check_missing_tile_sysfs(struct xe_device *xe_dev,
+ int fd)
+{
+ char path[96];
+
+ igt_info("Checking missing tiles with sysfs\n");
+
+ for(int mis = 0; mis < xe_dev->info.mis_tile_count; mis++) {
+ xe_sysfs_tile_path(fd, xe_dev->info.mis_tile_id[mis], path, sizeof(path));
+ }
+
+ igt_assert_f(xe_dev->info.mis_tile_count < 0, "No Tile entry in sysfs found.");
+}
+/**
+ * igt_check_if_missingtile: Checking if tile missing by iterating over
+ * filled mis tile array
+ * @xe_dev: GPU Device structure which holds information about tile
+ * fd: GPU device descriptor
+ *
+ * Returns: None
+ */
+static void igt_check_if_missingtile(struct xe_device *xe_dev, int fd)
+{
+ igt_info("Checking missing/out of order tiles\n");
+
+ for(int i= 0; i < xe_dev->info.mis_tile_count; i++){
+ igt_warn("Tile :%d out of order/missing\n",
+ xe_dev->info.mis_tile_id[i]);
+ }
+}
+/**
+ * igt_get_tile_count: To get count of tile/s available in system,
+ * Getting missing tile and tle count if any
+ * @xe_dev: GPU Device structure which holds information about tile
+ * @fd: Device descriptor
+ * gt_list: list of gt%d and relavant information returned from Driver via IOCTL
+ *
+ * Return: Tile count
+ */
+static uint8_t igt_get_tile_count(struct xe_device *xe_dev, int fd,
+ struct drm_xe_query_gt_list *gt_list)
+{
+ int prev_tile = -1, tile_id;
+ uint8_t tile_mis_count = -1;
+
+ for(int index = 0; index < gt_list->num_gt; index++) {
+ tile_id = gt_list->gt_list[index].tile_id;
+ if(prev_tile != tile_id)
+ {
+ if(++tile_mis_count != tile_id) {
+ xe_dev->info.tile_unavailable = true;
+ xe_dev->info.mis_tile_id[xe_dev->info.mis_tile_count++] = tile_mis_count;
+ }
+ prev_tile = tile_id;
+ xe_dev->info.tile_count++;
+ }
+ xe_dev->info.tile_unavailable = false;
+ }
+
+ return xe_dev->info.tile_count;
+}
+
+igt_main
+{
+ int fd;
+ struct drm_xe_query_gt_list *gt_list;
+ struct xe_device *xe_dev;
+ struct drm_xe_tile *tile;
+ uint8_t gt_count;
+ uint8_t gt_arr[] = {0,1,2,3,4,5,6,7,8};
+
+ igt_fixture {
+ fd = drm_open_driver(DRIVER_XE);
+ xe_dev = xe_device_get(fd);
+ }
+
+ tile = malloc(sizeof(*tile));
+ igt_assert(tile);
+
+ igt_subtest("multi-tile-info") {
+ /** get gt information from driver using ioctl **/
+ gt_list = xe_gt_list(fd);
+ /** store pointer returned from driver which have gt information **/
+ tile->gt_list = gt_list;
+
+ /** Get tile count, initialize flag to check if any tile missing
+ * Fill internal struct
+ */
+ gt_count = igt_get_tile_count(xe_dev, fd, gt_list);
+ igt_assert_neq(gt_count, 0);
+ igt_info("Tiles :%d available in platform\n", gt_count);
+
+ /** check if multi-tile supported in platform */
+ igt_assert_f(xe_dev->info.tile_count > 1,
+ "Multi-Tile not supported in platform :%d\n",
+ xe_dev->info.tile_count);
+
+ /************* Per Tile Initilization ***********/
+ igt_assert_eq(igt_gt_init_per_tile(xe_dev, fd), 0);
+
+ /******** Condition to check if any tile missing/out of order *****/
+ if (xe_dev->info.tile_unavailable)
+ igt_check_if_missingtile(xe_dev, fd);
+
+ /******* Checking missing/out of order tile comparing with sysfs ***/
+ if (xe_dev->info.tile_unavailable)
+ igt_check_missing_tile_sysfs(xe_dev, fd);
+
+ /****** Display GT information on GPU Device *******/
+ igt_show_device_gt(xe_dev, fd);
+
+ /****** Query GT per Tile *****/
+ igt_query_gt_per_tile(xe_dev, fd);
+
+ /***** Checking GT exist, if exist on which tile or doesn't exist ******/
+ for(int gt_id = 0; gt_id < sizeof(gt_arr); gt_id++)
+ igt_check_gt_per_tile(xe_dev, gt_id);
+ }
+
+ igt_fixture {
+ drm_close_driver(fd);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index a0f984b34..9def89f38 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -294,6 +294,7 @@ intel_xe_progs = [
'xe_exec_reset',
'xe_exec_sip',
'xe_exec_store',
+ 'xe_multi_tile',
'xe_exec_threads',
'xe_exercise_blt',
'xe_fault_injection',
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT
2025-02-28 9:22 nishit.sharma
@ 2025-03-07 23:19 ` Matt Roper
0 siblings, 0 replies; 8+ messages in thread
From: Matt Roper @ 2025-03-07 23:19 UTC (permalink / raw)
To: nishit.sharma; +Cc: igt-dev
On Fri, Feb 28, 2025 at 09:22:51AM +0000, nishit.sharma@intel.com wrote:
> From: Nishit Sharma <nishit.sharma@intel.com>
>
> Added functionality to check Multi-Tile available in platform or not. GT%d exposed
> related to each Tile%d. Functionality added to check if any tile%d not provided by
> driver or missed E.g.tile available in platforms in order tile0, tile1...tileX in
> serial order, If tile1 tile2 tile4...tileX populated than will get Warning tile3 not available.
>
> Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
> ---
> include/drm-uapi/xe_drm.h | 88 ++++++++
> lib/igt_sysfs.c | 3 +-
> lib/xe/xe_query.h | 38 +++-
> tests/intel/xe_multi_tile.c | 423 ++++++++++++++++++++++++++++++++++++
> tests/meson.build | 1 +
> 5 files changed, 551 insertions(+), 2 deletions(-)
> create mode 100644 tests/intel/xe_multi_tile.c
>
> diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
> index 08e263b3b..5e2a54353 100644
> --- a/include/drm-uapi/xe_drm.h
> +++ b/include/drm-uapi/xe_drm.h
This is a uapi header and should always be a synchronized copy of the
kernel's header; it's not something you can make new changes to inside
of IGT. The things you're adding below don't exist on the kernel side
and aren't part of the userspace<->kernel interface, so this isn't the
right place to put them.
If your test does need something that's recently been added to the
kernel uapi and just hasn't shown up in the IGT copy of this header yet,
then you'd create an initial patch that just syncs with the kernel
version and does nothing else. For example, see ef0abf7f3
("drm-uapi/xe: Sync with OA uapi updates") for an example of a previous
synchronization commit.
> @@ -188,6 +188,94 @@ struct drm_xe_user_extension {
> __u32 pad;
> };
>
> +enum xe_gt_type {
> + XE_GT_TYPE_UNINITIALIZED,
> + XE_GT_TYPE_MAIN,
> + XE_GT_TYPE_MEDIA,
> +};
> +
> +/**
> + * struct xe_gt - A "Graphics Technology" unit of the GPU
> + *
> + * A GT ("Graphics Technology") is the subset of a GPU primarily responsible
> + * for implementing the graphics, compute, and/or media IP.
> + *
> + */
> +struct xe_gt {
> + /** @tile: Backpointer to GT's tile */
> + struct drm_xe_tile *tile;
> +
> + /** @info: GT info */
> + struct {
> + /** @info.type: type of GT */
> + enum xe_gt_type type;
> +
> + /** @info.id: Unique ID of this GT within the PCI Device */
> +
> + __u8 id;
> +
> + /**
> + * @gt_count: Number of GT/s available in tile
> + *
> + * */
> + __u8 gt_count;
Why is there a GT count inside the the per-GT structure? This seems
like the kind of thing that would be at the tile level instead.
> + } info;
> +};
> +
> +/**
> + * struct drm_xe_tile - hardware tile structure
> + *
> + * Tile structure contains info like tile ID, vram id, flag to check any tile
> + * missing or out of order, gt count per tile
> + *
> + */
> +struct drm_xe_tile {
> + /** @xe: Backpointer to tile's PCI device */
> + struct xe_device *xe;
> +
> + /** @id: ID of the tile */
> + __u8 id;
> +
> + /**
> + * @vram_id: ID of associated TTM VRAM region
> + *
> + * For multi-tile platforms not using unified vram, this is same
> + * as @id. Otherwise this is always 0 to denote a single unified
> + * vram region is in use.
> + */
> + __u8 vram_id;
> +
> + /**
> + * @mis_tile: Flasg to check if tile ID missing or out of order
> + *
> + */
> + __u8 mis_tile:1;
> +
> + /**
> + * @gt_count: Number of GT/s available in tile
> + *
> + * */
> + __u8 gt_count;
> +
> + /**
> + * @primary_gt: Primary GT
> + */
> + struct xe_gt *primary_gt;
> +
> + /**
> + * @media_gt: Media GT
> + *
> + * Only present on devices with media version >= 13.
> + */
> + struct xe_gt *media_gt;
This seems like we're trying to copy the kernel's internal details
inside IGT. From userspace's perspective, we query a list of GTs and
each of those GTs have a type. If we already have the GT list itself,
why are we adding these extra pointers (which may not even work on
future platforms if we get new types of GTs, multiple GTs of the same
type per tile, etc.)?
IGT should be following the uapi exposed by the kernel, not trying to
mimic the kernel's internal details (which we fully expect to change in
the future).
> +
> + /**
> + * @gt_list: List of GT descriptors from driver
> + *
> + */
> + struct drm_xe_query_gt_list *gt_list;
> +};
> +
> /**
> * struct drm_xe_ext_set_property - Generic set property extension
> *
> diff --git a/lib/igt_sysfs.c b/lib/igt_sysfs.c
> index 2e4c2ee63..6fb70ccc9 100644
> --- a/lib/igt_sysfs.c
> +++ b/lib/igt_sysfs.c
> @@ -235,7 +235,8 @@ char *xe_sysfs_gt_path(int xe_device, int gt, char *path, int pathlen)
>
> if (IS_PONTEVECCHIO(intel_get_drm_devid(xe_device)))
> snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile%d/gt%d",
> - major(st.st_rdev), minor(st.st_rdev), gt, gt);
> + major(st.st_rdev), minor(st.st_rdev),
> + xe_gt_get_tile_id(xe_device, gt), gt);
> else
> snprintf(path, pathlen, "/sys/dev/char/%d:%d/device/tile0/gt%d",
> major(st.st_rdev), minor(st.st_rdev), gt);
> diff --git a/lib/xe/xe_query.h b/lib/xe/xe_query.h
> index a84a6bfa5..34fea94d1 100644
> --- a/lib/xe/xe_query.h
> +++ b/lib/xe/xe_query.h
> @@ -21,6 +21,7 @@
> #define XE_DEFAULT_ALIGNMENT_64K SZ_64K
>
> struct xe_device {
> +#define XE_MAX_TILES_PER_DEVICE 4
This should probably be 2 rather than 4. The only multi-tile platform
we have today is PVC which just has two tiles. Way back I think
XeHP_SDV might have had some 4-tile configurations, but that platform
was just an early SDV for the Xe_HP architecture and no longer exists so
it isn't supported by the Xe driver. If new new platforms show up in
the future with higher tile counts, we can change this #define at that
time, once we know what the proper counts are.
> /** @fd: xe fd */
> int fd;
>
> @@ -36,6 +37,27 @@ struct xe_device {
> /** @gt_list: gt info */
> struct drm_xe_query_gt_list *gt_list;
>
> + /** @tiles: device tiles */
> + struct drm_xe_tile tiles[XE_MAX_TILES_PER_DEVICE];
> +
> + /** @info: device info */
> + struct drm_xe_tile_info {
If this structure holds device information, then why does it have 'tile'
in the structure name?
What is the point of info substructure in general? xe_device already
holds information about the device, so it's unclear why some fields are
inside this substructure and others are outside.
> + /** @info.tile_count: Number of tiles */
> + uint8_t tile_count;
> + /** @info.gt_count: Total number of GTs for entire device */
> + uint8_t gt_count;
> + /** @tile_unvailable: Flag to check if tile is missing or out of order */
> + uint8_t tile_unavailable:1;
What do you mean by 'missing or out of order?' That sounds like the
kind of thing that a specific IGT test would be checking to see if we
have driver bugs somewhere. It's not something that would need to go
into the common shared library used by all tests. Same for the next
couple fields too.
> + /** @mis_tile: Tile ID missing or out of order */
> + uint8_t mis_tile_id[XE_MAX_TILES_PER_DEVICE];
> + /** @mis_tile_count: missing TIle ID **/
> + uint8_t mis_tile_count;
> + /** @info.graphics_verx100: graphics IP version */
> + __u32 graphics_verx100;
> + /** @info.media_verx100: media IP version */
> + __u32 media_verx100;
> + } info;
When/where do all of the fields in this substructure get initialized?
If I'm using this IGT library, then I'd expect the whole structure to be
usable (in any test I write) after I call xe_device_get(). But as far
as I can see, nothing here ever gets initialized, except when running
the multitile test. On any other test (both current and future) all of
the fields here are just uninitialized.
If we're adding general information to the shared device library code,
then it should work for all tests. If it's only for one specific test,
then it doesn't really belong in the library in the first place.
> +
> /** @gt_list: bitmask of all memory regions */
> uint64_t memory_regions;
>
> @@ -75,13 +97,22 @@ struct xe_device {
> ++__class)
> #define xe_for_each_gt(__fd, __gt) \
> for (__gt = 0; __gt < xe_number_gt(__fd); ++__gt)
> -
> +#define xe_for_each_tile(tile__, xe__, id__) \
> + for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
> + for_each_if((tile__) = &(xe__)->tiles[(id__)])
> +#define xe_for_each_remote_tile(tile__, xe__, id__) \
> + for ((id__) = 0; (id__) < (xe__)->info.tile_count; (id__)++) \
> + for_each_if((tile__) = &(xe__)->tiles[(id__)])
What's the difference between 'xe_for_each_tile' and
'xe_for_each_remote_tile?' They seem to be identical. And the remote
version isn't used anywhere.
> +#define xe_for_each_device_gt(gt__, xe__, id__) \
> + for ((id__) = 0; (id__) < (xe__)->info.gt_count; (id__)++) \
> + for_each_if((gt__) = xe_device_get_gt((xe__), (id__)))
> #define xe_for_each_mem_region(__fd, __memreg, __r) \
> for (uint64_t igt_unique(__i) = 0; igt_unique(__i) < igt_fls(__memreg); igt_unique(__i)++) \
> for_if(__r = (__memreg & (1ull << igt_unique(__i))))
>
> #define XE_IS_CLASS_SYSMEM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_SYSMEM)
> #define XE_IS_CLASS_VRAM(__region) ((__region)->mem_class == DRM_XE_MEM_REGION_CLASS_VRAM)
> +#define MEDIA_VER(xe) ((xe)->info.media_verx100 / 100)
>
> /*
> * Max possible engine instance in drm_xe_engine_class_instance::engine_instance. Only
> @@ -89,6 +120,11 @@ struct xe_device {
> */
> #define XE_MAX_ENGINE_INSTANCE 9
>
> +/*
> + * Max possible GT per Tile
> + */
> +#define XE_MAX_GT_PER_TILE 2
> +
> unsigned int xe_number_gt(int fd);
> uint64_t all_memory_regions(int fd);
> uint64_t system_memory(int fd);
> diff --git a/tests/intel/xe_multi_tile.c b/tests/intel/xe_multi_tile.c
> new file mode 100644
> index 000000000..c5b2e0472
> --- /dev/null
> +++ b/tests/intel/xe_multi_tile.c
> @@ -0,0 +1,423 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2025 Intel Corporation
> + *
> + * Authors:
> + * Nishit Sharma <nishit.sharma@intel.com>
> + */
> +
> +#include <dirent.h>
> +#include <fcntl.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +
> +#include "igt.h"
> +#include "igt_sysfs.h"
> +
> +#include "xe_drm.h"
> +#include "xe/xe_ioctl.h"
> +#include "xe/xe_query.h"
> +
> +/**
> + * TEST: Test to verify if multi-tile support available in platform
The description here is confusing. A platform may or may not have
multiple tiles, and either case is fine (not a problem). So what are we
actually testing here? What kind of driver bug are we trying to catch
by adding this new test?
> + * Category: Core
> + * Mega feature: General Core features
> + * Sub-category: Tile/GT operations
> + * Functionality: multi-tile
> + * Test category: functionality test
> + */
> +
> +/**
> + * SUBTEST: multi-tile-info
> + * Description: Test gathers Tile_ID/s and GT_ID/s, update internal struct
As above, we should describe what the test is actually checking, not
just the steps it happens to take internally while doing that. I.e.,
what are we checking to decide between "PASS" and "FAIL?"
We already have tests for "make sure the information reported by the
query ioctl looks sane" in tests/intel/xe_query.c. If this test is just
going to exercise the query interface, then why aren't we extending the
existing test? If this test is trying to test something else (some
specific aspect of multi-tile execution), then we need to explain what
that is, and create subtests that match the specific behaviors we're
trying to test.
> + */
> +
> +struct xe_gt *xe_gt_alloc(struct drm_xe_tile *tile);
> +int xe_tile_init(struct drm_xe_tile *tile, struct xe_device *xe, uint8_t id);
> +struct drm_xe_tile *xe_device_get_root_tile(struct xe_device *xe);
> +struct xe_gt *xe_tile_get_gt(struct drm_xe_tile *tile, u8 gt_id);
> +struct xe_gt *xe_device_get_gt(struct xe_device *xe_dev, uint8_t gt_id);
> +
> +/*
> + * xe_gt_list: Get the list of gt%d, tile%d and count from driver
> + * @fd: GPU device descriptor
> + *
> + * Function gets the count of gt available in device
> + * including other information such as gt count, graphics ip version
> + *
> + * Return: Returns drm_xe_query_gt_list pointer
> + */
> +struct drm_xe_query_gt_list *xe_gt_list(int fd)
> +{
> + struct drm_xe_query_gt_list *gt_list;
> + struct drm_xe_device_query query = {
> + .extensions = 0,
> + .query = DRM_XE_DEVICE_QUERY_GT_LIST,
> + .size = 0,
> + .data = 0,
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
> + igt_assert_neq(query.size, 0);
> +
> + gt_list = malloc(query.size);
> + igt_assert(gt_list);
> +
> + query.data = to_user_pointer(gt_list);
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query), 0);
> +
> + return gt_list;
> +}
> +/*
> + * xe_gt_alloc: Memory allocation for gt struct and initializing
> + * struct drm_xe_tile as per gt
> + * @tile *: Tile structure
> + *
> + * This allocates memory per GT available on tile and assigns corresponding tile address
> + * to corresponding gt
> + *
> + * Return: Returns gt structure pointer
> + */
> +struct xe_gt *xe_gt_alloc(struct drm_xe_tile *tile)
> +{
> + struct xe_gt *gt;
> +
> + gt = malloc(sizeof(*gt));
> + igt_assert(gt);
> +
> + gt->tile = tile;
> + return gt;
> +}
> +/**
> + * xe_tile_init - Initialize the tile structure and allocates memmory for primary GT
> + * @tile: Tile to initialize
> + * @xe: Parent Xe device
> + * @id: Tile ID
> + *
> + * Initializes per-tile resources.
> + *
> + * Returns: 0 on success, assert if no memory allocation.
> + */
> +int xe_tile_init(struct drm_xe_tile *tile, struct xe_device *xe, uint8_t id)
> +{
> + tile->xe = xe;
> + tile->id = id;
> +
> + tile->primary_gt = xe_gt_alloc(tile);
> + igt_assert(tile->primary_gt);
> +
> + return 0;
> +}
> +/**
> + * xe_device_get_root_tile: Returns address of root tile
> + * @xe: GPU Device structure which holds information about tile
> + * available in system
> + *
> + * Return: root tile address
> + */
> +struct drm_xe_tile *xe_device_get_root_tile(struct xe_device *xe)
> +{
> + return &xe->tiles[0];
> +}
> +/**
> + * xe_tile_get_gt: Return address gt struct
> + * @tile *: Tile associated with gt
> + * @gt_id: gt%d
> + *
> + * Returns: Based on gt_id passed xe_gt address returned which
> + * can be media_gt or primary gt
> + */
> +struct xe_gt *xe_tile_get_gt(struct drm_xe_tile *tile, u8 gt_id)
> +{
> + igt_assert_f(gt_id <= XE_MAX_GT_PER_TILE, "gt_id greater than defined XE_MAX_GT_PER_TILE");
> +
> + return gt_id ? tile->media_gt : tile->primary_gt;
> +}
> +/**
> + * @xe_dev: GPU Device structure which holds information about tile
> + * @gt_id: gt%d
> + *
> + * Returns: gt struct address based on media version available in platform
> + */
> +struct xe_gt *xe_device_get_gt(struct xe_device *xe_dev, uint8_t gt_id)
> +{
> + struct drm_xe_tile *root_tile = xe_device_get_root_tile(xe_dev);
> + struct xe_gt *gt;
> +
> + if (MEDIA_VER(xe_dev) >= 13)
> + gt = xe_tile_get_gt(root_tile, gt_id);
> + else
> + gt = xe_dev->tiles[gt_id].primary_gt;
> +
> + igt_assert(gt);
> +
> + return gt;
> +}
> +/**
> + * @xe_dev: GPU Device structure which holds information about tile
> + * @gt_id: gt%d
> + *
> + * Check gt%d passed available or not on tile%d
> + *
> + * Return: None
> + */
> +static void igt_check_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
> +{
> + uint8_t id;
> + struct drm_xe_tile *tile;
> + struct xe_gt *gt;
> +
> + xe_for_each_device_gt(gt, xe_dev, id) {
> + tile = gt->tile;
> + if(gt_id == gt->info.id)
> + {
> + igt_info("GT ID :%d available in Tile :tile%d\n",
> + gt_id, tile->id);
> + }
> + }
> +}
This function didn't actually check anything; all it did was print some
debug output on the console (which isn't something we'll even look at in
CI if the test isn't reporting a failure).
> +/**
> + * @xe_dev: GPU Device structure which holds information about tile
> + * @gt_id: gt%d
> + *
> + * To query gt%d available in tile%d by iterating over list of tiles available
> + *
> + * Returns: None
> + */
> +static void igt_query_gt_per_tile(struct xe_device *xe_dev, uint8_t gt_id)
> +{
> + struct drm_xe_tile *tile;
> + struct xe_gt *gt;
> +
> + xe_for_each_tile(tile, xe_dev, gt_id) {
> + gt = tile->primary_gt;
> +
> + if(MEDIA_VER(xe_dev) >= 12)
> + gt = tile->media_gt;
> +
> + igt_info("Inside GT Id :%d GT type :%d GT count :%d for Tile ID :%d GT count in Tile :%d\n",
> + gt->info.id, gt->info.type, gt->info.gt_count, tile->id, tile->gt_count);
> + }
> +}
> +/**
> + * igt_show_device_gt: To show gt availale on GPU device
> + * @xe_dev: GPU Device structure which holds information about tile
> + * @fd: GPU device descriptor
> + *
> + * Show GT%d available on device
> + *
> + * Return: None
> + */
> +static void igt_show_device_gt(struct xe_device *xe_dev, int fd)
> +{
> + struct drm_xe_tile *tile;
> + struct xe_gt *gt;
> +
> + uint8_t id;
> +
> + xe_for_each_device_gt(gt, xe_dev, id) {
> + tile = gt->tile;
> + igt_info("GT Id :%d GT type :%d Tile ID :%d\n",
> + gt->info.id, gt->info.type, tile->id);
> + }
> +}
> +/**
> + * igt_gt_init_per_tile: Initialize xe_gt structure per gt%d and per tile%d
> + * @xe_dev: GPU Device structure which holds information about tile
> + * @fd: GPU device descriptor
> + *
> + * Returns: 0 in case of success or assert
> + */
> +static uint8_t igt_gt_init_per_tile(struct xe_device *xe_dev, int fd)
> +{
> + uint8_t gt_id = 0;
> + struct drm_xe_tile *tile;
> + struct xe_gt *gt;
> + int ip_version, media_version;
> + char name[100];
> + FILE *file;
> +
> + igt_info("per Tile initialization\n");
> +
> + xe_for_each_tile(tile, xe_dev, gt_id) {
> + int err;
> + err = xe_tile_init(tile, xe_dev, gt_id);
> + igt_assert_eq(err, 0);
> + }
> +
> + xe_for_each_tile(tile, xe_dev, gt_id) {
> + gt = tile->primary_gt;
> + //new_gt = gt;
> + gt->info.id = xe_dev->info.gt_count++;
> + gt->info.type= XE_GT_TYPE_MAIN;
> + gt->info.gt_count++;
> + tile->gt_count++;
> +
> + file = fopen("/sys/kernel/debug/dri/0/info", "r");
> + igt_assert(file);
> +
> + while (fscanf(file, "%s %d", name, &ip_version) == 1) {
> + ip_version = -1;
> + }
> + while (fscanf(file, "%s %d", name, &media_version) == 1) {
> + media_version = -1;
> + }
If we're trying to get the graphics and media versions, then it would be
best to use the official query uapi for that, rather than the unofficial
debugfs output. Switching over to that is something that needs to
happen throughout our IGT Xe test codebase; I believe Sai Teja is
working on that at the moment.
> +
> + fclose(file);
> +
> + xe_dev->info.graphics_verx100 = ip_version;
> + xe_dev->info.media_verx100 = media_version;
> +
> + if (MEDIA_VER(xe_dev) < 13)
> + continue;
> +
> + /*
> + * Allocate and setup media GT for platforms with standalone
> + * media.
> + *
> + */
> + tile->media_gt = xe_gt_alloc(tile);
> + igt_assert(tile->media_gt);
> + gt->info.type = XE_GT_TYPE_MEDIA;
> + gt->info.id = xe_dev->info.gt_count++;
> + gt->info.gt_count++;
> + tile->gt_count++;
> + }
> +
> + return 0;
> +}
> +/**
> + * igt_check_missing_tile_sysfs: Checking if tile missing or out of order in system
> + * @xe_device: GPU Device structure which holds information about tile
> + * @fd: Device descriptor
> + *
> + * This opens the sysfs tile directory corresponding to device and tile for use
> + * The mis_tile_id[] contains tile%d which is checked with sysfs whether entry is present
> + * or not. E.g. After tile2 user get tile4, tile3 is missing which will be checked in sysfs path
> + *
> + * Returns: None
> + */
> +static void igt_check_missing_tile_sysfs(struct xe_device *xe_dev,
> + int fd)
> +{
> + char path[96];
> +
> + igt_info("Checking missing tiles with sysfs\n");
> +
> + for(int mis = 0; mis < xe_dev->info.mis_tile_count; mis++) {
> + xe_sysfs_tile_path(fd, xe_dev->info.mis_tile_id[mis], path, sizeof(path));
> + }
> +
> + igt_assert_f(xe_dev->info.mis_tile_count < 0, "No Tile entry in sysfs found.");
> +}
> +/**
> + * igt_check_if_missingtile: Checking if tile missing by iterating over
> + * filled mis tile array
> + * @xe_dev: GPU Device structure which holds information about tile
> + * fd: GPU device descriptor
> + *
> + * Returns: None
> + */
> +static void igt_check_if_missingtile(struct xe_device *xe_dev, int fd)
> +{
> + igt_info("Checking missing/out of order tiles\n");
> +
> + for(int i= 0; i < xe_dev->info.mis_tile_count; i++){
> + igt_warn("Tile :%d out of order/missing\n",
> + xe_dev->info.mis_tile_id[i]);
> + }
> +}
> +/**
> + * igt_get_tile_count: To get count of tile/s available in system,
> + * Getting missing tile and tle count if any
> + * @xe_dev: GPU Device structure which holds information about tile
> + * @fd: Device descriptor
> + * gt_list: list of gt%d and relavant information returned from Driver via IOCTL
> + *
> + * Return: Tile count
> + */
> +static uint8_t igt_get_tile_count(struct xe_device *xe_dev, int fd,
> + struct drm_xe_query_gt_list *gt_list)
> +{
> + int prev_tile = -1, tile_id;
> + uint8_t tile_mis_count = -1;
> +
> + for(int index = 0; index < gt_list->num_gt; index++) {
> + tile_id = gt_list->gt_list[index].tile_id;
> + if(prev_tile != tile_id)
> + {
> + if(++tile_mis_count != tile_id) {
> + xe_dev->info.tile_unavailable = true;
> + xe_dev->info.mis_tile_id[xe_dev->info.mis_tile_count++] = tile_mis_count;
> + }
> + prev_tile = tile_id;
> + xe_dev->info.tile_count++;
> + }
> + xe_dev->info.tile_unavailable = false;
> + }
> +
> + return xe_dev->info.tile_count;
> +}
> +
> +igt_main
> +{
> + int fd;
> + struct drm_xe_query_gt_list *gt_list;
> + struct xe_device *xe_dev;
> + struct drm_xe_tile *tile;
> + uint8_t gt_count;
> + uint8_t gt_arr[] = {0,1,2,3,4,5,6,7,8};
> +
> + igt_fixture {
> + fd = drm_open_driver(DRIVER_XE);
> + xe_dev = xe_device_get(fd);
> + }
> +
> + tile = malloc(sizeof(*tile));
> + igt_assert(tile);
> +
> + igt_subtest("multi-tile-info") {
> + /** get gt information from driver using ioctl **/
> + gt_list = xe_gt_list(fd);
> + /** store pointer returned from driver which have gt information **/
> + tile->gt_list = gt_list;
> +
> + /** Get tile count, initialize flag to check if any tile missing
> + * Fill internal struct
> + */
> + gt_count = igt_get_tile_count(xe_dev, fd, gt_list);
> + igt_assert_neq(gt_count, 0);
> + igt_info("Tiles :%d available in platform\n", gt_count);
> +
> + /** check if multi-tile supported in platform */
> + igt_assert_f(xe_dev->info.tile_count > 1,
> + "Multi-Tile not supported in platform :%d\n",
> + xe_dev->info.tile_count);
We shouldn't fail here. It's perfectly legal for platforms to not have
multiple tiles (in fact that's the usual case). If a test isn't
relevant on platforms without a certain configuration, we should be
using igt_require/igt_skip to make the test skip rather than fail.
> +
> + /************* Per Tile Initilization ***********/
The comment style in this file is a bit crazy. We should just follow
standard comment style and eliminate all the extra asterisks.
> + igt_assert_eq(igt_gt_init_per_tile(xe_dev, fd), 0);
> +
> + /******** Condition to check if any tile missing/out of order *****/
> + if (xe_dev->info.tile_unavailable)
> + igt_check_if_missingtile(xe_dev, fd);
This (and a bunch of the other functions called here) don't actually do
any checking. All they do is print messages on the console. The point
of IGT tests is to return pass/fail for various actions. If we wanted
something to just print output, then that would be more appropriate for
the tools/ folder rather than the tests/ folder. Remember that IGT
mostly gets used in CI, run among hundreds of other tests; if we're not
returning failure results, nobody is even going to look at the log
output for an individual test.
> +
> + /******* Checking missing/out of order tile comparing with sysfs ***/
> + if (xe_dev->info.tile_unavailable)
> + igt_check_missing_tile_sysfs(xe_dev, fd);
> +
> + /****** Display GT information on GPU Device *******/
> + igt_show_device_gt(xe_dev, fd);
> +
> + /****** Query GT per Tile *****/
> + igt_query_gt_per_tile(xe_dev, fd);
> +
> + /***** Checking GT exist, if exist on which tile or doesn't exist ******/
> + for(int gt_id = 0; gt_id < sizeof(gt_arr); gt_id++)
> + igt_check_gt_per_tile(xe_dev, gt_id);
> + }
> +
> + igt_fixture {
> + drm_close_driver(fd);
> + }
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index a0f984b34..9def89f38 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -294,6 +294,7 @@ intel_xe_progs = [
> 'xe_exec_reset',
> 'xe_exec_sip',
> 'xe_exec_store',
> + 'xe_multi_tile',
The whitespace here doesn't match (you're using spaces and surrounding
code is using tabs).
At a high level it seems like we don't have a single, clear goal with
this patch. It seems like the patch here contains bits of three
different things all kind of mixed together, but none of them are really
complete or explained:
* Update IGT's libraries to obtain more information about the device
and make it available to any test(s) interested in using that
information.
* Create new test(s) that exercise a specific behavior to make sure the
driver is operating as expected and doesn't have any bugs.
* Dump information about a device for interactive use.
I think the first step is to clearly explain the motivation of making
changes (i.e., what is IGT lacking today?) and what the end goal of your
work is. If there are multiple goals, then those likely need to be
accomplished as separate patches and/or separate series.
Matt
> 'xe_exec_threads',
> 'xe_exercise_blt',
> 'xe_fault_injection',
> --
> 2.43.0
>
--
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-03-07 23:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-31 14:27 [PATCH i-g-t] tests/intel/xe_multi_tile: Multi-Tile support in IGT nishit.sharma
2025-01-31 17:11 ` ✗ GitLab.Pipeline: warning for " Patchwork
2025-02-05 22:26 ` [PATCH i-g-t] " Matt Roper
-- strict thread matches above, loose matches on Subject: below --
2025-02-14 12:03 nishit.sharma
2025-02-15 1:11 nishit.sharma
2025-02-17 14:20 ` Kamil Konieczny
2025-02-28 9:22 nishit.sharma
2025-03-07 23:19 ` Matt Roper
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox