Hi Thadeu,
On 2026-09-03 at 19:00:26 -0300, Thadeu Lima de Souza Cascardo wrote:
> 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 was based on the original operations from
> xe_cgroups.c written by Thomas Hellström. However, instead of doing a
> deferred backing, followed by a bind, it does a simple non-deferred GEM
> object creation on the VRAM region.
>
> Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]>
> ---
> lib/igt_dmem_driver.h | 34 ++++++++++++++++++
> lib/meson.build | 1 +
> lib/xe/xe_dmem.c | 97
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 132 insertions(+)
>
> diff --git a/lib/igt_dmem_driver.h b/lib/igt_dmem_driver.h
> new file mode 100644
> index 000000000000..e6998387eff9
> --- /dev/null
> +++ b/lib/igt_dmem_driver.h
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright 2026 Valve Corporation
> + * Authors:
> + * Thadeu Lima de Souza Cascardo <[email protected]>
> + */
> +
> +#ifndef __IGT_DMEM_DRIVER_H__
> +#define __IGT_DMEM_DRIVER_H__
> +
> +#include <stdlib.h>
Please drop this include from header, and if needed move to .c lib.
Regards,
Kamil
> +
> +/**
> + * struct igt_dmem_driver - vendor driver to allocate and free device memory
> + *
> + */
> +struct igt_dmem_driver {
> + /** @name: Driver name */
> + const char *name;
> + /** @init: Initialize an opaque context given a DRM device fd */
> + int (*init)(void **ctx, int fd);
> + /** @deinit: Release resources associated with context */
> + void (*deinit)(void *ctx);
> + /** @get_region_name: Return expected region name at dmem cgroup files
> */
> + char * (*get_region_name)(void *ctx);
> + /** @allocate_vram: Allocate @len sized vram and return an opaque
> @handle */
> + int (*allocate_vram)(void *ctx, size_t len, void **handle);
> + /** @free_vram: Free vram associated with @handle */
> + void (*free_vram)(void *ctx, void *handle);
> +};
> +
> +extern const struct igt_dmem_driver xe_dmem_driver;
> +
> +#endif
> diff --git a/lib/meson.build b/lib/meson.build
> index b7e1be61d844..022408ce6864 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -130,6 +130,7 @@ lib_sources = [
> 'igt_dsc.c',
> 'igt_hook.c',
> 'xe/xe_device.c',
> + 'xe/xe_dmem.c',
> 'xe/xe_ggtt.c',
> 'xe/xe_gt.c',
> 'xe/xe_ioctl.c',
> diff --git a/lib/xe/xe_dmem.c b/lib/xe/xe_dmem.c
> new file mode 100644
> index 000000000000..628c905997d4
> --- /dev/null
> +++ b/lib/xe/xe_dmem.c
> @@ -0,0 +1,97 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright 2026 Valve Corporation
> + * Authors:
> + * Thadeu Lima de Souza Cascardo <[email protected]>
> + */
> +
> +#include <errno.h>
> +
> +#include "igt.h"
> +#include "igt_cgroup.h"
> +#include "igt_dmem_driver.h"
> +#include "xe_drm.h"
> +#include "xe/xe_ioctl.h"
> +#include "xe/xe_query.h"
> +
> +struct xe_dmem_ctx {
> + int fd;
> + uint64_t vram_region;
> +};
> +
> +static int xe_dmem_init(void **ctx, int fd)
> +{
> + struct xe_dmem_ctx *xe_ctx;
> + uint64_t region;
> +
> + xe_ctx = malloc(sizeof(*xe_ctx));
> + if (!xe_ctx)
> + return -ENOMEM;
> +
> + 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->fd = fd;
> +
> + *ctx = xe_ctx;
> +
> + return 0;
> +
> +out:
> + free(xe_ctx);
> +
> + return -ENOMEM;
> +}
> +
> +static void xe_dmem_deinit(void *ctx)
> +{
> + struct xe_dmem_ctx *xe_ctx = ctx;
> +
> + free(xe_ctx);
> +}
> +
> +static char * xe_dmem_get_region_name(void *ctx)
> +{
> + struct xe_dmem_ctx *xe_ctx = ctx;
> +
> + return xe_cgroup_region_name(xe_ctx->fd, xe_ctx->vram_region);
> +}
> +
> +static int xe_dmem_allocate_vram(void *ctx, size_t len, void **ret_handle)
> +{
> + 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, 0,
> + NULL, &handle);
> + if (err)
> + return err;
> +
> + *ret_handle = (void *)(uintptr_t) handle;
> + return 0;
> +}
> +
> +static void xe_dmem_free_vram(void *ctx, void *handle)
> +{
> + struct xe_dmem_ctx *xe_ctx = ctx;
> +
> + gem_close(xe_ctx->fd, (uint32_t)(uintptr_t) handle);
> +}
> +
> +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
>