On Wed, Nov 04, 2026 at 05:16:27PM -0800, Niranjana Vishwanathapura wrote:
> On Wed, Nov 04, 2026 at 01:52:28PM -0800, Matthew Brost wrote:
> > From: Thomas Hellström <[email protected]>
> > 
> > Expose per-page-order DMA mapping counts for the system memory that the
> > xe driver maps for GPU access, split into two categories: TTM buffer
> > objects, and the GPU SVM / userptr ranges (which share a single
> > drm_gpusvm instance per VM).
> > 
> > The stats are visible at:
> > 
> >  <debugfs>/dri/<N>/dma_mapped_pages
> > 
> > and are broken out into two rows (bo, svm/userptr), one column per page
> > order, mirroring the layout of the TTM pool page_pool stat.
> > 
> > For TTM BOs the per-order counts are derived from the DMA scatter-gather
> > table: each mapped segment is physically contiguous, so its page count is
> > split into the largest power-of-two runs (a segment of N pages contributes
> > a 2^k chunk for the largest k with 2^k <= N, repeated for the remainder).
> > Driving the accounting off the sg table rather than the pages[] array keeps
> > it correct even when pages[] entries are cleared while still DMA-mapped,
> > as happens on the defrag page-borrowing path. Dma-buf BOs are not
> > accounted for in dma_mapped_pages stats.
> > 
> > For the SVM and userptr ranges the accounting is driven by the
> > drm_gpusvm @dma_map_account callback, which fires once per dma_addr[]
> > entry at the exact point the entry is DMA-mapped and unmapped. This
> > makes the accounting symmetric by construction and avoids driver-side
> > walks that could drift across migration, partial unmaps and the iova vs
> > non-iova paths. Only DRM_INTERCONNECT_SYSTEM entries are real DMA maps
> > and counted; device interconnect (VRAM, P2P) entries are skipped, so the
> > counter reflects only system pages actually mapped through the DMA layer.
> > 
> > The callback is shared between the full SVM instance (fault mode) and the
> > core drm_gpusvm_pages-only instance used for userptr, so userptr
> > mappings are accounted in both the CONFIG_DRM_XE_GPUSVM=y and =n (but
> > CONFIG_DRM_GPUSVM=y) configurations, into the same svm/userptr counter.
> > 
> > Since the counts are only ever consumed through debugfs, gate the counter
> > storage and all accounting on CONFIG_DEBUG_FS so that builds without
> > debugfs carry no extra atomic traffic or device state; the drm_gpusvm
> > callback is simply left unregistered in that case.
> > 
> > On device teardown assert that every counter has returned to zero, to
> > catch any unbalanced accounting (a leaked DMA mapping) during testing.
> > 
> > Assisted-by: LLM
> > Signed-off-by: Thomas Hellström <[email protected]>
> > Signed-off-by: Matthew Brost <[email protected]>
> > ---
> > drivers/gpu/drm/xe/xe_bo.c           | 53 ++++++++++++++++++++---
> > drivers/gpu/drm/xe/xe_debugfs.c      | 26 ++++++++++++
> > drivers/gpu/drm/xe/xe_device.c       | 30 +++++++++++++
> > drivers/gpu/drm/xe/xe_device_types.h | 17 ++++++++
> > drivers/gpu/drm/xe/xe_svm.c          | 44 ++++++++++++++++++-
> > drivers/gpu/drm/xe/xe_svm.h          |  4 +-
> > drivers/gpu/drm/xe/xe_userptr.c      | 63 ++++++++++++++++++++++++++++
> > drivers/gpu/drm/xe/xe_userptr.h      |  1 +
> > 8 files changed, 230 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> > index 42a6aa1a2e4a..a8031cb9c74f 100644
> > --- a/drivers/gpu/drm/xe/xe_bo.c
> > +++ b/drivers/gpu/drm/xe/xe_bo.c
> > @@ -396,6 +396,50 @@ struct xe_ttm_tt {
> >     bool purgeable;
> > };
> > 
> > +/*
> > + * xe_tt_account_dma_pages - account DMA-mapped tt pages per order
> > + * @xe: the xe device
> > + * @xe_tt: the xe_ttm_tt whose sg table to walk
> > + * @sign: +1 to add, -1 to subtract
> > + *
> > + * Walk the tt's DMA scatter-gather table and split each (physically
> > + * contiguous) segment into the largest power-of-two page runs: a segment 
> > of N
> > + * pages contributes a 2^k chunk for the largest k with 2^k <= N, repeated 
> > for
> > + * the remainder. Accumulate the count of 2^k pages into
> > + * xe->mem.dma_mapped_pages[k]. Driving this off the sg table rather than
> > + * tt->pages keeps the accounting correct even when pages[] entries are 
> > cleared
> > + * while still DMA-mapped (e.g. the defrag page-borrowing path).
> > + */
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +static void xe_tt_account_dma_pages(struct xe_device *xe,
> > +                               struct xe_ttm_tt *xe_tt, int sign)
> > +{
> > +   struct scatterlist *sg;
> > +   unsigned int i;
> > +
> > +   for_each_sgtable_sg(xe_tt->sg, sg, i) {
> > +           unsigned long nr_pages = sg->length >> PAGE_SHIFT;
> > +
> > +           while (nr_pages) {
> > +                   unsigned int order = min_t(unsigned int,
> > +                                              __fls(nr_pages),
> > +                                              MAX_PAGE_ORDER);
> > +                   unsigned long chunk = 1UL << order;
> > +
> > +                   atomic_long_add((long)chunk * sign,
> > +                                   &xe->mem.dma_mapped_pages[order]);
> > +
> 
> Here both array index and array value is clamped.
> But in the svm case below, only the array index is clamped, but not the value.
> I guess here we don't expect huge pages? If so, should we be clamping here
> or asserting if order is bigger than MAX_PAGE_ORDER?
> 

What? I'm not following this at all.

The SVM case we clamp the index to the highest order + add the actual order.

Here we decompose a segment to into individual orders, clamping at the
highest order.

> > +                   nr_pages -= chunk;
> > +           }
> > +   }
> > +}
> > +#else
> > +static void xe_tt_account_dma_pages(struct xe_device *xe,
> > +                               struct xe_ttm_tt *xe_tt, int sign)
> > +{
> > +}
> > +#endif
> > +
> > static int xe_tt_map_sg(struct xe_device *xe, struct ttm_tt *tt)
> > {
> >     struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
> > @@ -425,6 +469,7 @@ static int xe_tt_map_sg(struct xe_device *xe, struct 
> > ttm_tt *tt)
> >             return ret;
> >     }
> > 
> > +   xe_tt_account_dma_pages(xe, xe_tt, 1);
> >     return 0;
> > }
> > 
> > @@ -433,6 +478,7 @@ static void xe_tt_unmap_sg(struct xe_device *xe, struct 
> > ttm_tt *tt)
> >     struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
> > 
> >     if (xe_tt->sg) {
> > +           xe_tt_account_dma_pages(xe, xe_tt, -1);
> >             dma_unmap_sgtable(xe->drm.dev, xe_tt->sg,
> >                               DMA_BIDIRECTIONAL, 0);
> >             sg_free_table(xe_tt->sg);
> > @@ -1800,11 +1846,8 @@ int xe_bo_dma_unmap_pinned(struct xe_bo *bo)
> >                     ttm_bo->sg = NULL;
> >                     xe_tt->sg = NULL;
> >             } else if (xe_tt->sg) {
> > -                   
> > dma_unmap_sgtable(ttm_to_xe_device(ttm_bo->bdev)->drm.dev,
> > -                                     xe_tt->sg,
> > -                                     DMA_BIDIRECTIONAL, 0);
> > -                   sg_free_table(xe_tt->sg);
> > -                   xe_tt->sg = NULL;
> > +                   xe_tt_unmap_sg(ttm_to_xe_device(ttm_bo->bdev),
> > +                                  &xe_tt->ttm);
> >             }
> >     }
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_debugfs.c 
> > b/drivers/gpu/drm/xe/xe_debugfs.c
> > index e59d4964d811..1a306b6523e7 100644
> > --- a/drivers/gpu/drm/xe/xe_debugfs.c
> > +++ b/drivers/gpu/drm/xe/xe_debugfs.c
> > @@ -7,6 +7,7 @@
> > 
> > #include <linux/bits.h>
> > #include <linux/debugfs.h>
> > +#include <linux/mmzone.h>
> > #include <linux/fault-inject.h>
> > #include <linux/string_helpers.h>
> > 
> > @@ -345,6 +346,28 @@ static int dgfx_pcie_link_residencies_show(struct 
> > seq_file *m, void *data)
> >     return 0;
> > }
> > 
> > +static int dma_mapped_pages_show(struct seq_file *m, void *data)
> > +{
> > +   struct xe_device *xe = m->private;
> > +   unsigned int i;
> > +
> > +   seq_printf(m, "%-11s ", "");
> > +   for (i = 0; i < NR_PAGE_ORDERS; i++)
> > +           seq_printf(m, " ---%2u---", i);
> > +   seq_printf(m, "\n%-11s:", "bo");
> > +   for (i = 0; i < NR_PAGE_ORDERS; i++)
> > +           seq_printf(m, " %8lu",
> > +                      atomic_long_read(&xe->mem.dma_mapped_pages[i]));
> > +   seq_printf(m, "\n%-11s:", "svm/userptr");
> > +   for (i = 0; i < NR_PAGE_ORDERS; i++)
> > +           seq_printf(m, " %8lu",
> > +                      atomic_long_read(&xe->mem.dma_mapped_pages_svm[i]));
> 
> The array values are signed long, but printed as unsigned.
> Should we use '%8l' instead of '%8lu'?
> 

If we ever underflow that is problem, I guess %8l would have that clear.

> Also, under each order column, we are not printing the number of pages
> of that order, but instead the 4kb page count mapped in that order.
> Is that intended?

Yes.

> As we are counting huge pages in the highest order bucket, counting the
> 4kb page count seems necessary here. But perhaps needs to be documented.
> 

A segment can be larger NR_PAGE_ORDERS, thus we clamp large segments
into the highest order. I don't we really need much an explaination, the
debugfs clearly shows if we getting higher order pages, which is the
information we are looking for during debug of perf problems on iGPU.

> Niranjana
> 
> > +   seq_puts(m, "\n");
> > +
> > +   return 0;
> > +}
> > +DEFINE_SHOW_ATTRIBUTE(dma_mapped_pages);
> > +
> > static const struct drm_info_list debugfs_list[] = {
> >     {"info", info, 0},
> >     { .name = "sriov_info", .show = sriov_info, },
> > @@ -765,6 +788,9 @@ void xe_debugfs_register(struct xe_device *xe)
> > 
> >     xe_ttm_vram_debugfs_init(xe, root);
> > 
> > +   debugfs_create_file("dma_mapped_pages", 0444, root, xe,
> > +                       &dma_mapped_pages_fops);
> > +
> >     for_each_tile(tile, xe, tile_id)
> >             xe_tile_debugfs_register(tile);
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> > index 273e2c45fea9..c40bb8f7c697 100644
> > --- a/drivers/gpu/drm/xe/xe_device.c
> > +++ b/drivers/gpu/drm/xe/xe_device.c
> > @@ -377,12 +377,42 @@ bool xe_device_is_admin_only(const struct xe_device 
> > *xe)
> > /* Number of allocated struct xe_device */
> > static atomic_t xe_device_count;
> > 
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +static void xe_device_assert_dma_pages_zero(struct xe_device *xe)
> > +{
> > +   unsigned int i;
> > +
> > +   /*
> > +    * All BOs, userptr VMAs and SVM ranges must have been torn down by the
> > +    * time the device is destroyed, so every DMA-mapped-pages counter must
> > +    * have returned to zero. A non-zero value indicates unbalanced
> > +    * accounting, i.e. a missing unmap-side decrement.
> > +    */
> > +   for (i = 0; i < NR_PAGE_ORDERS; i++) {
> > +           xe_assert(xe, !atomic_long_read(&xe->mem.dma_mapped_pages[i]));
> > +           xe_assert(xe, 
> > !atomic_long_read(&xe->mem.dma_mapped_pages_svm[i]));
> > +   }
> 
> xe_assert() is only valid with CONFIG_DRM_XE_DEBUG.
> So, it is kind of tied to CONFIG_DRM_XE_DEBUG. So, it goes back to original
> comment as to if we should make it xe debug specific and only make the
> debugfs interface part CONFIG_DEBUG_FS specific?
> I am fine either way.
> 
> > +}
> > +#else
> > +static void xe_device_assert_dma_pages_zero(struct xe_device *xe)
> > +{
> > +}
> > +#endif
> > +
> > static void xe_device_destroy(struct drm_device *dev, void *dummy)
> > {
> >     struct xe_device *xe = to_xe_device(dev);
> > 
> >     xe_bo_dev_fini(&xe->bo_device);
> > 
> > +   /*
> > +    * Assert the DMA-mapped-pages accounting only after xe_bo_dev_fini()
> > +    * has flushed the async BO-free worker: BOs pending async free still
> > +    * hold their DMA mappings (and counts) until the worker runs, so
> > +    * asserting before the flush could trip a false positive.
> > +    */
> > +   xe_device_assert_dma_pages_zero(xe);
> > +
> >     if (xe->preempt_fence_wq)
> >             destroy_workqueue(xe->preempt_fence_wq);
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_device_types.h 
> > b/drivers/gpu/drm/xe/xe_device_types.h
> > index d99881c6e1d5..e816db751da4 100644
> > --- a/drivers/gpu/drm/xe/xe_device_types.h
> > +++ b/drivers/gpu/drm/xe/xe_device_types.h
> > @@ -6,6 +6,7 @@
> > #ifndef _XE_DEVICE_TYPES_H_
> > #define _XE_DEVICE_TYPES_H_
> > 
> > +#include <linux/mmzone.h>
> > #include <linux/pci.h>
> > 
> > #include <drm/drm_device.h>
> > @@ -302,6 +303,22 @@ struct xe_device {
> >             struct xe_shrinker *shrinker;
> >             /** @mem.stolen_mgr: stolen memory manager. */
> >             struct xe_ttm_stolen_mgr *stolen_mgr;
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +           /**
> > +            * @mem.dma_mapped_pages: number of DMA-mapped pages per page
> > +            * order currently live for this device, for TTM BOs. Only
> > +            * accounted when CONFIG_DEBUG_FS is enabled, since it is solely
> > +            * exposed through debugfs.
> > +            */
> > +           atomic_long_t dma_mapped_pages[NR_PAGE_ORDERS];
> > +           /**
> > +            * @mem.dma_mapped_pages_svm: number of DMA-mapped pages per
> > +            * page order currently live for this device, for SVM ranges
> > +            * and userptr VMAs (both share a single drm_gpusvm instance).
> > +            * Only accounted when CONFIG_DEBUG_FS is enabled.
> > +            */
> > +           atomic_long_t dma_mapped_pages_svm[NR_PAGE_ORDERS];
> > +#endif
> >     } mem;
> > 
> >     /** @sriov: device level virtualization data */
> > diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
> > index 909a602d091e..7a4988289749 100644
> > --- a/drivers/gpu/drm/xe/xe_svm.c
> > +++ b/drivers/gpu/drm/xe/xe_svm.c
> > @@ -845,10 +845,50 @@ static int xe_svm_get_pagemaps(struct xe_vm *vm)
> > }
> > #endif
> > 
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +/*
> > + * xe_svm_dma_map_account - drm_gpusvm DMA-mapping accounting callback
> > + * @gpusvm: The GPU SVM the mapping belongs to
> > + * @addr: The address descriptor of the chunk being (un)mapped
> > + * @sign: +1 when @addr was DMA-mapped, -1 when it is being unmapped
> > + *
> > + * Maintain per-order counts of the system-memory pages that the full SVM
> > + * instance (SVM ranges, and userptr VMAs in fault mode) has DMA-mapped 
> > for GPU
> > + * access. Only DRM_INTERCONNECT_SYSTEM entries are real DMA maps and 
> > counted;
> > + * device interconnect (VRAM, P2P) entries are skipped. The counts are 
> > solely
> > + * exposed through debugfs, so the callback is only registered when
> > + * CONFIG_DEBUG_FS is enabled.
> > + */
> > +static void xe_svm_dma_map_account(struct drm_gpusvm *gpusvm,
> > +                              const struct drm_pagemap_addr *addr,
> > +                              int sign)
> > +{
> > +   struct xe_device *xe = gpusvm_to_vm(gpusvm)->xe;
> > +   unsigned int order = addr->order;
> > +
> > +   if (addr->proto != DRM_INTERCONNECT_SYSTEM)
> > +           return;
> > +
> > +   /*
> > +    * The CPU-PTE map order reported by hmm can exceed MAX_PAGE_ORDER
> > +    * (e.g. an order-18 1GB mapping), so clamp the array index to avoid an
> > +    * out-of-bounds access. Clamping is symmetric across the +1/-1 calls,
> > +    * so the per-order counters stay balanced.
> > +    */
> > +   order = min(order, (unsigned int)NR_PAGE_ORDERS - 1);
> > +
> > +   atomic_long_add((long)(1UL << addr->order) * sign,
> > +                   &xe->mem.dma_mapped_pages_svm[order]);
> > +}
> 
> This seems identical to xe_userptr_dma_map_account() except that there
> gpusvm_to_vm() helper is not there, hence needs to be expanded.
> Can we combine these two helpers into one?
> 

I guess one of files can export it and they can share code.

Matt

> > +#endif
> > +
> > static const struct drm_gpusvm_ops gpusvm_ops = {
> >     .range_alloc = xe_svm_range_alloc,
> >     .range_free = xe_svm_range_free,
> >     .invalidate = xe_svm_invalidate,
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +   .dma_map_account = xe_svm_dma_map_account,
> > +#endif
> > };
> > 
> > static const unsigned long fault_chunk_sizes[] = {
> > @@ -946,8 +986,8 @@ int xe_svm_init(struct xe_vm *vm)
> >             }
> >     } else {
> >             err = drm_gpusvm_init(&vm->svm.gpusvm, "Xe SVM (simple)",
> > -                                 NULL, 0, 0, 0, NULL,
> > -                                 NULL, 0);
> > +                                 NULL, 0, 0, 0,
> > +                                 xe_userptr_gpusvm_ops_get(), NULL, 0);
> >             if (err)
> >                     goto out_err;
> >     }
> > diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
> > index ffc1cc808102..f8b908a74ba9 100644
> > --- a/drivers/gpu/drm/xe/xe_svm.h
> > +++ b/drivers/gpu/drm/xe/xe_svm.h
> > @@ -249,6 +249,7 @@ struct drm_pagemap *xe_drm_pagemap_from_fd(int fd, u32 
> > region_instance);
> > 
> > #else
> > #include <linux/interval_tree.h>
> > +#include "xe_userptr.h"
> > #include "xe_vm.h"
> > 
> > struct drm_pagemap_addr;
> > @@ -296,7 +297,8 @@ int xe_svm_init(struct xe_vm *vm)
> > {
> > #if IS_ENABLED(CONFIG_DRM_GPUSVM)
> >     return drm_gpusvm_init(&vm->svm.gpusvm, "Xe SVM (simple)",
> > -                          NULL, 0, 0, 0, NULL, NULL, 0);
> > +                          NULL, 0, 0, 0,
> > +                          xe_userptr_gpusvm_ops_get(), NULL, 0);
> > #else
> >     return 0;
> > #endif
> > diff --git a/drivers/gpu/drm/xe/xe_userptr.c 
> > b/drivers/gpu/drm/xe/xe_userptr.c
> > index 9c1dac0fce6f..40f97bd4751d 100644
> > --- a/drivers/gpu/drm/xe/xe_userptr.c
> > +++ b/drivers/gpu/drm/xe/xe_userptr.c
> > @@ -8,9 +8,72 @@
> > 
> > #include <linux/mm.h>
> > 
> > +#include <drm/drm_pagemap.h>
> > +
> > #include "xe_tlb_inval.h"
> > #include "xe_trace_bo.h"
> > 
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +/*
> > + * xe_userptr_dma_map_account - drm_gpusvm DMA-mapping accounting callback
> > + * @gpusvm: The GPU SVM the mapping belongs to
> > + * @addr: The address descriptor of the chunk being (un)mapped
> > + * @sign: +1 when @addr was DMA-mapped, -1 when it is being unmapped
> > + *
> > + * Account, per page order, the system-memory pages DMA-mapped for GPU 
> > access
> > + * through the drm_gpusvm_pages instance shared by userptr (and, in fault 
> > mode,
> > + * SVM). Only DRM_INTERCONNECT_SYSTEM entries are real DMA maps and 
> > counted;
> > + * device interconnect (VRAM, P2P) entries are skipped. The counts are 
> > solely
> > + * exposed through debugfs, so the callback is only registered when
> > + * CONFIG_DEBUG_FS is enabled.
> > + */
> > +static void xe_userptr_dma_map_account(struct drm_gpusvm *gpusvm,
> > +                                  const struct drm_pagemap_addr *addr,
> > +                                  int sign)
> > +{
> > +   struct xe_vm *vm = container_of(gpusvm, struct xe_vm, svm.gpusvm);
> > +   unsigned int order = addr->order;
> > +
> > +   if (addr->proto != DRM_INTERCONNECT_SYSTEM)
> > +           return;
> > +
> > +   /*
> > +    * The CPU-PTE map order reported by hmm can exceed MAX_PAGE_ORDER
> > +    * (e.g. an order-18 1GB mapping), so clamp the array index to avoid an
> > +    * out-of-bounds access. Clamping is symmetric across the +1/-1 calls,
> > +    * so the per-order counters stay balanced.
> > +    */
> > +   order = min(order, (unsigned int)NR_PAGE_ORDERS - 1);
> > +
> > +   atomic_long_add((long)(1UL << addr->order) * sign,
> > +                   &vm->xe->mem.dma_mapped_pages_svm[order]);
> > +}
> > +
> > +static const struct drm_gpusvm_ops xe_userptr_gpusvm_ops = {
> > +   .dma_map_account = xe_userptr_dma_map_account,
> > +};
> > +#endif
> > +
> > +/**
> > + * xe_userptr_gpusvm_ops_get() - Accounting ops for the simple gpusvm 
> > instance
> > + *
> > + * The core drm_gpusvm_pages-only instance used for userptr (and, in fault
> > + * mode, shared with SVM) is initialised with these ops so that DMA-mapped
> > + * system pages are accounted and exposed through debugfs. Returns NULL 
> > when
> > + * CONFIG_DEBUG_FS is disabled, in which case no accounting is kept and the
> > + * instance is initialised without ops.
> > + *
> > + * Return: Pointer to the restricted &drm_gpusvm_ops, or NULL.
> > + */
> > +const struct drm_gpusvm_ops *xe_userptr_gpusvm_ops_get(void)
> > +{
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +   return &xe_userptr_gpusvm_ops;
> > +#else
> > +   return NULL;
> > +#endif
> > +}
> > +
> > static void xe_userptr_assert_in_notifier(struct xe_vm *vm)
> > {
> >     lockdep_assert(lockdep_is_held_type(&vm->svm.gpusvm.notifier_lock, 0) ||
> > diff --git a/drivers/gpu/drm/xe/xe_userptr.h 
> > b/drivers/gpu/drm/xe/xe_userptr.h
> > index 2a3cd1b5efbb..1e9601be5713 100644
> > --- a/drivers/gpu/drm/xe/xe_userptr.h
> > +++ b/drivers/gpu/drm/xe/xe_userptr.h
> > @@ -108,6 +108,7 @@ int __xe_vm_userptr_needs_repin(struct xe_vm *vm);
> > int xe_vm_userptr_check_repin(struct xe_vm *vm);
> > int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma);
> > int xe_vma_userptr_check_repin(struct xe_userptr_vma *uvma);
> > +const struct drm_gpusvm_ops *xe_userptr_gpusvm_ops_get(void);
> > #else
> > static inline void xe_userptr_remove(struct xe_userptr_vma *uvma) {}
> > 
> > -- 
> > 2.34.1
> > 

Reply via email to