Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: Matthew Auld <matthew.auld@intel.com>
Cc: <intel-xe@lists.freedesktop.org>,
	<dri-devel@lists.freedesktop.org>,
	<himal.prasad.ghimiray@intel.com>, <apopple@nvidia.com>,
	<airlied@gmail.com>,  <thomas.hellstrom@linux.intel.com>,
	<simona.vetter@ffwll.ch>, <felix.kuehling@amd.com>,
	<dakr@kernel.org>
Subject: Re: [PATCH v4 28/33] drm/xe: Add SVM VRAM migration
Date: Thu, 30 Jan 2025 08:32:45 -0800	[thread overview]
Message-ID: <Z5uprTtHJqOsn0EB@lstrano-desk.jf.intel.com> (raw)
In-Reply-To: <01d5d109-aef5-463f-9475-22c2483501a3@intel.com>

On Thu, Jan 30, 2025 at 02:22:55PM +0000, Matthew Auld wrote:
> On 29/01/2025 19:52, Matthew Brost wrote:
> > Migration is implemented with range granularity, with VRAM backing being
> > a VM private TTM BO (i.e., shares dma-resv with VM). The lifetime of the
> > TTM BO is limited to when the SVM range is in VRAM (i.e., when a VRAM
> > SVM range is migrated to SRAM, the TTM BO is destroyed).
> > 
> > The design choice for using TTM BO for VRAM backing store, as opposed to
> > direct buddy allocation, is as follows:
> > 
> > - DRM buddy allocations are not at page granularity, offering no
> >    advantage over a BO.
> > - Unified eviction is required (SVM VRAM and TTM BOs need to be able to
> >    evict each other).
> > - For exhaustive eviction [1], SVM VRAM allocations will almost certainly
> >    require a dma-resv.
> > - Likely allocation size is 2M which makes of size of BO (872)
> >    acceptable per allocation (872 / 2M == .0004158).
> > 
> > With this, using TTM BO for VRAM backing store seems to be an obvious
> > choice as it allows leveraging of the TTM eviction code.
> > 
> > Current migration policy is migrate any SVM range greater than or equal
> > to 64k once.
> > 
> > [1] https://patchwork.freedesktop.org/series/133643/
> > 
> > v2:
> >   - Rebase on latest GPU SVM
> >   - Retry page fault on get pages returning mixed allocation
> >   - Use drm_gpusvm_devmem
> > v3:
> >   - Use new BO flags
> >   - New range structure (Thomas)
> >   - Hide migration behind Kconfig
> >   - Kernel doc (Thomas)
> >   - Use check_pages_threshold
> > v4:
> >   - Don't evict partial unmaps in garbage collector (Thomas)
> >   - Use %pe to print errors (Thomas)
> >   - Use %p to print pointers (Thomas)
> > 
> > Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> > ---
> >   drivers/gpu/drm/xe/xe_svm.c | 99 +++++++++++++++++++++++++++++++++++--
> >   drivers/gpu/drm/xe/xe_svm.h |  5 ++
> >   2 files changed, 100 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
> > index ba1db030bf33..fc030855d078 100644
> > --- a/drivers/gpu/drm/xe/xe_svm.c
> > +++ b/drivers/gpu/drm/xe/xe_svm.c
> > @@ -502,7 +502,6 @@ static int xe_svm_populate_devmem_pfn(struct drm_gpusvm_devmem *devmem_allocatio
> >   	return 0;
> >   }
> > -__maybe_unused
> >   static const struct drm_gpusvm_devmem_ops gpusvm_devmem_ops = {
> >   	.devmem_release = xe_svm_devmem_release,
> >   	.populate_devmem_pfn = xe_svm_populate_devmem_pfn,
> > @@ -582,6 +581,64 @@ static bool xe_svm_range_is_valid(struct xe_svm_range *range,
> >   	return (range->tile_present & ~range->tile_invalidated) & BIT(tile->id);
> >   }
> > +static struct xe_mem_region *tile_to_mr(struct xe_tile *tile)
> > +{
> > +	return &tile->mem.vram;
> > +}
> > +
> > +static struct xe_bo *xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
> > +				       struct xe_svm_range *range,
> > +				       const struct drm_gpusvm_ctx *ctx)
> > +{
> > +	struct xe_mem_region *mr = tile_to_mr(tile);
> > +	struct drm_buddy_block *block;
> > +	struct list_head *blocks;
> > +	struct xe_bo *bo;
> > +	ktime_t end = 0;
> > +	int err;
> > +
> > +retry:
> > +	xe_vm_lock(vm, false);
> > +	bo = xe_bo_create(tile_to_xe(tile), tile, vm, range->base.itree.last + 1 -
> > +			  range->base.itree.start, ttm_bo_type_device,
> > +			  XE_BO_FLAG_VRAM_IF_DGFX(tile) |
> > +			  XE_BO_FLAG_CPU_ADDR_MIRROR);
> > +	xe_vm_unlock(vm);
> 
> What was the trick again to ensure eviction is not triggered at this point?
> I thought there was some trick with eviction_valuable() but I can't find it.
> 

I dropped that given the hacky nature of how it was implemented. Yes, it
is possible that we allocate VRAM and it is immediately evicted before
the bind occurs but in practice should never really happen given this BO
should be the last entry on the LRU list. Even if this happens, I
believe this is harmless given the bind will abort and trigger a retry.

Matt

> > +	if (IS_ERR(bo)) {
> > +		err = PTR_ERR(bo);
> > +		if (xe_vm_validate_should_retry(NULL, err, &end))
> > +			goto retry;
> > +		return bo;
> > +	}
> > +
> > +	drm_gpusvm_devmem_init(&bo->devmem_allocation,
> > +			       vm->xe->drm.dev, vm->svm.gpusvm.mm,
> > +			       &gpusvm_devmem_ops,
> > +			       &tile->mem.vram.dpagemap,
> > +			       range->base.itree.last + 1 -
> > +			       range->base.itree.start);
> > +
> > +	blocks = &to_xe_ttm_vram_mgr_resource(bo->ttm.resource)->blocks;
> > +	list_for_each_entry(block, blocks, link)
> > +		block->private = mr;
> > +
> > +	/*
> > +	 * Take ref because as soon as drm_gpusvm_migrate_to_devmem succeeds the
> > +	 * creation ref can be dropped upon CPU fault or unmap.
> > +	 */
> > +	xe_bo_get(bo);
> > +
> > +	err = drm_gpusvm_migrate_to_devmem(&vm->svm.gpusvm, &range->base,
> > +					   &bo->devmem_allocation, ctx);
> > +	if (err) {
> > +		xe_bo_put(bo);	/* Local ref */
> > +		xe_bo_put(bo);	/* Creation ref */
> > +		return ERR_PTR(err);
> > +	}
> > +
> > +	return bo;
> > +}
> > +
> >   /**
> >    * xe_svm_handle_pagefault() - SVM handle page fault
> >    * @vm: The VM.
> > @@ -590,7 +647,8 @@ static bool xe_svm_range_is_valid(struct xe_svm_range *range,
> >    * @fault_addr: The GPU fault address.
> >    * @atomic: The fault atomic access bit.
> >    *
> > - * Create GPU bindings for a SVM page fault.
> > + * Create GPU bindings for a SVM page fault. Optionally migrate to device
> > + * memory.
> >    *
> >    * Return: 0 on success, negative error code on error.
> >    */
> > @@ -598,11 +656,18 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
> >   			    struct xe_tile *tile, u64 fault_addr,
> >   			    bool atomic)
> >   {
> > -	struct drm_gpusvm_ctx ctx = { .read_only = xe_vma_read_only(vma), };
> > +	struct drm_gpusvm_ctx ctx = {
> > +		.read_only = xe_vma_read_only(vma),
> > +		.devmem_possible = IS_DGFX(vm->xe) &&
> > +			IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR),
> > +		.check_pages_threshold = IS_DGFX(vm->xe) &&
> > +			IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR) ? SZ_64K : 0,
> > +	};
> >   	struct xe_svm_range *range;
> >   	struct drm_gpusvm_range *r;
> >   	struct drm_exec exec;
> >   	struct dma_fence *fence;
> > +	struct xe_bo *bo = NULL;
> >   	ktime_t end = 0;
> >   	int err;
> > @@ -610,6 +675,9 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
> >   	xe_assert(vm->xe, xe_vma_is_cpu_addr_mirror(vma));
> >   retry:
> > +	xe_bo_put(bo);
> > +	bo = NULL;
> > +
> >   	/* Always process UNMAPs first so view SVM ranges is current */
> >   	err = xe_svm_garbage_collector(vm);
> >   	if (err)
> > @@ -625,9 +693,31 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
> >   	if (xe_svm_range_is_valid(range, tile))
> >   		return 0;
> > +	/* XXX: Add migration policy, for now migrate range once */
> > +	if (!range->migrated && range->base.flags.migrate_devmem &&
> > +	    (range->base.itree.last + 1 - range->base.itree.start) >= SZ_64K) {
> > +		range->migrated = true;
> > +
> > +		bo = xe_svm_alloc_vram(vm, tile, range, &ctx);
> > +		if (IS_ERR(bo)) {
> > +			drm_info(&vm->xe->drm,
> > +				 "VRAM allocation failed, falling back to retrying, asid=%u, errno %pe\n",
> > +				 vm->usm.asid, bo);
> > +			bo = NULL;
> > +			goto retry;
> > +		}
> > +	}
> > +
> >   	err = drm_gpusvm_range_get_pages(&vm->svm.gpusvm, r, &ctx);
> > -	if (err == -EFAULT || err == -EPERM)	/* Corner where CPU mappings have changed */
> > +	/* Corner where CPU mappings have changed */
> > +	if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) {
> > +		if (err == -EOPNOTSUPP)
> > +			drm_gpusvm_range_evict(&vm->svm.gpusvm, &range->base);
> > +		drm_info(&vm->xe->drm,
> > +			 "Get pages failed, falling back to retrying, asid=%u, gpusvm=%p, errno %pe\n",
> > +			 vm->usm.asid, &vm->svm.gpusvm, ERR_PTR(err));
> >   		goto retry;
> > +	}
> >   	if (err)
> >   		goto err_out;
> > @@ -658,6 +748,7 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
> >   	dma_fence_put(fence);
> >   err_out:
> > +	xe_bo_put(bo);
> >   	return err;
> >   }
> > diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
> > index 63daffdfdbf6..4c2576162c39 100644
> > --- a/drivers/gpu/drm/xe/xe_svm.h
> > +++ b/drivers/gpu/drm/xe/xe_svm.h
> > @@ -35,6 +35,11 @@ struct xe_svm_range {
> >   	 * range. Protected by GPU SVM notifier lock.
> >   	 */
> >   	u8 tile_invalidated;
> > +	/**
> > +	 * @migrated: Range has been migrated to device memory, protected by
> > +	 * GPU fault handler locking.
> > +	 */
> > +	u8 migrated	:1;
> >   };
> >   int xe_devm_add(struct xe_tile *tile, struct xe_mem_region *mr);
> 

  reply	other threads:[~2025-01-30 16:32 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-29 19:51 [PATCH v4 00/33] Introduce GPU SVM and Xe SVM implementation Matthew Brost
2025-01-29 19:51 ` [PATCH v4 01/33] drm/xe: Retry BO allocation Matthew Brost
2025-01-29 19:51 ` [PATCH v4 02/33] mm/migrate: Add migrate_device_pfns Matthew Brost
2025-01-31  5:24   ` Alistair Popple
2025-01-31  7:47   ` Gwan-gyeong Mun
2025-02-04 22:17     ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 03/33] mm/migrate: Trylock device page in do_swap_page Matthew Brost
2025-01-29 19:51 ` [PATCH v4 04/33] drm/pagemap: Add DRM pagemap Matthew Brost
2025-02-07  8:34   ` Thomas Hellström
2025-02-10 18:41     ` Matthew Brost
2025-02-11 16:03       ` Thomas Hellström
2025-02-11 18:17         ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 05/33] drm/xe/bo: Introduce xe_bo_put_async Matthew Brost
2025-01-30  8:49   ` Thomas Hellström
2025-01-30 16:26     ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 06/33] drm/gpusvm: Add support for GPU Shared Virtual Memory Matthew Brost
2025-01-30  9:13   ` Thomas Hellström
2025-01-30 11:17   ` Matthew Auld
2025-01-30 13:13     ` Gwan-gyeong Mun
2025-01-30 16:42       ` Matthew Brost
2025-02-07  9:06   ` Thomas Hellström
2025-02-10 17:31     ` Matthew Brost
2025-02-11 15:17       ` Thomas Hellström
2025-02-11 18:05         ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 07/33] drm/xe: Select DRM_GPUSVM Kconfig Matthew Brost
2025-02-07  3:18   ` Ghimiray, Himal Prasad
2025-02-07  9:30   ` Thomas Hellström
2025-01-29 19:51 ` [PATCH v4 08/33] drm/xe/uapi: Add DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR flag Matthew Brost
2025-02-07  9:37   ` Thomas Hellström
2025-02-07 12:11   ` Ghimiray, Himal Prasad
2025-02-07 13:47     ` Upadhyay, Tejas
2025-02-10 19:08       ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 09/33] drm/xe: Add SVM init / close / fini to faulting VMs Matthew Brost
2025-02-07  3:24   ` Ghimiray, Himal Prasad
2025-02-07  9:43   ` Thomas Hellström
2025-01-29 19:51 ` [PATCH v4 10/33] drm/xe: Add dma_addr res cursor Matthew Brost
2025-02-10 19:11   ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 11/33] drm/xe: Nuke VM's mapping upon close Matthew Brost
2025-01-30 10:50   ` Matthew Auld
2025-01-30 16:28     ` Matthew Brost
2025-02-07 10:15   ` Thomas Hellström
2025-02-10 19:16     ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 12/33] drm/xe: Add SVM range invalidation and page fault handler Matthew Brost
2025-02-07 10:32   ` Thomas Hellström
2025-01-29 19:51 ` [PATCH v4 13/33] drm/gpuvm: Add DRM_GPUVA_OP_DRIVER Matthew Brost
2025-02-07 10:36   ` Thomas Hellström
2025-01-29 19:51 ` [PATCH v4 14/33] drm/xe: Add (re)bind to SVM page fault handler Matthew Brost
2025-01-29 19:51 ` [PATCH v4 15/33] drm/xe: Add SVM garbage collector Matthew Brost
2025-02-07 12:42   ` Thomas Hellström
2025-01-29 19:51 ` [PATCH v4 16/33] drm/xe: Add unbind to " Matthew Brost
2025-02-07 12:55   ` Thomas Hellström
2025-02-10 21:17     ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 17/33] drm/xe: Do not allow CPU address mirror VMA unbind if the GPU has bindings Matthew Brost
2025-02-07 13:01   ` Thomas Hellström
2025-01-29 19:51 ` [PATCH v4 18/33] drm/xe: Enable CPU address mirror uAPI Matthew Brost
2025-02-07 13:02   ` Thomas Hellström
2025-01-29 19:51 ` [PATCH v4 19/33] drm/xe/uapi: Add DRM_XE_QUERY_CONFIG_FLAG_HAS_CPU_ADDR_MIRROR Matthew Brost
2025-02-07 11:35   ` Ghimiray, Himal Prasad
2025-02-07 11:35   ` Ghimiray, Himal Prasad
2025-02-07 13:04   ` Thomas Hellström
2025-02-07 13:43     ` Upadhyay, Tejas
2025-02-10 19:15       ` Matthew Brost
2025-01-29 19:51 ` [PATCH v4 20/33] drm/xe: Add migrate layer functions for SVM support Matthew Brost
2025-02-07 13:07   ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 21/33] drm/xe: Add SVM device memory mirroring Matthew Brost
2025-02-07 13:29   ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 22/33] drm/xe: Add drm_gpusvm_devmem to xe_bo Matthew Brost
2025-01-29 19:52 ` [PATCH v4 23/33] drm/xe: Add drm_pagemap ops to SVM Matthew Brost
2025-01-30 10:54   ` Matthew Auld
2025-01-30 13:24     ` Gwan-gyeong Mun
2025-01-30 16:24       ` Matthew Brost
2025-01-29 19:52 ` [PATCH v4 24/33] drm/xe: Add GPUSVM device memory copy vfunc functions Matthew Brost
2025-02-07 13:32   ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 25/33] drm/xe: Add Xe SVM populate_devmem_pfn GPU SVM vfunc Matthew Brost
2025-01-29 19:52 ` [PATCH v4 26/33] drm/xe: Add Xe SVM devmem_release " Matthew Brost
2025-01-29 19:52 ` [PATCH v4 27/33] drm/xe: Add BO flags required for SVM Matthew Brost
2025-02-07 13:54   ` Thomas Hellström
2025-02-11 19:19     ` Matthew Brost
2025-02-11 19:36       ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 28/33] drm/xe: Add SVM VRAM migration Matthew Brost
2025-01-30 14:22   ` Matthew Auld
2025-01-30 16:32     ` Matthew Brost [this message]
2025-01-30 16:41       ` Thomas Hellström
2025-01-30 16:56       ` Matthew Auld
2025-01-30 17:31         ` Matthew Brost
2025-01-30 18:51           ` Thomas Hellström
2025-01-31 17:30             ` Matthew Brost
2025-02-07 13:57   ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 29/33] drm/xe: Basic SVM BO eviction Matthew Brost
2025-02-07 14:45   ` Thomas Hellström
2025-02-11 19:21     ` Matthew Brost
2025-01-29 19:52 ` [PATCH v4 30/33] drm/xe: Add SVM debug Matthew Brost
2025-02-07 14:46   ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 31/33] drm/xe: Add modparam for SVM notifier size Matthew Brost
2025-02-07 14:48   ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 32/33] drm/xe: Add always_migrate_to_vram modparam Matthew Brost
2025-02-07 14:50   ` Thomas Hellström
2025-01-29 19:52 ` [PATCH v4 33/33] drm/doc: gpusvm: Add GPU SVM documentation Matthew Brost
2025-02-07 14:54   ` Thomas Hellström
2025-01-29 21:04 ` ✓ CI.Patch_applied: success for Introduce GPU SVM and Xe SVM implementation (rev4) Patchwork
2025-01-29 21:05 ` ✗ CI.checkpatch: warning " Patchwork
2025-01-29 21:06 ` ✗ CI.KUnit: failure " Patchwork
2025-01-30 13:52 ` [PATCH v4 00/33] Introduce GPU SVM and Xe SVM implementation Gwan-gyeong Mun

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=Z5uprTtHJqOsn0EB@lstrano-desk.jf.intel.com \
    --to=matthew.brost@intel.com \
    --cc=airlied@gmail.com \
    --cc=apopple@nvidia.com \
    --cc=dakr@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=felix.kuehling@amd.com \
    --cc=himal.prasad.ghimiray@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=matthew.auld@intel.com \
    --cc=simona.vetter@ffwll.ch \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox