From: Matthew Brost <matthew.brost@intel.com>
To: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Cc: intel-xe@lists.freedesktop.org,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Subject: Re: [PATCH v5 20/23] drm/xe: Reset VMA attributes to default in SVM garbage collector
Date: Thu, 24 Jul 2025 14:50:47 -0700 [thread overview]
Message-ID: <aIKqt67Ob0sYuDIO@lstrano-desk.jf.intel.com> (raw)
In-Reply-To: <20250722133526.3550547-21-himal.prasad.ghimiray@intel.com>
On Tue, Jul 22, 2025 at 07:05:23PM +0530, Himal Prasad Ghimiray wrote:
> Restore default memory attributes for VMAs during garbage collection
> if they were modified by madvise. Reuse existing VMA if fully overlapping;
> otherwise, allocate a new mirror VMA.
>
> Suggested-by: Matthew Brost <matthew.brost@intel.com>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_svm.c | 34 +++++++++
> drivers/gpu/drm/xe/xe_vm.c | 140 +++++++++++++++++++++++++-----------
> drivers/gpu/drm/xe/xe_vm.h | 2 +
> 3 files changed, 135 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
> index ba1233d0d5a2..79709dc066b9 100644
> --- a/drivers/gpu/drm/xe/xe_svm.c
> +++ b/drivers/gpu/drm/xe/xe_svm.c
> @@ -255,7 +255,18 @@ static int __xe_svm_garbage_collector(struct xe_vm *vm,
> static int xe_svm_garbage_collector(struct xe_vm *vm)
> {
> struct xe_svm_range *range;
> + struct xe_vma *vma;
> + u64 range_start;
> + u64 range_size;
> + u64 range_end;
> int err;
> + struct xe_vma_mem_attr default_attr = {
> + .preferred_loc = {
> + .devmem_fd = DRM_XE_PREFERRED_LOC_DEFAULT_DEVICE,
> + .migration_policy = DRM_XE_MIGRATE_ALL_PAGES,
> + },
> + .atomic_access = DRM_XE_ATOMIC_UNDEFINED,
> + };
>
> lockdep_assert_held_write(&vm->lock);
>
> @@ -270,6 +281,12 @@ static int xe_svm_garbage_collector(struct xe_vm *vm)
> if (!range)
> break;
>
> + range_start = xe_svm_range_start(range);
> + range_size = xe_svm_range_size(range);
> + range_end = xe_svm_range_end(range);
> +
> + vma = xe_vm_find_vma_by_addr(vm, xe_svm_range_start(range));
> +
I'd find the VMA outside of the svm.garbage_collector.lock.
> list_del(&range->garbage_collector_link);
> spin_unlock(&vm->svm.garbage_collector.lock);
>
> @@ -282,7 +299,24 @@ static int xe_svm_garbage_collector(struct xe_vm *vm)
> return err;
> }
>
> + if (!xe_vma_has_default_mem_attrs(vma)) {
It seems possible the VMA could be NULL in error cases. I'd check for
NULL and error out.
Also could this code be moved to a helper? Internal SVM seems ok, in
that case xe_vm_find_vma_by_addr could also be in the helper.
> + vm_dbg(&vm->xe->drm, "Existing VMA start=0x%016llx, vma_end=0x%016llx",
> + xe_vma_start(vma), xe_vma_end(vma));
> +
> + if (xe_vma_start(vma) == range_start && xe_vma_end(vma) == range_end) {
> + default_attr.pat_index = vma->attr.default_pat_index;
> + default_attr.default_pat_index = vma->attr.default_pat_index;
> + vma->attr = default_attr;
> + } else {
> + vm_dbg(&vm->xe->drm, "Split VMA start=0x%016llx, vma_end=0x%016llx",
> + range_start, range_end);
> + err = xe_vm_alloc_cpu_addr_mirror_vma(vm, range_start, range_size);
> + if (err)
On error, I'd print a message and kill the VM as it shouldn't be
possible to fail aside from a memory allocation failure and we can't
code with errors given this can be inside a worker.
I'll circle back to the rest of the patch a bit later.
Matt
> + return err;
> + }
> + }
> spin_lock(&vm->svm.garbage_collector.lock);
> +
> }
> spin_unlock(&vm->svm.garbage_collector.lock);
>
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index d3f08bf9a3ee..003c8209f8bd 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -4254,34 +4254,24 @@ bool xe_vma_need_vram_for_atomic(struct xe_device *xe, struct xe_vma *vma, bool
> }
> }
>
> -/**
> - * xe_vm_alloc_madvise_vma - Allocate VMA's with madvise ops
> - * @vm: Pointer to the xe_vm structure
> - * @start: Starting input address
> - * @range: Size of the input range
> - *
> - * This function splits existing vma to create new vma for user provided input range
> - *
> - * Return: 0 if success
> - */
> -int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
> +static int xe_vm_alloc_vma(struct xe_vm *vm,
> + u64 start, u64 range,
> + enum drm_gpuvm_sm_map_ops_flags flags)
> {
> struct xe_vma_ops vops;
> struct drm_gpuva_ops *ops = NULL;
> struct drm_gpuva_op *__op;
> bool is_cpu_addr_mirror = false;
> bool remap_op = false;
> + bool is_madvise = flags == DRM_GPUVM_SKIP_GEM_OBJ_VA_SPLIT_MADVISE;
> struct xe_vma_mem_attr tmp_attr;
> + u16 default_pat;
> int err;
>
> - vm_dbg(&vm->xe->drm, "MADVISE IN: addr=0x%016llx, size=0x%016llx", start, range);
> -
> lockdep_assert_held_write(&vm->lock);
>
> - vm_dbg(&vm->xe->drm, "MADVISE_OPS_CREATE: addr=0x%016llx, size=0x%016llx", start, range);
> ops = drm_gpuvm_sm_map_ops_create(&vm->gpuvm, start, range,
> - DRM_GPUVM_SKIP_GEM_OBJ_VA_SPLIT_MADVISE,
> - NULL, start);
> + flags, NULL, start);
> if (IS_ERR(ops))
> return PTR_ERR(ops);
>
> @@ -4292,33 +4282,56 @@ int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
>
> drm_gpuva_for_each_op(__op, ops) {
> struct xe_vma_op *op = gpuva_op_to_vma_op(__op);
> + struct xe_vma *vma = NULL;
>
> - if (__op->op == DRM_GPUVA_OP_REMAP) {
> - xe_assert(vm->xe, !remap_op);
> - remap_op = true;
> + if (!is_madvise) {
> + if (__op->op == DRM_GPUVA_OP_UNMAP) {
> + vma = gpuva_to_vma(op->base.unmap.va);
> + XE_WARN_ON(!xe_vma_has_default_mem_attrs(vma));
> + default_pat = vma->attr.default_pat_index;
> + }
>
> - if (xe_vma_is_cpu_addr_mirror(gpuva_to_vma(op->base.remap.unmap->va)))
> - is_cpu_addr_mirror = true;
> - else
> - is_cpu_addr_mirror = false;
> - }
> + if (__op->op == DRM_GPUVA_OP_REMAP) {
> + vma = gpuva_to_vma(op->base.remap.unmap->va);
> + default_pat = vma->attr.default_pat_index;
> + }
>
> - if (__op->op == DRM_GPUVA_OP_MAP) {
> - xe_assert(vm->xe, remap_op);
> - remap_op = false;
> + if (__op->op == DRM_GPUVA_OP_MAP) {
> + op->map.is_cpu_addr_mirror = true;
> + op->map.pat_index = default_pat;
> + }
> + } else {
> + if (__op->op == DRM_GPUVA_OP_REMAP) {
> + vma = gpuva_to_vma(op->base.remap.unmap->va);
> + xe_assert(vm->xe, !remap_op);
> + remap_op = true;
>
> - /* In case of madvise ops DRM_GPUVA_OP_MAP is always after
> - * DRM_GPUVA_OP_REMAP, so ensure we assign op->map.is_cpu_addr_mirror true
> - * if REMAP is for xe_vma_is_cpu_addr_mirror vma
> - */
> - op->map.is_cpu_addr_mirror = is_cpu_addr_mirror;
> - }
> + if (xe_vma_is_cpu_addr_mirror(vma))
> + is_cpu_addr_mirror = true;
> + else
> + is_cpu_addr_mirror = false;
> + }
>
> + if (__op->op == DRM_GPUVA_OP_MAP) {
> + xe_assert(vm->xe, remap_op);
> + remap_op = false;
> + /*
> + * In case of madvise ops DRM_GPUVA_OP_MAP is
> + * always after DRM_GPUVA_OP_REMAP, so ensure
> + * we assign op->map.is_cpu_addr_mirror true
> + * if REMAP is for xe_vma_is_cpu_addr_mirror vma
> + */
> + op->map.is_cpu_addr_mirror = is_cpu_addr_mirror;
> + }
> + }
> print_op(vm->xe, __op);
> }
>
> xe_vma_ops_init(&vops, vm, NULL, NULL, 0);
> - vops.flags |= XE_VMA_OPS_FLAG_MADVISE;
> +
> + if (is_madvise)
> + vops.flags |= XE_VMA_OPS_FLAG_MADVISE;
> +
> err = vm_bind_ioctl_ops_parse(vm, ops, &vops);
> if (err)
> goto unwind_ops;
> @@ -4330,15 +4343,20 @@ int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
> struct xe_vma *vma;
>
> if (__op->op == DRM_GPUVA_OP_UNMAP) {
> - /* There should be no unmap */
> - XE_WARN_ON("UNEXPECTED UNMAP");
> - xe_vma_destroy(gpuva_to_vma(op->base.unmap.va), NULL);
> + vma = gpuva_to_vma(op->base.unmap.va);
> + /* There should be no unmap for madvise */
> + if (is_madvise)
> + XE_WARN_ON("UNEXPECTED UNMAP");
> +
> + xe_vma_destroy(vma, NULL);
> } else if (__op->op == DRM_GPUVA_OP_REMAP) {
> vma = gpuva_to_vma(op->base.remap.unmap->va);
> - /* Store attributes for REMAP UNMAPPED VMA, so they can be assigned
> - * to newly MAP created vma.
> + /* In case of madvise ops Store attributes for REMAP UNMAPPED
> + * VMA, so they can be assigned to newly MAP created vma.
> */
> - tmp_attr = vma->attr;
> + if (is_madvise)
> + tmp_attr = vma->attr;
> +
> xe_vma_destroy(gpuva_to_vma(op->base.remap.unmap->va), NULL);
> } else if (__op->op == DRM_GPUVA_OP_MAP) {
> vma = op->map.vma;
> @@ -4346,7 +4364,8 @@ int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
> * Therefore temp_attr will always have sane values, making it safe to
> * copy them to new vma.
> */
> - vma->attr = tmp_attr;
> + if (is_madvise)
> + vma->attr = tmp_attr;
> }
> }
>
> @@ -4360,3 +4379,42 @@ int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
> drm_gpuva_ops_free(&vm->gpuvm, ops);
> return err;
> }
> +
> +/**
> + * xe_vm_alloc_madvise_vma - Allocate VMA's with madvise ops
> + * @vm: Pointer to the xe_vm structure
> + * @start: Starting input address
> + * @range: Size of the input range
> + *
> + * This function splits existing vma to create new vma for user provided input range
> + *
> + * Return: 0 if success
> + */
> +int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
> +{
> + lockdep_assert_held_write(&vm->lock);
> +
> + vm_dbg(&vm->xe->drm, "MADVISE_OPS_CREATE: addr=0x%016llx, size=0x%016llx", start, range);
> +
> + return xe_vm_alloc_vma(vm, start, range, DRM_GPUVM_SKIP_GEM_OBJ_VA_SPLIT_MADVISE);
> +}
> +
> +/**
> + * xe_vm_alloc_cpu_addr_mirror_vma - Allocate CPU addr mirror vma
> + * @vm: Pointer to the xe_vm structure
> + * @start: Starting input address
> + * @range: Size of the input range
> + *
> + * This function splits/merges existing vma to create new vma for user provided input range
> + *
> + * Return: 0 if success
> + */
> +int xe_vm_alloc_cpu_addr_mirror_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
> +{
> + lockdep_assert_held_write(&vm->lock);
> +
> + vm_dbg(&vm->xe->drm, "CPU_ADDR_MIRROR_VMA_OPS_CREATE: addr=0x%016llx, size=0x%016llx",
> + start, range);
> +
> + return xe_vm_alloc_vma(vm, start, range, DRM_GPUVM_SM_MAP_NOT_MADVISE);
> +}
> diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
> index a4db843de540..f7b9ad83685a 100644
> --- a/drivers/gpu/drm/xe/xe_vm.h
> +++ b/drivers/gpu/drm/xe/xe_vm.h
> @@ -177,6 +177,8 @@ bool xe_vma_need_vram_for_atomic(struct xe_device *xe, struct xe_vma *vma, bool
>
> int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t addr, uint64_t size);
>
> +int xe_vm_alloc_cpu_addr_mirror_vma(struct xe_vm *vm, uint64_t addr, uint64_t size);
> +
> /**
> * to_userptr_vma() - Return a pointer to an embedding userptr vma
> * @vma: Pointer to the embedded struct xe_vma
> --
> 2.34.1
>
next prev parent reply other threads:[~2025-07-24 21:49 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-22 13:35 [PATCH v5 00/23] MADVISE FOR XE Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 01/23] Introduce drm_gpuvm_sm_map_ops_flags enums for sm_map_ops Himal Prasad Ghimiray
2025-07-22 13:38 ` Danilo Krummrich
2025-07-24 0:43 ` Matthew Brost
2025-07-24 10:05 ` Ghimiray, Himal Prasad
2025-07-24 10:32 ` Caterina Shablia
2025-07-28 10:20 ` Ghimiray, Himal Prasad
2025-07-24 10:02 ` Ghimiray, Himal Prasad
2025-07-27 21:18 ` Matthew Brost
2025-07-28 6:16 ` Ghimiray, Himal Prasad
2025-07-22 13:35 ` [PATCH v5 02/23] drm/xe/uapi: Add madvise interface Himal Prasad Ghimiray
2025-07-29 3:29 ` Matthew Brost
2025-07-22 13:35 ` [PATCH v5 03/23] drm/xe/vm: Add attributes struct as member of vma Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 04/23] drm/xe/vma: Move pat_index to vma attributes Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 05/23] drm/xe/vma: Modify new_vma to accept struct xe_vma_mem_attr as parameter Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 06/23] drm/gpusvm: Make drm_gpusvm_for_each_* macros public Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 07/23] drm/xe/svm: Split system allocator vma incase of madvise call Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 08/23] drm/xe: Allow CPU address mirror VMA unbind with gpu bindings for madvise Himal Prasad Ghimiray
2025-07-29 3:40 ` Matthew Brost
2025-07-29 7:42 ` Ghimiray, Himal Prasad
2025-07-22 13:35 ` [PATCH v5 09/23] drm/xe/svm: Add xe_svm_ranges_zap_ptes_in_range() for PTE zapping Himal Prasad Ghimiray
2025-07-29 3:42 ` Matthew Brost
2025-07-22 13:35 ` [PATCH v5 10/23] drm/xe: Implement madvise ioctl for xe Himal Prasad Ghimiray
2025-07-29 3:52 ` Matthew Brost
2025-07-29 4:23 ` Matthew Brost
2025-07-29 9:43 ` Ghimiray, Himal Prasad
2025-07-22 13:35 ` [PATCH v5 11/23] drm/xe/svm : Add svm ranges migration policy on atomic access Himal Prasad Ghimiray
2025-07-29 4:04 ` Matthew Brost
2025-07-30 4:59 ` Ghimiray, Himal Prasad
2025-07-22 13:35 ` [PATCH v5 12/23] drm/xe/madvise: Update migration policy based on preferred location Himal Prasad Ghimiray
2025-07-29 4:07 ` Matthew Brost
2025-07-22 13:35 ` [PATCH v5 13/23] drm/xe/svm: Support DRM_XE_SVM_ATTR_PAT memory attribute Himal Prasad Ghimiray
2025-07-23 16:55 ` Ghimiray, Himal Prasad
2025-07-22 13:35 ` [PATCH v5 14/23] drm/xe/uapi: Add flag for consulting madvise hints on svm prefetch Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 15/23] drm/xe/svm: Consult madvise preferred location in prefetch Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 16/23] drm/xe/bo: Add attributes field to xe_bo Himal Prasad Ghimiray
2025-07-22 13:35 ` [PATCH v5 17/23] drm/xe/bo: Update atomic_access attribute on madvise Himal Prasad Ghimiray
2025-07-29 4:18 ` Matthew Brost
2025-07-22 13:35 ` [PATCH v5 18/23] drm/xe/madvise: Skip vma invalidation if mem attr are unchanged Himal Prasad Ghimiray
2025-07-29 4:19 ` Matthew Brost
2025-07-22 13:35 ` [PATCH v5 19/23] drm/xe/vm: Add helper to check for default VMA memory attributes Himal Prasad Ghimiray
2025-07-29 4:33 ` Matthew Brost
2025-07-22 13:35 ` [PATCH v5 20/23] drm/xe: Reset VMA attributes to default in SVM garbage collector Himal Prasad Ghimiray
2025-07-24 21:50 ` Matthew Brost [this message]
2025-07-29 5:27 ` Matthew Brost
2025-07-30 6:09 ` Ghimiray, Himal Prasad
2025-07-29 5:41 ` Matthew Brost
2025-07-30 6:06 ` Ghimiray, Himal Prasad
2025-07-22 13:35 ` [PATCH v5 21/23] drm/xe/vm: Add a delayed worker to merge fragmented vmas Himal Prasad Ghimiray
2025-07-29 4:39 ` Matthew Brost
2025-07-30 11:08 ` Ghimiray, Himal Prasad
2025-07-22 13:35 ` [PATCH v5 22/23] drm/xe: Enable madvise ioctl for xe Himal Prasad Ghimiray
2025-07-29 4:34 ` Matthew Brost
2025-07-22 13:35 ` [PATCH v5 23/23] drm/xe/uapi: Add UAPI for querying VMA count and memory attributes Himal Prasad Ghimiray
2025-07-29 5:37 ` Matthew Brost
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aIKqt67Ob0sYuDIO@lstrano-desk.jf.intel.com \
--to=matthew.brost@intel.com \
--cc=himal.prasad.ghimiray@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=thomas.hellstrom@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.