* [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test
@ 2026-05-12 21:51 Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 1/8] Introduce dmem driver and implement Xe support Thadeu Lima de Souza Cascardo
` (9 more replies)
0 siblings, 10 replies; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
This work builds on top of Thomas Hellström's patches at [1].
Besides the case of eviction when setting dmem.max, which still needs
support from [2], there are other cases for testing dmem behavior and
potential regressions. Thomas' patches lay over the groundwork for this,
while this patchset addes one basic test of checking current usage and that
drivers respect max setting when no eviction is taking place yet.
This patchset also introduces a driver layer such that the same tests can
work with different drivers. amdgpu support is here added too.
[1] https://patchwork.freedesktop.org/series/163935/
Thadeu Lima de Souza Cascardo (8):
Introduce dmem driver and implement Xe support
Adjust xe_cgroups test to use igt_dmem_driver
Make xe_cgroup test a generic test
amdgpu: add amdgpu_cgroup_region_name
igt_dmem_driver: add amdgpu support
dmem: add test for current/max
dmem: only check for dmem availability once
dmem: get region once per driver
lib/amdgpu/amd_dmem.c | 94 ++++++++++
lib/amdgpu/amd_memory.c | 25 +++
lib/amdgpu/amd_memory.h | 2 +
lib/igt_dmem_driver.h | 25 +++
lib/meson.build | 2 +
lib/xe/xe_dmem.c | 145 +++++++++++++++
tests/drv_dmem_cgroups.c | 390 +++++++++++++++++++++++++++++++++++++++
tests/intel/xe_cgroups.c | 296 -----------------------------
tests/meson.build | 2 +-
9 files changed, 684 insertions(+), 297 deletions(-)
create mode 100644 lib/amdgpu/amd_dmem.c
create mode 100644 lib/igt_dmem_driver.h
create mode 100644 lib/xe/xe_dmem.c
create mode 100644 tests/drv_dmem_cgroups.c
delete mode 100644 tests/intel/xe_cgroups.c
--
2.47.3
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH i-g-t 1/8] Introduce dmem driver and implement Xe support
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 2/8] Adjust xe_cgroups test to use igt_dmem_driver Thadeu Lima de Souza Cascardo
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
In order to be reuse the same dmem tests with multiple drivers, we need to
abstract a few operations. That includes getting the region name, and
allocating and releasing VRAM. As there is some initialization also when
multiple allocations are done, also provide init and deinit functions.
The Xe implementation is based on the equivalente operations from
xe_cgroups.c.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
lib/igt_dmem_driver.h | 24 +++++++
lib/meson.build | 1 +
lib/xe/xe_dmem.c | 145 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 170 insertions(+)
create mode 100644 lib/igt_dmem_driver.h
create mode 100644 lib/xe/xe_dmem.c
diff --git a/lib/igt_dmem_driver.h b/lib/igt_dmem_driver.h
new file mode 100644
index 000000000000..869356fbf2c2
--- /dev/null
+++ b/lib/igt_dmem_driver.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2026 Valve Corporation
+ * Authors:
+ * Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+ */
+
+#ifndef __IGT_DMEM_DRIVER_H__
+#define __IGT_DMEM_DRIVER_H__
+
+#include <stdlib.h>
+
+struct igt_dmem_driver {
+ const char *name;
+ char * (*get_region_name)(int fd);
+ int (*init)(void **ctx, int fd, int max_bo);
+ void (*deinit)(void *ctx);
+ int (*allocate_vram)(void *ctx, int n_bo, size_t len);
+ void (*free_vram)(void *ctx, int n_bo, size_t len);
+};
+
+extern const struct igt_dmem_driver xe_dmem_driver;
+
+#endif
diff --git a/lib/meson.build b/lib/meson.build
index fb4679ffdfc1..269f3b9f0af8 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -122,6 +122,7 @@ lib_sources = [
'igt_msm.c',
'igt_dsc.c',
'igt_hook.c',
+ 'xe/xe_dmem.c',
'xe/xe_gt.c',
'xe/xe_ioctl.c',
'xe/xe_legacy.c',
diff --git a/lib/xe/xe_dmem.c b/lib/xe/xe_dmem.c
new file mode 100644
index 000000000000..977b4c5f168f
--- /dev/null
+++ b/lib/xe/xe_dmem.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2026 Valve Corporation
+ * Authors:
+ * Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+ */
+
+#include "igt_dmem_driver.h"
+
+#include <errno.h>
+
+#include "igt.h"
+#include "igt_cgroup.h"
+#include "xe_drm.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+
+static char * xe_dmem_get_region_name(int fd)
+{
+ uint64_t vram_region = 0;
+ uint64_t region;
+ char *cg_region;
+
+ /* Find first VRAM region */
+ xe_for_each_mem_region(fd, all_memory_regions(fd), region) {
+ if (xe_region_class(fd, region) == DRM_XE_MEM_REGION_CLASS_VRAM) {
+ vram_region = region;
+ break;
+ }
+ }
+ if (!vram_region)
+ return NULL;
+
+ cg_region = xe_cgroup_region_name(fd, vram_region);
+
+ return cg_region;
+}
+
+struct xe_dmem_ctx {
+ int fd;
+ uint32_t vm;
+ uint32_t *handles;
+ uint64_t addr;
+ uint64_t vram_region;
+};
+
+#define BIND_BASE 0x100000000ULL /* 4 GiB VA base */
+
+static int xe_dmem_init(void **ctx, int fd, int max_bo)
+{
+ struct xe_dmem_ctx *xe_ctx;
+ uint64_t region;
+
+ xe_ctx = malloc(sizeof(*xe_ctx));
+ if (!xe_ctx)
+ return -ENOMEM;
+
+ xe_ctx->handles = calloc(max_bo, sizeof(xe_ctx->handles[0]));
+ if (!xe_ctx->handles)
+ goto out;
+
+ xe_ctx->vram_region = 0;
+ /* Find first VRAM region */
+ xe_for_each_mem_region(fd, all_memory_regions(fd), region) {
+ if (xe_region_class(fd, region) == DRM_XE_MEM_REGION_CLASS_VRAM) {
+ xe_ctx->vram_region = region;
+ break;
+ }
+ }
+ if (!xe_ctx->vram_region)
+ goto out;
+
+ xe_ctx->addr = BIND_BASE;
+ xe_ctx->fd = fd;
+
+ xe_ctx->vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
+
+ *ctx = xe_ctx;
+
+ return 0;
+
+out:
+ if (xe_ctx->handles)
+ free(xe_ctx->handles);
+ free(xe_ctx);
+
+ return -ENOMEM;
+}
+
+static void xe_dmem_deinit(void *ctx)
+{
+ struct xe_dmem_ctx *xe_ctx = ctx;
+
+ xe_vm_destroy(xe_ctx->fd, xe_ctx->vm);
+ free(xe_ctx->handles);
+ free(xe_ctx);
+}
+
+static int xe_dmem_allocate_vram(void *ctx, int n_bo, size_t len)
+{
+ struct xe_dmem_ctx *xe_ctx = ctx;
+ uint32_t handle;
+ int err;
+
+ err = __xe_bo_create(xe_ctx->fd, 0, len, xe_ctx->vram_region,
+ DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING,
+ NULL, &handle);
+ if (err)
+ goto out;
+
+ xe_ctx->handles[n_bo] = handle;
+
+ err = __xe_vm_bind_lr_sync(xe_ctx->fd, xe_ctx->vm, handle, 0,
+ xe_ctx->addr, len, 0);
+ if (err)
+ goto out;
+
+ xe_ctx->addr += len;
+
+out:
+ return err;
+}
+
+static void xe_dmem_free_vram(void *ctx, int n_bo, size_t len)
+{
+ struct xe_dmem_ctx *xe_ctx = ctx;
+ uint64_t addr = BIND_BASE;
+ int i;
+ for (i = 0; i < n_bo; i++) {
+ if (xe_ctx->handles[i]) {
+ xe_vm_unbind_lr_sync(xe_ctx->fd, xe_ctx->vm, 0, addr, len);
+ gem_close(xe_ctx->fd, xe_ctx->handles[i]);
+ }
+ addr += len;
+ }
+}
+
+const struct igt_dmem_driver xe_dmem_driver = {
+ .name = "xe",
+ .get_region_name = xe_dmem_get_region_name,
+ .init = xe_dmem_init,
+ .deinit = xe_dmem_deinit,
+ .allocate_vram = xe_dmem_allocate_vram,
+ .free_vram = xe_dmem_free_vram,
+};
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH i-g-t 2/8] Adjust xe_cgroups test to use igt_dmem_driver
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 1/8] Introduce dmem driver and implement Xe support Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-13 15:18 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 3/8] Make xe_cgroup test a generic test Thadeu Lima de Souza Cascardo
` (7 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
Using the driver should not have any functional changes.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
tests/intel/xe_cgroups.c | 69 ++++++++--------------------------------
1 file changed, 14 insertions(+), 55 deletions(-)
diff --git a/tests/intel/xe_cgroups.c b/tests/intel/xe_cgroups.c
index 08cf8e3bdc5b..9ff8d46570ab 100644
--- a/tests/intel/xe_cgroups.c
+++ b/tests/intel/xe_cgroups.c
@@ -25,6 +25,7 @@
#include "igt.h"
#include "igt_aux.h"
#include "igt_cgroup.h"
+#include "igt_dmem_driver.h"
#include "xe_drm.h"
#include "xe/xe_ioctl.h"
#include "xe/xe_query.h"
@@ -110,27 +111,14 @@ static uint64_t wait_for_usage_drop(struct igt_cgroup *cg, const char *region,
return current;
}
-static int fill_vram(int fd, uint32_t vm, uint64_t vram_region,
- uint32_t *handles, int max_bo)
+static int fill_vram(struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
{
- uint32_t handle;
- uint64_t addr = BIND_BASE;
int n_bo, err = 0;
for (n_bo = 0; n_bo < max_bo; n_bo++) {
- err = __xe_bo_create(fd, 0, BO_SIZE, vram_region,
- DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING,
- NULL, &handle);
+ err = drv->allocate_vram(ctx, n_bo, BO_SIZE);
if (err)
break;
-
- handles[n_bo] = handle;
-
- err = __xe_vm_bind_lr_sync(fd, vm, handle, 0, addr, BO_SIZE, 0);
- if (err)
- break;
-
- addr += BO_SIZE;
}
igt_assert_f(err == -ENOMEM || err == -ENOSPC,
@@ -140,47 +128,20 @@ static int fill_vram(int fd, uint32_t vm, uint64_t vram_region,
return n_bo;
}
-static void unfill_vram(int fd, uint32_t vm, uint32_t *handles, int n_bo)
-{
- uint64_t addr = BIND_BASE;
- int i;
-
- for (i = 0; i < n_bo; i++) {
- if (handles[i]) {
- xe_vm_unbind_lr_sync(fd, vm, 0, addr, BO_SIZE);
- gem_close(fd, handles[i]);
- }
- addr += BO_SIZE;
- }
- free(handles);
-}
-
-static void test_write_eviction(int fd, unsigned int flags)
+static void test_write_eviction(int fd, unsigned int flags, struct igt_dmem_driver *drv)
{
+ void *ctx;
struct igt_cgroup *cg;
char *cg_region;
- uint32_t vm;
- uint64_t vram_region = 0;
- uint64_t region;
- uint32_t *handles = NULL;
int n_bo = 0, max_bo;
uint64_t current, capacity, cg_max, limit, after;
- int set_err;
+ int set_err, err;
/* Check dmem cgroup controller is available before doing anything else */
igt_require_f(igt_cgroup_dmem_available(),
"dmem cgroup controller not available (no cgroup v2 or no registered regions)\n");
- /* Find first VRAM region */
- xe_for_each_mem_region(fd, all_memory_regions(fd), region) {
- if (xe_region_class(fd, region) == DRM_XE_MEM_REGION_CLASS_VRAM) {
- vram_region = region;
- break;
- }
- }
- igt_require_f(vram_region, "No VRAM region found on this device\n");
-
- cg_region = xe_cgroup_region_name(fd, vram_region);
+ cg_region = drv->get_region_name(fd);
igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
igt_cgroup_dmem_get_capacity(cg_region, &capacity);
@@ -204,13 +165,12 @@ static void test_write_eviction(int fd, unsigned int flags)
igt_cgroup_move_current(cg);
igt_cgroup_dmem_set_max(cg, cg_region, cg_max);
- vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
-
max_bo = (cg_max / BO_SIZE) + 8; /* headroom for overcommit */
- handles = calloc(max_bo, sizeof(*handles));
- igt_assert(handles);
- n_bo = fill_vram(fd, vm, vram_region, handles, max_bo);
+ err = drv->init(&ctx, fd, max_bo);
+ igt_assert_f(!err, "Failed to initialize driver");
+
+ n_bo = fill_vram(drv, ctx, fd, max_bo);
igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
@@ -261,9 +221,8 @@ static void test_write_eviction(int fd, unsigned int flags)
/* Cleanup */
igt_cgroup_dmem_set_max(cg, cg_region, IGT_CGROUP_DMEM_MAX);
- unfill_vram(fd, vm, handles, n_bo);
- handles = NULL;
- xe_vm_destroy(fd, vm);
+ drv->free_vram(ctx, n_bo, BO_SIZE);
+ drv->deinit(ctx);
free(cg_region);
igt_cgroup_free(cg);
}
@@ -288,7 +247,7 @@ int igt_main()
for (int i = 0; subtests[i].name; i++)
igt_subtest(subtests[i].name)
- test_write_eviction(fd, subtests[i].flags);
+ test_write_eviction(fd, subtests[i].flags, &xe_dmem_driver);
igt_fixture() {
drm_close_driver(fd);
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH i-g-t 3/8] Make xe_cgroup test a generic test
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 1/8] Introduce dmem driver and implement Xe support Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 2/8] Adjust xe_cgroups test to use igt_dmem_driver Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-13 15:21 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 4/8] amdgpu: add amdgpu_cgroup_region_name Thadeu Lima de Souza Cascardo
` (6 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
It should not be driver specific anymore. Make it run for multiple drivers,
though there is still only Xe now.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
.../xe_cgroups.c => drv_dmem_cgroups.c} | 61 +++++++++++--------
tests/meson.build | 2 +-
2 files changed, 38 insertions(+), 25 deletions(-)
rename tests/{intel/xe_cgroups.c => drv_dmem_cgroups.c} (83%)
diff --git a/tests/intel/xe_cgroups.c b/tests/drv_dmem_cgroups.c
similarity index 83%
rename from tests/intel/xe_cgroups.c
rename to tests/drv_dmem_cgroups.c
index 9ff8d46570ab..6f4f779f3c2c 100644
--- a/tests/intel/xe_cgroups.c
+++ b/tests/drv_dmem_cgroups.c
@@ -4,13 +4,12 @@
*/
/**
- * TEST: xe_cgroups
- * DESCRIPTION: Tests exercising the dmem cgroup controller on xe devices.
+ * TEST: drv_dmem_cgroups
+ * DESCRIPTION: Tests exercising the dmem cgroup controller on devices.
* Category: Core
* Mega feature: General Core features
* Sub-category: cgroup
* FUNCTIONALITY: cgroup dmem controller
- * SUBSETS: xe
*/
#include <errno.h>
@@ -26,9 +25,6 @@
#include "igt_aux.h"
#include "igt_cgroup.h"
#include "igt_dmem_driver.h"
-#include "xe_drm.h"
-#include "xe/xe_ioctl.h"
-#include "xe/xe_query.h"
#define BO_SIZE SZ_128M
#define MAX_LIMIT ((uint64_t)4 * SZ_1G)
@@ -45,13 +41,12 @@
* DESCRIPTION:
* Create a dmem cgroup, move the current process into it and set the max
* device memory limit for the first VRAM region to 4 GiB. Then fill VRAM
- * by creating BOs with %DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING (so that the
- * physical allocation is deferred until VM_BIND) and binding them into an
- * LR VM until the cgroup limit is hit. Verify that the reported cgroup
- * current usage is within the expected range when the error occurs.
+ * by creating BOs.
+ * Verify that the reported cgroup current usage is within the expected
+ * range when the error occurs.
* Finally lower the max limit in 256 MiB steps and verify that the cgroup
* usage follows.
- * REQUIREMENTS: must run as root; xe device with at least one VRAM region
+ * REQUIREMENTS: must run as root; device with at least one VRAM region
*/
/**
@@ -61,7 +56,7 @@
* igt_fork_signal_helper() to verify that the dmem.max write path handles
* signal interruption correctly. A signal handler counts received signals
* and the count is reported as debug output at the end of the test.
- * REQUIREMENTS: must run as root; xe device with at least one VRAM region
+ * REQUIREMENTS: must run as root; device with at least one VRAM region
*/
static atomic_int signal_count;
@@ -111,7 +106,7 @@ static uint64_t wait_for_usage_drop(struct igt_cgroup *cg, const char *region,
return current;
}
-static int fill_vram(struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
+static int fill_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
{
int n_bo, err = 0;
@@ -128,7 +123,7 @@ static int fill_vram(struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
return n_bo;
}
-static void test_write_eviction(int fd, unsigned int flags, struct igt_dmem_driver *drv)
+static void test_write_eviction(int fd, unsigned int flags, const struct igt_dmem_driver *drv)
{
void *ctx;
struct igt_cgroup *cg;
@@ -161,7 +156,7 @@ static void test_write_eviction(int fd, unsigned int flags, struct igt_dmem_driv
install_sigcont_counter();
/* Create cgroup and move into it */
- cg = igt_cgroup_new("xe_cgroups_test");
+ cg = igt_cgroup_new("igt_cgroups_test");
igt_cgroup_move_current(cg);
igt_cgroup_dmem_set_max(cg, cg_region, cg_max);
@@ -236,20 +231,38 @@ static const struct {
{ }
};
+static const struct {
+ int driver_flag;
+ const struct igt_dmem_driver *driver;
+} drivers[] = {
+ { DRIVER_XE, &xe_dmem_driver },
+ { },
+};
+
int igt_main()
{
- int fd = -1;
-
igt_fixture() {
- fd = drm_open_driver(DRIVER_XE);
igt_require_f(getuid() == 0, "Test requires root\n");
}
- for (int i = 0; subtests[i].name; i++)
- igt_subtest(subtests[i].name)
- test_write_eviction(fd, subtests[i].flags, &xe_dmem_driver);
-
- igt_fixture() {
- drm_close_driver(fd);
+ for (int d = 0; drivers[d].driver; d++) {
+ igt_subtest_group() {
+ int fd = -1;
+ igt_fixture() {
+ fd = drm_open_driver(drivers[d].driver_flag);
+ igt_require_f(fd >= 0,
+ "No %s device found, skipping\n",
+ drivers[d].driver->name);
+ }
+
+ for (int i = 0; subtests[i].name; i++)
+ igt_subtest_f("%s-%s", drivers[d].driver->name, subtests[i].name)
+ test_write_eviction(fd, subtests[i].flags, drivers[d].driver);
+
+ igt_fixture() {
+ if (fd >= 0)
+ drm_close_driver(fd);
+ }
+ }
}
}
diff --git a/tests/meson.build b/tests/meson.build
index b4463a722361..deb049875b46 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -17,6 +17,7 @@ test_progs = [
'drm_mm',
'drm_read',
'drm_virtgpu',
+ 'drv_dmem_cgroups',
'fbdev',
'kms_3d',
'kms_addfb_basic',
@@ -292,7 +293,6 @@ intel_xe_progs = [
'xe_dma_buf_sync',
'xe_drm_fdinfo',
'xe_eu_stall',
- 'xe_cgroups',
'xe_evict',
'xe_evict_ccs',
'xe_exec_atomic',
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH i-g-t 4/8] amdgpu: add amdgpu_cgroup_region_name
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
` (2 preceding siblings ...)
2026-05-12 21:51 ` [PATCH i-g-t 3/8] Make xe_cgroup test a generic test Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 5/8] igt_dmem_driver: add amdgpu support Thadeu Lima de Souza Cascardo
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
The amdgpu dmem region name uses its PCI address, just like the one from
Xe, but there is only a single VRAM region.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
lib/amdgpu/amd_memory.c | 25 +++++++++++++++++++++++++
lib/amdgpu/amd_memory.h | 2 ++
2 files changed, 27 insertions(+)
diff --git a/lib/amdgpu/amd_memory.c b/lib/amdgpu/amd_memory.c
index 12fe23c65ab2..2da4a8a4baee 100644
--- a/lib/amdgpu/amd_memory.c
+++ b/lib/amdgpu/amd_memory.c
@@ -30,9 +30,11 @@
#include <amdgpu_drm.h>
#include <stdio.h>
#include <string.h>
+#include <limits.h>
#include <unistd.h>
#include <sys/mman.h>
#include <inttypes.h>
+#include "igt_device.h"
/**
*
@@ -679,6 +681,29 @@ bool virtual_free_memory(void *address, unsigned int size)
}
}
+/**
+ * amdgpu_cgroup_region_name() - Build the dmem cgroup region name for an amdgpu.
+ * @fd: amdgpu device fd.
+ *
+ * Constructs the full dmem cgroup region path for VRAM on the device
+ * identified by @fd. The returned string has the form
+ * ``drm/<pci-slot>/vram`` (e.g. ``drm/0000:03:00.0/vram``), matching
+ * the name registered by the kernel driver via drmm_cgroup_register_region().
+ *
+ * Return: A newly allocated string that the caller must free(), or %NULL if
+ * @region is not tracked by the dmem cgroup controller.
+ */
+char *amdgpu_cgroup_region_name(int fd)
+{
+ char pci_slot[NAME_MAX];
+ char *name;
+
+ igt_device_get_pci_slot_name(fd, pci_slot);
+
+ igt_assert(asprintf(&name, "drm/%s/vram", pci_slot) > 0);
+ return name;
+}
+
/**
* Wait for specific value in memory with timeout
*/
diff --git a/lib/amdgpu/amd_memory.h b/lib/amdgpu/amd_memory.h
index e26c85bc4b0a..de169e580c1b 100644
--- a/lib/amdgpu/amd_memory.h
+++ b/lib/amdgpu/amd_memory.h
@@ -105,6 +105,8 @@ void
bool
virtual_free_memory(void *address, unsigned int size);
+char *amdgpu_cgroup_region_name(int fd);
+
bool
wait_on_value(unsigned int *ptr, unsigned int expected);
#endif
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH i-g-t 5/8] igt_dmem_driver: add amdgpu support
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
` (3 preceding siblings ...)
2026-05-12 21:51 ` [PATCH i-g-t 4/8] amdgpu: add amdgpu_cgroup_region_name Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-13 15:26 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 6/8] dmem: add test for current/max Thadeu Lima de Souza Cascardo
` (4 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
Allocate a BO from VRAM domain. That will try to place BOs on VRAM, but may
fallback to GTT. That can still be tracked with dmem.current.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
lib/amdgpu/amd_dmem.c | 94 ++++++++++++++++++++++++++++++++++++++++
lib/igt_dmem_driver.h | 1 +
lib/meson.build | 1 +
tests/drv_dmem_cgroups.c | 6 ++-
4 files changed, 100 insertions(+), 2 deletions(-)
create mode 100644 lib/amdgpu/amd_dmem.c
diff --git a/lib/amdgpu/amd_dmem.c b/lib/amdgpu/amd_dmem.c
new file mode 100644
index 000000000000..1c0825af43b6
--- /dev/null
+++ b/lib/amdgpu/amd_dmem.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2026 Valve Corporation
+ * Authors:
+ * Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+ */
+
+#include "igt_dmem_driver.h"
+
+#include <errno.h>
+
+#include "igt.h"
+#include "igt_cgroup.h"
+#include "lib/amdgpu/amd_memory.h"
+
+struct amdgpu_dmem_ctx {
+ int fd;
+ amdgpu_device_handle device;
+ amdgpu_bo_handle *handles;
+};
+
+static int amdgpu_dmem_init(void **ctx, int fd, int max_bo)
+{
+ struct amdgpu_dmem_ctx *actx;
+ uint32_t major, minor;
+ int err = -ENOMEM;
+
+ actx = malloc(sizeof(*actx));
+ if (!actx)
+ return -ENOMEM;
+
+ actx->handles = calloc(max_bo, sizeof(actx->handles[0]));
+ if (!actx->handles)
+ goto out;
+
+ err = amdgpu_device_initialize(fd, &major, &minor, &actx->device);
+ if (err)
+ goto out;
+
+ *ctx = actx;
+
+ return 0;
+
+out:
+ if (actx->handles)
+ free(actx->handles);
+ free(actx);
+
+ return err;
+}
+
+static void amdgpu_dmem_deinit(void *ctx)
+{
+ struct amdgpu_dmem_ctx *actx = ctx;
+
+ amdgpu_device_deinitialize(actx->device);
+ free(actx->handles);
+ free(actx);
+}
+
+static int amdgpu_dmem_allocate_vram(void *ctx, int n_bo, size_t len)
+{
+ struct amdgpu_dmem_ctx *actx = ctx;
+ amdgpu_bo_handle handle;
+ int err;
+
+ err = amdgpu_bo_alloc_wrap(actx->device, len, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0, &handle);
+ if (err)
+ return err;
+
+ actx->handles[n_bo] = handle;
+
+ return 0;
+}
+
+static void amdgpu_dmem_free_vram(void *ctx, int n_bo, size_t len)
+{
+ struct amdgpu_dmem_ctx *actx = ctx;
+ int i;
+ for (i = 0; i < n_bo; i++) {
+ if (actx->handles[i])
+ amdgpu_bo_free(actx->handles[i]);
+ }
+}
+
+const struct igt_dmem_driver amdgpu_dmem_driver = {
+ .name = "amdgpu",
+ .get_region_name = amdgpu_cgroup_region_name,
+ .init = amdgpu_dmem_init,
+ .deinit = amdgpu_dmem_deinit,
+ .allocate_vram = amdgpu_dmem_allocate_vram,
+ .free_vram = amdgpu_dmem_free_vram,
+};
diff --git a/lib/igt_dmem_driver.h b/lib/igt_dmem_driver.h
index 869356fbf2c2..d43e5140d4f6 100644
--- a/lib/igt_dmem_driver.h
+++ b/lib/igt_dmem_driver.h
@@ -20,5 +20,6 @@ struct igt_dmem_driver {
};
extern const struct igt_dmem_driver xe_dmem_driver;
+extern const struct igt_dmem_driver amdgpu_dmem_driver;
#endif
diff --git a/lib/meson.build b/lib/meson.build
index 269f3b9f0af8..dd02d087875b 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -188,6 +188,7 @@ if libdrm_amdgpu.found()
'amdgpu/amd_mmd_shared.c',
'amdgpu/amd_jpeg_shared.c',
'amdgpu/amd_utils.c',
+ 'amdgpu/amd_dmem.c',
'amdgpu/amd_vcn_shared.c'
]
if libdrm_amdgpu.version().version_compare('> 2.4.99')
diff --git a/tests/drv_dmem_cgroups.c b/tests/drv_dmem_cgroups.c
index 6f4f779f3c2c..0e26b7e2bb9a 100644
--- a/tests/drv_dmem_cgroups.c
+++ b/tests/drv_dmem_cgroups.c
@@ -116,8 +116,9 @@ static int fill_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, int m
break;
}
- igt_assert_f(err == -ENOMEM || err == -ENOSPC,
- "Expected -ENOMEM or -ENOSPC, got %d (%s)\n",
+ /* amdgpu will fallback to GTT if it cannot allocate on VRAM */
+ igt_assert_f(err == -ENOMEM || err == -ENOSPC || err == 0,
+ "Expected -ENOMEM,-ENOSPC or success, got %d (%s)\n",
err, strerror(-err));
return n_bo;
@@ -236,6 +237,7 @@ static const struct {
const struct igt_dmem_driver *driver;
} drivers[] = {
{ DRIVER_XE, &xe_dmem_driver },
+ { DRIVER_AMDGPU, &amdgpu_dmem_driver },
{ },
};
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH i-g-t 6/8] dmem: add test for current/max
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
` (4 preceding siblings ...)
2026-05-12 21:51 ` [PATCH i-g-t 5/8] igt_dmem_driver: add amdgpu support Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-13 15:31 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 7/8] dmem: only check for dmem availability once Thadeu Lima de Souza Cascardo
` (3 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
Add a test that checks for current usage after VRAM allocation and release.
Set max to different values and track that current usage is not above max,
given some slack.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
tests/drv_dmem_cgroups.c | 136 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 133 insertions(+), 3 deletions(-)
diff --git a/tests/drv_dmem_cgroups.c b/tests/drv_dmem_cgroups.c
index 0e26b7e2bb9a..43331117854c 100644
--- a/tests/drv_dmem_cgroups.c
+++ b/tests/drv_dmem_cgroups.c
@@ -223,12 +223,142 @@ static void test_write_eviction(int fd, unsigned int flags, const struct igt_dme
igt_cgroup_free(cg);
}
+static int allocate_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo, size_t len)
+{
+ int n_bo, err = 0;
+ for (n_bo = 0; n_bo < max_bo; n_bo++) {
+ err = drv->allocate_vram(ctx, n_bo, len);
+ if (err)
+ break;
+ }
+ return err ?: n_bo;
+}
+
+static void test_current(int fd, unsigned int flags, const struct igt_dmem_driver *drv)
+{
+ struct igt_cgroup *cg;
+ char *cg_region;
+ void *ctx;
+ uint64_t current, capacity, cg_max;
+ int n_bo = 0, max_bo;
+ int err;
+
+ cg_region = drv->get_region_name(fd);
+ igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
+
+ /* Check dmem cgroup controller is available before doing anything else */
+ igt_require_f(igt_cgroup_dmem_available(),
+ "dmem cgroup controller not available (no cgroup v2 or no registered regions)\n");
+
+ igt_cgroup_dmem_get_capacity(cg_region, &capacity);
+ igt_require_f(capacity >= 4 * BO_SIZE,
+ "VRAM capacity (%"PRIu64" MiB) too small to test\n",
+ capacity / SZ_1M);
+
+ /*
+ * Use up to 4 GiB, or the full capacity if the device has less.
+ * Leave one BO_SIZE worth of headroom so the device isn't completely
+ * exhausted before the cgroup limit is hit.
+ */
+ cg_max = min(MAX_LIMIT, capacity - BO_SIZE);
+ cg_max = ALIGN_DOWN(cg_max, EVICT_STEP);
+
+ if (flags & TEST_INTERRUPTIBLE)
+ install_sigcont_counter();
+
+ /* Create cgroup and move into it */
+ cg = igt_cgroup_new("igt_cgroups_test");
+ igt_cgroup_move_current(cg);
+
+ max_bo = cg_max / BO_SIZE;
+
+ err = drv->init(&ctx, fd, max_bo);
+ igt_assert_f(!err, "Failed to initialize driver");
+
+ n_bo = allocate_vram(drv, ctx, fd, max_bo, BO_SIZE);
+ igt_assert_f(n_bo > 0, "failed to allocate VRAM\n");
+
+ igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
+ igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
+ "max = %"PRIu64" MiB\n",
+ current / SZ_1M, cg_max / SZ_1M);
+ igt_assert_f(current < cg_max + USAGE_SLACK && current > cg_max - USAGE_SLACK,
+ "current usage (%"PRIu64" MiB) is not within margin of allocation (%"PRIu64" MiB)\n",
+ current / SZ_1M, cg_max / SZ_1M);
+
+ drv->free_vram(ctx, n_bo, BO_SIZE);
+ sleep(1);
+
+ igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
+ igt_debug("After free: cgroup current = %"PRIu64" MiB, "
+ "max = %"PRIu64" MiB\n",
+ current / SZ_1M, cg_max / SZ_1M);
+ igt_assert_f(current < USAGE_SLACK,
+ "current usage (%"PRIu64" MiB) is not within margin (%d MiB)\n",
+ current / SZ_1M, USAGE_SLACK / SZ_1M);
+
+ igt_cgroup_dmem_set_max(cg, cg_region, 2 * BO_SIZE);
+
+ n_bo = allocate_vram(drv, ctx, fd, max_bo, BO_SIZE);
+ igt_assert_f(n_bo > 0, "failed to allocate VRAM\n");
+
+ igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
+ igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
+ "max = %"PRIu64" MiB\n",
+ current / SZ_1M, cg_max / SZ_1M);
+ igt_assert_f(current < 2 * BO_SIZE + USAGE_SLACK && current > 2 * BO_SIZE - USAGE_SLACK,
+ "current usage (%"PRIu64" MiB) is not within margin of allocation (%"PRIu64" MiB)\n",
+ current / SZ_1M, cg_max / SZ_1M);
+
+ drv->free_vram(ctx, n_bo, BO_SIZE);
+ sleep(1);
+
+ igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
+ igt_debug("After free: cgroup current = %"PRIu64" MiB, "
+ "max = %"PRIu64" MiB\n",
+ current / SZ_1M, cg_max / SZ_1M);
+ igt_assert_f(current < USAGE_SLACK,
+ "current usage (%"PRIu64" MiB) is not within margin (%d MiB)\n",
+ current / SZ_1M, USAGE_SLACK / SZ_1M);
+
+ igt_cgroup_dmem_set_max(cg, cg_region, 0);
+
+ n_bo = allocate_vram(drv, ctx, fd, max_bo, BO_SIZE);
+ igt_assert_f(n_bo != -ENOMEM, "VRAM allocation succeeded despite max set to 0\n");
+
+ igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
+ igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
+ "max = %"PRIu64" MiB\n",
+ current / SZ_1M, cg_max / SZ_1M);
+ igt_assert_f(current < USAGE_SLACK,
+ "current usage (%"PRIu64" MiB) is not within margin\n",
+ current / SZ_1M);
+
+ if (n_bo > 0)
+ drv->free_vram(ctx, n_bo, BO_SIZE);
+ sleep(1);
+
+ igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
+ igt_debug("After free: cgroup current = %"PRIu64" MiB, "
+ "max = %"PRIu64" MiB\n",
+ current / SZ_1M, cg_max / SZ_1M);
+ igt_assert_f(current < USAGE_SLACK,
+ "current usage (%"PRIu64" MiB) is not within margin (%d MiB)\n",
+ current / SZ_1M, USAGE_SLACK / SZ_1M);
+
+ drv->deinit(ctx);
+ free(cg_region);
+ igt_cgroup_free(cg);
+}
+
static const struct {
const char *name;
+ void (*test_fn)(int fd, unsigned int flags, const struct igt_dmem_driver *drv);
unsigned int flags;
} subtests[] = {
- { "write_eviction", 0 },
- { "write_eviction_interruptible", TEST_INTERRUPTIBLE },
+ { "current", test_current, 0 },
+ { "write_eviction", test_write_eviction, 0 },
+ { "write_eviction_interruptible", test_write_eviction, TEST_INTERRUPTIBLE },
{ }
};
@@ -259,7 +389,7 @@ int igt_main()
for (int i = 0; subtests[i].name; i++)
igt_subtest_f("%s-%s", drivers[d].driver->name, subtests[i].name)
- test_write_eviction(fd, subtests[i].flags, drivers[d].driver);
+ subtests[i].test_fn(fd, subtests[i].flags, drivers[d].driver);
igt_fixture() {
if (fd >= 0)
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH i-g-t 7/8] dmem: only check for dmem availability once
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
` (5 preceding siblings ...)
2026-05-12 21:51 ` [PATCH i-g-t 6/8] dmem: add test for current/max Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 8/8] dmem: get region once per driver Thadeu Lima de Souza Cascardo
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
While running multiple tests, we only need to check dmem is available at
the beginning.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
tests/drv_dmem_cgroups.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/tests/drv_dmem_cgroups.c b/tests/drv_dmem_cgroups.c
index 43331117854c..0791bb62d3a2 100644
--- a/tests/drv_dmem_cgroups.c
+++ b/tests/drv_dmem_cgroups.c
@@ -133,10 +133,6 @@ static void test_write_eviction(int fd, unsigned int flags, const struct igt_dme
uint64_t current, capacity, cg_max, limit, after;
int set_err, err;
- /* Check dmem cgroup controller is available before doing anything else */
- igt_require_f(igt_cgroup_dmem_available(),
- "dmem cgroup controller not available (no cgroup v2 or no registered regions)\n");
-
cg_region = drv->get_region_name(fd);
igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
@@ -246,10 +242,6 @@ static void test_current(int fd, unsigned int flags, const struct igt_dmem_drive
cg_region = drv->get_region_name(fd);
igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
- /* Check dmem cgroup controller is available before doing anything else */
- igt_require_f(igt_cgroup_dmem_available(),
- "dmem cgroup controller not available (no cgroup v2 or no registered regions)\n");
-
igt_cgroup_dmem_get_capacity(cg_region, &capacity);
igt_require_f(capacity >= 4 * BO_SIZE,
"VRAM capacity (%"PRIu64" MiB) too small to test\n",
@@ -375,6 +367,10 @@ int igt_main()
{
igt_fixture() {
igt_require_f(getuid() == 0, "Test requires root\n");
+ /* Check dmem cgroup controller is available before doing anything else */
+ igt_require_f(igt_cgroup_dmem_available(),
+ "dmem cgroup controller not available (no cgroup v2 or no registered regions)\n");
+
}
for (int d = 0; drivers[d].driver; d++) {
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH i-g-t 8/8] dmem: get region once per driver
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
` (6 preceding siblings ...)
2026-05-12 21:51 ` [PATCH i-g-t 7/8] dmem: only check for dmem availability once Thadeu Lima de Souza Cascardo
@ 2026-05-12 21:51 ` Thadeu Lima de Souza Cascardo
2026-05-12 22:27 ` [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
2026-05-13 8:06 ` Christian König
9 siblings, 0 replies; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 21:51 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Thadeu Lima de Souza Cascardo
It is expected that only the same region is going to be tested for, so
there is no use getting the region name for every test for a given driver.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
tests/drv_dmem_cgroups.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/tests/drv_dmem_cgroups.c b/tests/drv_dmem_cgroups.c
index 0791bb62d3a2..30f9caf3630c 100644
--- a/tests/drv_dmem_cgroups.c
+++ b/tests/drv_dmem_cgroups.c
@@ -124,18 +124,14 @@ static int fill_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, int m
return n_bo;
}
-static void test_write_eviction(int fd, unsigned int flags, const struct igt_dmem_driver *drv)
+static void test_write_eviction(int fd, char *cg_region, unsigned int flags, const struct igt_dmem_driver *drv)
{
void *ctx;
struct igt_cgroup *cg;
- char *cg_region;
int n_bo = 0, max_bo;
uint64_t current, capacity, cg_max, limit, after;
int set_err, err;
- cg_region = drv->get_region_name(fd);
- igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
-
igt_cgroup_dmem_get_capacity(cg_region, &capacity);
igt_require_f(capacity >= 4 * BO_SIZE,
"VRAM capacity (%"PRIu64" MiB) too small to test\n",
@@ -215,7 +211,6 @@ static void test_write_eviction(int fd, unsigned int flags, const struct igt_dme
igt_cgroup_dmem_set_max(cg, cg_region, IGT_CGROUP_DMEM_MAX);
drv->free_vram(ctx, n_bo, BO_SIZE);
drv->deinit(ctx);
- free(cg_region);
igt_cgroup_free(cg);
}
@@ -230,18 +225,14 @@ static int allocate_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, i
return err ?: n_bo;
}
-static void test_current(int fd, unsigned int flags, const struct igt_dmem_driver *drv)
+static void test_current(int fd, char *cg_region, unsigned int flags, const struct igt_dmem_driver *drv)
{
struct igt_cgroup *cg;
- char *cg_region;
void *ctx;
uint64_t current, capacity, cg_max;
int n_bo = 0, max_bo;
int err;
- cg_region = drv->get_region_name(fd);
- igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
-
igt_cgroup_dmem_get_capacity(cg_region, &capacity);
igt_require_f(capacity >= 4 * BO_SIZE,
"VRAM capacity (%"PRIu64" MiB) too small to test\n",
@@ -339,13 +330,12 @@ static void test_current(int fd, unsigned int flags, const struct igt_dmem_drive
current / SZ_1M, USAGE_SLACK / SZ_1M);
drv->deinit(ctx);
- free(cg_region);
igt_cgroup_free(cg);
}
static const struct {
const char *name;
- void (*test_fn)(int fd, unsigned int flags, const struct igt_dmem_driver *drv);
+ void (*test_fn)(int fd, char *cg_region, unsigned int flags, const struct igt_dmem_driver *drv);
unsigned int flags;
} subtests[] = {
{ "current", test_current, 0 },
@@ -376,20 +366,24 @@ int igt_main()
for (int d = 0; drivers[d].driver; d++) {
igt_subtest_group() {
int fd = -1;
+ char *cg_region;
igt_fixture() {
fd = drm_open_driver(drivers[d].driver_flag);
igt_require_f(fd >= 0,
"No %s device found, skipping\n",
drivers[d].driver->name);
+ cg_region = drivers[d].driver->get_region_name(fd);
+ igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
}
for (int i = 0; subtests[i].name; i++)
igt_subtest_f("%s-%s", drivers[d].driver->name, subtests[i].name)
- subtests[i].test_fn(fd, subtests[i].flags, drivers[d].driver);
+ subtests[i].test_fn(fd, cg_region, subtests[i].flags, drivers[d].driver);
igt_fixture() {
if (fd >= 0)
drm_close_driver(fd);
+ free(cg_region);
}
}
}
--
2.47.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
` (7 preceding siblings ...)
2026-05-12 21:51 ` [PATCH i-g-t 8/8] dmem: get region once per driver Thadeu Lima de Souza Cascardo
@ 2026-05-12 22:27 ` Thadeu Lima de Souza Cascardo
2026-05-13 8:06 ` Christian König
9 siblings, 0 replies; 16+ messages in thread
From: Thadeu Lima de Souza Cascardo @ 2026-05-12 22:27 UTC (permalink / raw)
To: igt-dev
Cc: dri-devel, amd-gfx, intel-xe, Christian Koenig, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin
On Tue, May 12, 2026 at 06:51:47PM -0300, Thadeu Lima de Souza Cascardo wrote:
> This work builds on top of Thomas Hellström's patches at [1].
>
> Besides the case of eviction when setting dmem.max, which still needs
> support from [2], there are other cases for testing dmem behavior and
It was pointed out that I missed the link here. And here it is.
[2] https://lore.kernel.org/dri-devel/20260512082406.44470-1-thomas.hellstrom@linux.intel.com/
> potential regressions. Thomas' patches lay over the groundwork for this,
> while this patchset addes one basic test of checking current usage and that
> drivers respect max setting when no eviction is taking place yet.
>
> This patchset also introduces a driver layer such that the same tests can
> work with different drivers. amdgpu support is here added too.
>
> [1] https://patchwork.freedesktop.org/series/163935/
>
> Thadeu Lima de Souza Cascardo (8):
> Introduce dmem driver and implement Xe support
> Adjust xe_cgroups test to use igt_dmem_driver
> Make xe_cgroup test a generic test
> amdgpu: add amdgpu_cgroup_region_name
> igt_dmem_driver: add amdgpu support
> dmem: add test for current/max
> dmem: only check for dmem availability once
> dmem: get region once per driver
>
> lib/amdgpu/amd_dmem.c | 94 ++++++++++
> lib/amdgpu/amd_memory.c | 25 +++
> lib/amdgpu/amd_memory.h | 2 +
> lib/igt_dmem_driver.h | 25 +++
> lib/meson.build | 2 +
> lib/xe/xe_dmem.c | 145 +++++++++++++++
> tests/drv_dmem_cgroups.c | 390 +++++++++++++++++++++++++++++++++++++++
> tests/intel/xe_cgroups.c | 296 -----------------------------
> tests/meson.build | 2 +-
> 9 files changed, 684 insertions(+), 297 deletions(-)
> create mode 100644 lib/amdgpu/amd_dmem.c
> create mode 100644 lib/igt_dmem_driver.h
> create mode 100644 lib/xe/xe_dmem.c
> create mode 100644 tests/drv_dmem_cgroups.c
> delete mode 100644 tests/intel/xe_cgroups.c
>
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
` (8 preceding siblings ...)
2026-05-12 22:27 ` [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
@ 2026-05-13 8:06 ` Christian König
2026-05-13 8:54 ` Thomas Hellström
9 siblings, 1 reply; 16+ messages in thread
From: Christian König @ 2026-05-13 8:06 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo, igt-dev
Cc: dri-devel, amd-gfx, intel-xe, maarten.lankhorst,
Thomas Hellström, Natalie Vock, kernel-dev, Tvrtko Ursulin,
Prosyak, Vitaly
On 5/12/26 23:51, Thadeu Lima de Souza Cascardo wrote:
> This work builds on top of Thomas Hellström's patches at [1].
>
> Besides the case of eviction when setting dmem.max, which still needs
> support from [2], there are other cases for testing dmem behavior and
> potential regressions. Thomas' patches lay over the groundwork for this,
> while this patchset addes one basic test of checking current usage and that
> drivers respect max setting when no eviction is taking place yet.
>
> This patchset also introduces a driver layer such that the same tests can
> work with different drivers. amdgpu support is here added too.
Of hand that looks really nice.
Please always keep Vitaly CCed for igt test patches which affect amdgpu as well.
Thanks,
Christian.
>
> [1] https://patchwork.freedesktop.org/series/163935/
>
> Thadeu Lima de Souza Cascardo (8):
> Introduce dmem driver and implement Xe support
> Adjust xe_cgroups test to use igt_dmem_driver
> Make xe_cgroup test a generic test
> amdgpu: add amdgpu_cgroup_region_name
> igt_dmem_driver: add amdgpu support
> dmem: add test for current/max
> dmem: only check for dmem availability once
> dmem: get region once per driver
>
> lib/amdgpu/amd_dmem.c | 94 ++++++++++
> lib/amdgpu/amd_memory.c | 25 +++
> lib/amdgpu/amd_memory.h | 2 +
> lib/igt_dmem_driver.h | 25 +++
> lib/meson.build | 2 +
> lib/xe/xe_dmem.c | 145 +++++++++++++++
> tests/drv_dmem_cgroups.c | 390 +++++++++++++++++++++++++++++++++++++++
> tests/intel/xe_cgroups.c | 296 -----------------------------
> tests/meson.build | 2 +-
> 9 files changed, 684 insertions(+), 297 deletions(-)
> create mode 100644 lib/amdgpu/amd_dmem.c
> create mode 100644 lib/igt_dmem_driver.h
> create mode 100644 lib/xe/xe_dmem.c
> create mode 100644 tests/drv_dmem_cgroups.c
> delete mode 100644 tests/intel/xe_cgroups.c
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test
2026-05-13 8:06 ` Christian König
@ 2026-05-13 8:54 ` Thomas Hellström
0 siblings, 0 replies; 16+ messages in thread
From: Thomas Hellström @ 2026-05-13 8:54 UTC (permalink / raw)
To: Christian König, Thadeu Lima de Souza Cascardo, igt-dev
Cc: dri-devel, amd-gfx, intel-xe, maarten.lankhorst, Natalie Vock,
kernel-dev, Tvrtko Ursulin, Prosyak, Vitaly
On Wed, 2026-05-13 at 10:06 +0200, Christian König wrote:
> On 5/12/26 23:51, Thadeu Lima de Souza Cascardo wrote:
> > This work builds on top of Thomas Hellström's patches at [1].
> >
> > Besides the case of eviction when setting dmem.max, which still
> > needs
> > support from [2], there are other cases for testing dmem behavior
> > and
> > potential regressions. Thomas' patches lay over the groundwork for
> > this,
> > while this patchset addes one basic test of checking current usage
> > and that
> > drivers respect max setting when no eviction is taking place yet.
> >
> > This patchset also introduces a driver layer such that the same
> > tests can
> > work with different drivers. amdgpu support is here added too.
>
> Of hand that looks really nice.
>
> Please always keep Vitaly CCed for igt test patches which affect
> amdgpu as well.
>
> Thanks,
> Christian.
Agree this looks nice.
For the xe changes (once [1] gets merged)
Acked-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Thanks,
Thomas
>
> >
> > [1] https://patchwork.freedesktop.org/series/163935/
> >
> > Thadeu Lima de Souza Cascardo (8):
> > Introduce dmem driver and implement Xe support
> > Adjust xe_cgroups test to use igt_dmem_driver
> > Make xe_cgroup test a generic test
> > amdgpu: add amdgpu_cgroup_region_name
> > igt_dmem_driver: add amdgpu support
> > dmem: add test for current/max
> > dmem: only check for dmem availability once
> > dmem: get region once per driver
> >
> > lib/amdgpu/amd_dmem.c | 94 ++++++++++
> > lib/amdgpu/amd_memory.c | 25 +++
> > lib/amdgpu/amd_memory.h | 2 +
> > lib/igt_dmem_driver.h | 25 +++
> > lib/meson.build | 2 +
> > lib/xe/xe_dmem.c | 145 +++++++++++++++
> > tests/drv_dmem_cgroups.c | 390
> > +++++++++++++++++++++++++++++++++++++++
> > tests/intel/xe_cgroups.c | 296 -----------------------------
> > tests/meson.build | 2 +-
> > 9 files changed, 684 insertions(+), 297 deletions(-)
> > create mode 100644 lib/amdgpu/amd_dmem.c
> > create mode 100644 lib/igt_dmem_driver.h
> > create mode 100644 lib/xe/xe_dmem.c
> > create mode 100644 tests/drv_dmem_cgroups.c
> > delete mode 100644 tests/intel/xe_cgroups.c
> >
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH i-g-t 2/8] Adjust xe_cgroups test to use igt_dmem_driver
2026-05-12 21:51 ` [PATCH i-g-t 2/8] Adjust xe_cgroups test to use igt_dmem_driver Thadeu Lima de Souza Cascardo
@ 2026-05-13 15:18 ` Kamil Konieczny
0 siblings, 0 replies; 16+ messages in thread
From: Kamil Konieczny @ 2026-05-13 15:18 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: igt-dev, dri-devel, amd-gfx, intel-xe, Christian Koenig,
maarten.lankhorst, Thomas Hellström, Natalie Vock,
kernel-dev, Tvrtko Ursulin
Hi Thadeu,
On 2026-05-12 at 18:51:49 -0300, Thadeu Lima de Souza Cascardo wrote:
> Using the driver should not have any functional changes.
>
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
> ---
> tests/intel/xe_cgroups.c | 69 ++++++++--------------------------------
> 1 file changed, 14 insertions(+), 55 deletions(-)
Instead of a change and in next patch a file rename,
could you squash the two into one? Xe test is not merged yet.
Regards,
Kamil
>
> diff --git a/tests/intel/xe_cgroups.c b/tests/intel/xe_cgroups.c
> index 08cf8e3bdc5b..9ff8d46570ab 100644
> --- a/tests/intel/xe_cgroups.c
> +++ b/tests/intel/xe_cgroups.c
> @@ -25,6 +25,7 @@
> #include "igt.h"
> #include "igt_aux.h"
> #include "igt_cgroup.h"
> +#include "igt_dmem_driver.h"
> #include "xe_drm.h"
> #include "xe/xe_ioctl.h"
> #include "xe/xe_query.h"
> @@ -110,27 +111,14 @@ static uint64_t wait_for_usage_drop(struct igt_cgroup *cg, const char *region,
> return current;
> }
>
> -static int fill_vram(int fd, uint32_t vm, uint64_t vram_region,
> - uint32_t *handles, int max_bo)
> +static int fill_vram(struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
> {
> - uint32_t handle;
> - uint64_t addr = BIND_BASE;
> int n_bo, err = 0;
>
> for (n_bo = 0; n_bo < max_bo; n_bo++) {
> - err = __xe_bo_create(fd, 0, BO_SIZE, vram_region,
> - DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING,
> - NULL, &handle);
> + err = drv->allocate_vram(ctx, n_bo, BO_SIZE);
> if (err)
> break;
> -
> - handles[n_bo] = handle;
> -
> - err = __xe_vm_bind_lr_sync(fd, vm, handle, 0, addr, BO_SIZE, 0);
> - if (err)
> - break;
> -
> - addr += BO_SIZE;
> }
>
> igt_assert_f(err == -ENOMEM || err == -ENOSPC,
> @@ -140,47 +128,20 @@ static int fill_vram(int fd, uint32_t vm, uint64_t vram_region,
> return n_bo;
> }
>
> -static void unfill_vram(int fd, uint32_t vm, uint32_t *handles, int n_bo)
> -{
> - uint64_t addr = BIND_BASE;
> - int i;
> -
> - for (i = 0; i < n_bo; i++) {
> - if (handles[i]) {
> - xe_vm_unbind_lr_sync(fd, vm, 0, addr, BO_SIZE);
> - gem_close(fd, handles[i]);
> - }
> - addr += BO_SIZE;
> - }
> - free(handles);
> -}
> -
> -static void test_write_eviction(int fd, unsigned int flags)
> +static void test_write_eviction(int fd, unsigned int flags, struct igt_dmem_driver *drv)
> {
> + void *ctx;
> struct igt_cgroup *cg;
> char *cg_region;
> - uint32_t vm;
> - uint64_t vram_region = 0;
> - uint64_t region;
> - uint32_t *handles = NULL;
> int n_bo = 0, max_bo;
> uint64_t current, capacity, cg_max, limit, after;
> - int set_err;
> + int set_err, err;
>
> /* Check dmem cgroup controller is available before doing anything else */
> igt_require_f(igt_cgroup_dmem_available(),
> "dmem cgroup controller not available (no cgroup v2 or no registered regions)\n");
>
> - /* Find first VRAM region */
> - xe_for_each_mem_region(fd, all_memory_regions(fd), region) {
> - if (xe_region_class(fd, region) == DRM_XE_MEM_REGION_CLASS_VRAM) {
> - vram_region = region;
> - break;
> - }
> - }
> - igt_require_f(vram_region, "No VRAM region found on this device\n");
> -
> - cg_region = xe_cgroup_region_name(fd, vram_region);
> + cg_region = drv->get_region_name(fd);
> igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
>
> igt_cgroup_dmem_get_capacity(cg_region, &capacity);
> @@ -204,13 +165,12 @@ static void test_write_eviction(int fd, unsigned int flags)
> igt_cgroup_move_current(cg);
> igt_cgroup_dmem_set_max(cg, cg_region, cg_max);
>
> - vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
> -
> max_bo = (cg_max / BO_SIZE) + 8; /* headroom for overcommit */
> - handles = calloc(max_bo, sizeof(*handles));
> - igt_assert(handles);
>
> - n_bo = fill_vram(fd, vm, vram_region, handles, max_bo);
> + err = drv->init(&ctx, fd, max_bo);
> + igt_assert_f(!err, "Failed to initialize driver");
> +
> + n_bo = fill_vram(drv, ctx, fd, max_bo);
>
> igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
> igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
> @@ -261,9 +221,8 @@ static void test_write_eviction(int fd, unsigned int flags)
>
> /* Cleanup */
> igt_cgroup_dmem_set_max(cg, cg_region, IGT_CGROUP_DMEM_MAX);
> - unfill_vram(fd, vm, handles, n_bo);
> - handles = NULL;
> - xe_vm_destroy(fd, vm);
> + drv->free_vram(ctx, n_bo, BO_SIZE);
> + drv->deinit(ctx);
> free(cg_region);
> igt_cgroup_free(cg);
> }
> @@ -288,7 +247,7 @@ int igt_main()
>
> for (int i = 0; subtests[i].name; i++)
> igt_subtest(subtests[i].name)
> - test_write_eviction(fd, subtests[i].flags);
> + test_write_eviction(fd, subtests[i].flags, &xe_dmem_driver);
>
> igt_fixture() {
> drm_close_driver(fd);
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH i-g-t 3/8] Make xe_cgroup test a generic test
2026-05-12 21:51 ` [PATCH i-g-t 3/8] Make xe_cgroup test a generic test Thadeu Lima de Souza Cascardo
@ 2026-05-13 15:21 ` Kamil Konieczny
0 siblings, 0 replies; 16+ messages in thread
From: Kamil Konieczny @ 2026-05-13 15:21 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: igt-dev, dri-devel, amd-gfx, intel-xe, Christian Koenig,
maarten.lankhorst, Thomas Hellström, Natalie Vock,
kernel-dev, Tvrtko Ursulin, Janusz Krzysztofik
Hi Thadeu,
On 2026-05-12 at 18:51:50 -0300, Thadeu Lima de Souza Cascardo wrote:
> It should not be driver specific anymore. Make it run for multiple drivers,
> though there is still only Xe now.
>
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
> ---
> .../xe_cgroups.c => drv_dmem_cgroups.c} | 61 +++++++++++--------
Can we start with a more generic name? imho core_cgroups.c
looks better, so it will be tests/core_cgroups.c
+cc Janusz
Cc: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
> tests/meson.build | 2 +-
> 2 files changed, 38 insertions(+), 25 deletions(-)
> rename tests/{intel/xe_cgroups.c => drv_dmem_cgroups.c} (83%)
>
> diff --git a/tests/intel/xe_cgroups.c b/tests/drv_dmem_cgroups.c
> similarity index 83%
> rename from tests/intel/xe_cgroups.c
> rename to tests/drv_dmem_cgroups.c
> index 9ff8d46570ab..6f4f779f3c2c 100644
> --- a/tests/intel/xe_cgroups.c
> +++ b/tests/drv_dmem_cgroups.c
> @@ -4,13 +4,12 @@
> */
>
> /**
> - * TEST: xe_cgroups
> - * DESCRIPTION: Tests exercising the dmem cgroup controller on xe devices.
> + * TEST: drv_dmem_cgroups
> + * DESCRIPTION: Tests exercising the dmem cgroup controller on devices.
> * Category: Core
> * Mega feature: General Core features
> * Sub-category: cgroup
> * FUNCTIONALITY: cgroup dmem controller
> - * SUBSETS: xe
> */
>
> #include <errno.h>
> @@ -26,9 +25,6 @@
> #include "igt_aux.h"
> #include "igt_cgroup.h"
> #include "igt_dmem_driver.h"
> -#include "xe_drm.h"
> -#include "xe/xe_ioctl.h"
> -#include "xe/xe_query.h"
>
> #define BO_SIZE SZ_128M
> #define MAX_LIMIT ((uint64_t)4 * SZ_1G)
> @@ -45,13 +41,12 @@
> * DESCRIPTION:
> * Create a dmem cgroup, move the current process into it and set the max
> * device memory limit for the first VRAM region to 4 GiB. Then fill VRAM
> - * by creating BOs with %DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING (so that the
> - * physical allocation is deferred until VM_BIND) and binding them into an
> - * LR VM until the cgroup limit is hit. Verify that the reported cgroup
> - * current usage is within the expected range when the error occurs.
> + * by creating BOs.
> + * Verify that the reported cgroup current usage is within the expected
> + * range when the error occurs.
> * Finally lower the max limit in 256 MiB steps and verify that the cgroup
> * usage follows.
> - * REQUIREMENTS: must run as root; xe device with at least one VRAM region
> + * REQUIREMENTS: must run as root; device with at least one VRAM region
> */
>
> /**
> @@ -61,7 +56,7 @@
> * igt_fork_signal_helper() to verify that the dmem.max write path handles
> * signal interruption correctly. A signal handler counts received signals
> * and the count is reported as debug output at the end of the test.
> - * REQUIREMENTS: must run as root; xe device with at least one VRAM region
> + * REQUIREMENTS: must run as root; device with at least one VRAM region
Almost all igt tests require a root, do we need this comment here?
Regards,
Kamil
> */
>
> static atomic_int signal_count;
> @@ -111,7 +106,7 @@ static uint64_t wait_for_usage_drop(struct igt_cgroup *cg, const char *region,
> return current;
> }
>
> -static int fill_vram(struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
> +static int fill_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
> {
> int n_bo, err = 0;
>
> @@ -128,7 +123,7 @@ static int fill_vram(struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo)
> return n_bo;
> }
>
> -static void test_write_eviction(int fd, unsigned int flags, struct igt_dmem_driver *drv)
> +static void test_write_eviction(int fd, unsigned int flags, const struct igt_dmem_driver *drv)
> {
> void *ctx;
> struct igt_cgroup *cg;
> @@ -161,7 +156,7 @@ static void test_write_eviction(int fd, unsigned int flags, struct igt_dmem_driv
> install_sigcont_counter();
>
> /* Create cgroup and move into it */
> - cg = igt_cgroup_new("xe_cgroups_test");
> + cg = igt_cgroup_new("igt_cgroups_test");
> igt_cgroup_move_current(cg);
> igt_cgroup_dmem_set_max(cg, cg_region, cg_max);
>
> @@ -236,20 +231,38 @@ static const struct {
> { }
> };
>
> +static const struct {
> + int driver_flag;
> + const struct igt_dmem_driver *driver;
> +} drivers[] = {
> + { DRIVER_XE, &xe_dmem_driver },
> + { },
> +};
> +
> int igt_main()
> {
> - int fd = -1;
> -
> igt_fixture() {
> - fd = drm_open_driver(DRIVER_XE);
> igt_require_f(getuid() == 0, "Test requires root\n");
> }
>
> - for (int i = 0; subtests[i].name; i++)
> - igt_subtest(subtests[i].name)
> - test_write_eviction(fd, subtests[i].flags, &xe_dmem_driver);
> -
> - igt_fixture() {
> - drm_close_driver(fd);
> + for (int d = 0; drivers[d].driver; d++) {
> + igt_subtest_group() {
> + int fd = -1;
> + igt_fixture() {
> + fd = drm_open_driver(drivers[d].driver_flag);
> + igt_require_f(fd >= 0,
> + "No %s device found, skipping\n",
> + drivers[d].driver->name);
> + }
> +
> + for (int i = 0; subtests[i].name; i++)
> + igt_subtest_f("%s-%s", drivers[d].driver->name, subtests[i].name)
> + test_write_eviction(fd, subtests[i].flags, drivers[d].driver);
> +
> + igt_fixture() {
> + if (fd >= 0)
> + drm_close_driver(fd);
> + }
> + }
> }
> }
> diff --git a/tests/meson.build b/tests/meson.build
> index b4463a722361..deb049875b46 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -17,6 +17,7 @@ test_progs = [
> 'drm_mm',
> 'drm_read',
> 'drm_virtgpu',
> + 'drv_dmem_cgroups',
> 'fbdev',
> 'kms_3d',
> 'kms_addfb_basic',
> @@ -292,7 +293,6 @@ intel_xe_progs = [
> 'xe_dma_buf_sync',
> 'xe_drm_fdinfo',
> 'xe_eu_stall',
> - 'xe_cgroups',
> 'xe_evict',
> 'xe_evict_ccs',
> 'xe_exec_atomic',
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH i-g-t 5/8] igt_dmem_driver: add amdgpu support
2026-05-12 21:51 ` [PATCH i-g-t 5/8] igt_dmem_driver: add amdgpu support Thadeu Lima de Souza Cascardo
@ 2026-05-13 15:26 ` Kamil Konieczny
0 siblings, 0 replies; 16+ messages in thread
From: Kamil Konieczny @ 2026-05-13 15:26 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: igt-dev, dri-devel, amd-gfx, intel-xe, Christian Koenig,
maarten.lankhorst, Thomas Hellström, Natalie Vock,
kernel-dev, Tvrtko Ursulin, Vitaly Prosyak
Hi Thadeu,
On 2026-05-12 at 18:51:52 -0300, Thadeu Lima de Souza Cascardo wrote:
> Allocate a BO from VRAM domain. That will try to place BOs on VRAM, but may
> fallback to GTT. That can still be tracked with dmem.current.
>
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
> ---
> lib/amdgpu/amd_dmem.c | 94 ++++++++++++++++++++++++++++++++++++++++
Why amd_dmem.c? Why this all cannot reside in core_cgroups.c?
+cc Vitaly
Cc: Vitaly Prosyak <vitaly.prosyak@amd.com>
> lib/igt_dmem_driver.h | 1 +
> lib/meson.build | 1 +
> tests/drv_dmem_cgroups.c | 6 ++-
> 4 files changed, 100 insertions(+), 2 deletions(-)
> create mode 100644 lib/amdgpu/amd_dmem.c
>
> diff --git a/lib/amdgpu/amd_dmem.c b/lib/amdgpu/amd_dmem.c
> new file mode 100644
> index 000000000000..1c0825af43b6
> --- /dev/null
> +++ b/lib/amdgpu/amd_dmem.c
> @@ -0,0 +1,94 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright 2026 Valve Corporation
> + * Authors:
> + * Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
> + */
> +
> +#include "igt_dmem_driver.h"
> +
> +#include <errno.h>
Please make system includes first, then follow with igt ones, so:
#include <errno.h>
#include "igt.h"
#include "igt_cgroup.h"
#include "igt_dmem_driver.h"
#include "lib/amdgpu/amd_memory.h"
Regards,
Kamil
> +
> +#include "igt.h"
> +#include "igt_cgroup.h"
> +#include "lib/amdgpu/amd_memory.h"
> +
> +struct amdgpu_dmem_ctx {
> + int fd;
> + amdgpu_device_handle device;
> + amdgpu_bo_handle *handles;
> +};
> +
> +static int amdgpu_dmem_init(void **ctx, int fd, int max_bo)
> +{
> + struct amdgpu_dmem_ctx *actx;
> + uint32_t major, minor;
> + int err = -ENOMEM;
> +
> + actx = malloc(sizeof(*actx));
> + if (!actx)
> + return -ENOMEM;
> +
> + actx->handles = calloc(max_bo, sizeof(actx->handles[0]));
> + if (!actx->handles)
> + goto out;
> +
> + err = amdgpu_device_initialize(fd, &major, &minor, &actx->device);
> + if (err)
> + goto out;
> +
> + *ctx = actx;
> +
> + return 0;
> +
> +out:
> + if (actx->handles)
> + free(actx->handles);
> + free(actx);
> +
> + return err;
> +}
> +
> +static void amdgpu_dmem_deinit(void *ctx)
> +{
> + struct amdgpu_dmem_ctx *actx = ctx;
> +
> + amdgpu_device_deinitialize(actx->device);
> + free(actx->handles);
> + free(actx);
> +}
> +
> +static int amdgpu_dmem_allocate_vram(void *ctx, int n_bo, size_t len)
> +{
> + struct amdgpu_dmem_ctx *actx = ctx;
> + amdgpu_bo_handle handle;
> + int err;
> +
> + err = amdgpu_bo_alloc_wrap(actx->device, len, 4096,
> + AMDGPU_GEM_DOMAIN_VRAM, 0, &handle);
> + if (err)
> + return err;
> +
> + actx->handles[n_bo] = handle;
> +
> + return 0;
> +}
> +
> +static void amdgpu_dmem_free_vram(void *ctx, int n_bo, size_t len)
> +{
> + struct amdgpu_dmem_ctx *actx = ctx;
> + int i;
> + for (i = 0; i < n_bo; i++) {
> + if (actx->handles[i])
> + amdgpu_bo_free(actx->handles[i]);
> + }
> +}
> +
> +const struct igt_dmem_driver amdgpu_dmem_driver = {
> + .name = "amdgpu",
> + .get_region_name = amdgpu_cgroup_region_name,
> + .init = amdgpu_dmem_init,
> + .deinit = amdgpu_dmem_deinit,
> + .allocate_vram = amdgpu_dmem_allocate_vram,
> + .free_vram = amdgpu_dmem_free_vram,
> +};
> diff --git a/lib/igt_dmem_driver.h b/lib/igt_dmem_driver.h
> index 869356fbf2c2..d43e5140d4f6 100644
> --- a/lib/igt_dmem_driver.h
> +++ b/lib/igt_dmem_driver.h
> @@ -20,5 +20,6 @@ struct igt_dmem_driver {
> };
>
> extern const struct igt_dmem_driver xe_dmem_driver;
> +extern const struct igt_dmem_driver amdgpu_dmem_driver;
>
> #endif
> diff --git a/lib/meson.build b/lib/meson.build
> index 269f3b9f0af8..dd02d087875b 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -188,6 +188,7 @@ if libdrm_amdgpu.found()
> 'amdgpu/amd_mmd_shared.c',
> 'amdgpu/amd_jpeg_shared.c',
> 'amdgpu/amd_utils.c',
> + 'amdgpu/amd_dmem.c',
> 'amdgpu/amd_vcn_shared.c'
> ]
> if libdrm_amdgpu.version().version_compare('> 2.4.99')
> diff --git a/tests/drv_dmem_cgroups.c b/tests/drv_dmem_cgroups.c
> index 6f4f779f3c2c..0e26b7e2bb9a 100644
> --- a/tests/drv_dmem_cgroups.c
> +++ b/tests/drv_dmem_cgroups.c
> @@ -116,8 +116,9 @@ static int fill_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, int m
> break;
> }
>
> - igt_assert_f(err == -ENOMEM || err == -ENOSPC,
> - "Expected -ENOMEM or -ENOSPC, got %d (%s)\n",
> + /* amdgpu will fallback to GTT if it cannot allocate on VRAM */
> + igt_assert_f(err == -ENOMEM || err == -ENOSPC || err == 0,
> + "Expected -ENOMEM,-ENOSPC or success, got %d (%s)\n",
> err, strerror(-err));
>
> return n_bo;
> @@ -236,6 +237,7 @@ static const struct {
> const struct igt_dmem_driver *driver;
> } drivers[] = {
> { DRIVER_XE, &xe_dmem_driver },
> + { DRIVER_AMDGPU, &amdgpu_dmem_driver },
> { },
> };
>
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH i-g-t 6/8] dmem: add test for current/max
2026-05-12 21:51 ` [PATCH i-g-t 6/8] dmem: add test for current/max Thadeu Lima de Souza Cascardo
@ 2026-05-13 15:31 ` Kamil Konieczny
0 siblings, 0 replies; 16+ messages in thread
From: Kamil Konieczny @ 2026-05-13 15:31 UTC (permalink / raw)
To: Thadeu Lima de Souza Cascardo
Cc: igt-dev, dri-devel, amd-gfx, intel-xe, Christian Koenig,
maarten.lankhorst, Thomas Hellström, Natalie Vock,
kernel-dev, Tvrtko Ursulin
Hi Thadeu,
On 2026-05-12 at 18:51:53 -0300, Thadeu Lima de Souza Cascardo wrote:
> Add a test that checks for current usage after VRAM allocation and release.
> Set max to different values and track that current usage is not above max,
> given some slack.
>
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
> ---
> tests/drv_dmem_cgroups.c | 136 ++++++++++++++++++++++++++++++++++++++-
When you make a change in test only, add a prefix tests/a_test_name_here:
so in subject there will be:
[PATCH i-g-t 6/8] tests/drv_dmem_cgroups: add test for current/max
Btw I see below only 'current' subtest, where is 'max'?
> 1 file changed, 133 insertions(+), 3 deletions(-)
>
> diff --git a/tests/drv_dmem_cgroups.c b/tests/drv_dmem_cgroups.c
> index 0e26b7e2bb9a..43331117854c 100644
> --- a/tests/drv_dmem_cgroups.c
> +++ b/tests/drv_dmem_cgroups.c
> @@ -223,12 +223,142 @@ static void test_write_eviction(int fd, unsigned int flags, const struct igt_dme
> igt_cgroup_free(cg);
> }
>
> +static int allocate_vram(const struct igt_dmem_driver *drv, void *ctx, int fd, int max_bo, size_t len)
> +{
> + int n_bo, err = 0;
> + for (n_bo = 0; n_bo < max_bo; n_bo++) {
> + err = drv->allocate_vram(ctx, n_bo, len);
> + if (err)
> + break;
> + }
> + return err ?: n_bo;
> +}
> +
> +static void test_current(int fd, unsigned int flags, const struct igt_dmem_driver *drv)
> +{
> + struct igt_cgroup *cg;
> + char *cg_region;
> + void *ctx;
> + uint64_t current, capacity, cg_max;
> + int n_bo = 0, max_bo;
> + int err;
> +
> + cg_region = drv->get_region_name(fd);
> + igt_require_f(cg_region, "Region not tracked by dmem cgroup controller\n");
> +
> + /* Check dmem cgroup controller is available before doing anything else */
> + igt_require_f(igt_cgroup_dmem_available(),
> + "dmem cgroup controller not available (no cgroup v2 or no registered regions)\n");
> +
> + igt_cgroup_dmem_get_capacity(cg_region, &capacity);
> + igt_require_f(capacity >= 4 * BO_SIZE,
> + "VRAM capacity (%"PRIu64" MiB) too small to test\n",
> + capacity / SZ_1M);
> +
> + /*
> + * Use up to 4 GiB, or the full capacity if the device has less.
> + * Leave one BO_SIZE worth of headroom so the device isn't completely
> + * exhausted before the cgroup limit is hit.
> + */
> + cg_max = min(MAX_LIMIT, capacity - BO_SIZE);
> + cg_max = ALIGN_DOWN(cg_max, EVICT_STEP);
> +
> + if (flags & TEST_INTERRUPTIBLE)
> + install_sigcont_counter();
> +
> + /* Create cgroup and move into it */
> + cg = igt_cgroup_new("igt_cgroups_test");
> + igt_cgroup_move_current(cg);
> +
> + max_bo = cg_max / BO_SIZE;
> +
> + err = drv->init(&ctx, fd, max_bo);
> + igt_assert_f(!err, "Failed to initialize driver");
> +
> + n_bo = allocate_vram(drv, ctx, fd, max_bo, BO_SIZE);
> + igt_assert_f(n_bo > 0, "failed to allocate VRAM\n");
> +
> + igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
> + igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
> + "max = %"PRIu64" MiB\n",
> + current / SZ_1M, cg_max / SZ_1M);
> + igt_assert_f(current < cg_max + USAGE_SLACK && current > cg_max - USAGE_SLACK,
> + "current usage (%"PRIu64" MiB) is not within margin of allocation (%"PRIu64" MiB)\n",
> + current / SZ_1M, cg_max / SZ_1M);
> +
> + drv->free_vram(ctx, n_bo, BO_SIZE);
> + sleep(1);
> +
> + igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
> + igt_debug("After free: cgroup current = %"PRIu64" MiB, "
> + "max = %"PRIu64" MiB\n",
> + current / SZ_1M, cg_max / SZ_1M);
> + igt_assert_f(current < USAGE_SLACK,
> + "current usage (%"PRIu64" MiB) is not within margin (%d MiB)\n",
> + current / SZ_1M, USAGE_SLACK / SZ_1M);
> +
> + igt_cgroup_dmem_set_max(cg, cg_region, 2 * BO_SIZE);
> +
> + n_bo = allocate_vram(drv, ctx, fd, max_bo, BO_SIZE);
> + igt_assert_f(n_bo > 0, "failed to allocate VRAM\n");
> +
> + igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
> + igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
> + "max = %"PRIu64" MiB\n",
> + current / SZ_1M, cg_max / SZ_1M);
> + igt_assert_f(current < 2 * BO_SIZE + USAGE_SLACK && current > 2 * BO_SIZE - USAGE_SLACK,
> + "current usage (%"PRIu64" MiB) is not within margin of allocation (%"PRIu64" MiB)\n",
> + current / SZ_1M, cg_max / SZ_1M);
> +
> + drv->free_vram(ctx, n_bo, BO_SIZE);
> + sleep(1);
> +
> + igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
> + igt_debug("After free: cgroup current = %"PRIu64" MiB, "
> + "max = %"PRIu64" MiB\n",
> + current / SZ_1M, cg_max / SZ_1M);
> + igt_assert_f(current < USAGE_SLACK,
> + "current usage (%"PRIu64" MiB) is not within margin (%d MiB)\n",
> + current / SZ_1M, USAGE_SLACK / SZ_1M);
> +
> + igt_cgroup_dmem_set_max(cg, cg_region, 0);
> +
> + n_bo = allocate_vram(drv, ctx, fd, max_bo, BO_SIZE);
> + igt_assert_f(n_bo != -ENOMEM, "VRAM allocation succeeded despite max set to 0\n");
> +
> + igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
> + igt_debug("After fill: cgroup current = %"PRIu64" MiB, "
> + "max = %"PRIu64" MiB\n",
> + current / SZ_1M, cg_max / SZ_1M);
> + igt_assert_f(current < USAGE_SLACK,
> + "current usage (%"PRIu64" MiB) is not within margin\n",
> + current / SZ_1M);
> +
> + if (n_bo > 0)
> + drv->free_vram(ctx, n_bo, BO_SIZE);
> + sleep(1);
> +
> + igt_cgroup_dmem_get_current(cg, cg_region, ¤t);
> + igt_debug("After free: cgroup current = %"PRIu64" MiB, "
> + "max = %"PRIu64" MiB\n",
> + current / SZ_1M, cg_max / SZ_1M);
> + igt_assert_f(current < USAGE_SLACK,
> + "current usage (%"PRIu64" MiB) is not within margin (%d MiB)\n",
> + current / SZ_1M, USAGE_SLACK / SZ_1M);
> +
> + drv->deinit(ctx);
> + free(cg_region);
> + igt_cgroup_free(cg);
> +}
> +
> static const struct {
> const char *name;
> + void (*test_fn)(int fd, unsigned int flags, const struct igt_dmem_driver *drv);
> unsigned int flags;
> } subtests[] = {
> - { "write_eviction", 0 },
> - { "write_eviction_interruptible", TEST_INTERRUPTIBLE },
> + { "current", test_current, 0 },
For each new subetest add a corresponding SUBTEST: comment section.
Regards,
Kamil
> + { "write_eviction", test_write_eviction, 0 },
> + { "write_eviction_interruptible", test_write_eviction, TEST_INTERRUPTIBLE },
> { }
> };
>
> @@ -259,7 +389,7 @@ int igt_main()
>
> for (int i = 0; subtests[i].name; i++)
> igt_subtest_f("%s-%s", drivers[d].driver->name, subtests[i].name)
> - test_write_eviction(fd, subtests[i].flags, drivers[d].driver);
> + subtests[i].test_fn(fd, subtests[i].flags, drivers[d].driver);
>
> igt_fixture() {
> if (fd >= 0)
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-05-13 15:31 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-12 21:51 [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 1/8] Introduce dmem driver and implement Xe support Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 2/8] Adjust xe_cgroups test to use igt_dmem_driver Thadeu Lima de Souza Cascardo
2026-05-13 15:18 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 3/8] Make xe_cgroup test a generic test Thadeu Lima de Souza Cascardo
2026-05-13 15:21 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 4/8] amdgpu: add amdgpu_cgroup_region_name Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 5/8] igt_dmem_driver: add amdgpu support Thadeu Lima de Souza Cascardo
2026-05-13 15:26 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 6/8] dmem: add test for current/max Thadeu Lima de Souza Cascardo
2026-05-13 15:31 ` Kamil Konieczny
2026-05-12 21:51 ` [PATCH i-g-t 7/8] dmem: only check for dmem availability once Thadeu Lima de Souza Cascardo
2026-05-12 21:51 ` [PATCH i-g-t 8/8] dmem: get region once per driver Thadeu Lima de Souza Cascardo
2026-05-12 22:27 ` [PATCH i-g-t 0/8] dmem: add amdgpu support and one more test Thadeu Lima de Souza Cascardo
2026-05-13 8:06 ` Christian König
2026-05-13 8:54 ` Thomas Hellström
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox