* [RFC 01/29] drm/xe: Introduce xe_vma_op_prefetch_range struct for prefetch of ranges
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
@ 2025-03-14 8:01 ` Himal Prasad Ghimiray
2025-04-03 20:59 ` Matthew Brost
2025-03-14 8:01 ` [RFC 02/29] drm/xe: Make xe_svm_alloc_vram public Himal Prasad Ghimiray
` (28 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:01 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Add xe_vma_op_prefetch_range struct for svm ranges prefetching, including
an xarray of SVM range pointers, range count, and target memory region.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm_types.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
index 84fa41b9fa20..93224a87ab03 100644
--- a/drivers/gpu/drm/xe/xe_vm_types.h
+++ b/drivers/gpu/drm/xe/xe_vm_types.h
@@ -372,6 +372,16 @@ struct xe_vma_op_unmap_range {
struct xe_svm_range *range;
};
+/** struct xe_vma_op_prefetch_range - VMA prefetch range operation */
+struct xe_vma_op_prefetch_range {
+ /** @range: xarray for SVM ranges data */
+ struct xarray range;
+ /** @ranges_count: number of svm ranges to map */
+ u32 ranges_count;
+ /** @region: memory region to prefetch to */
+ u32 region;
+};
+
/** enum xe_vma_op_flags - flags for VMA operation */
enum xe_vma_op_flags {
/** @XE_VMA_OP_COMMITTED: VMA operation committed */
@@ -414,6 +424,8 @@ struct xe_vma_op {
struct xe_vma_op_map_range map_range;
/** @unmap_range: VMA unmap range operation specific data */
struct xe_vma_op_unmap_range unmap_range;
+ /** @prefetch: VMA prefetch range operation specific data */
+ struct xe_vma_op_prefetch_range prefetch_range;
};
};
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 01/29] drm/xe: Introduce xe_vma_op_prefetch_range struct for prefetch of ranges
2025-03-14 8:01 ` [RFC 01/29] drm/xe: Introduce xe_vma_op_prefetch_range struct for prefetch of ranges Himal Prasad Ghimiray
@ 2025-04-03 20:59 ` Matthew Brost
0 siblings, 0 replies; 52+ messages in thread
From: Matthew Brost @ 2025-04-03 20:59 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:31:58PM +0530, Himal Prasad Ghimiray wrote:
> Add xe_vma_op_prefetch_range struct for svm ranges prefetching, including
> an xarray of SVM range pointers, range count, and target memory region.
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm_types.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
> index 84fa41b9fa20..93224a87ab03 100644
> --- a/drivers/gpu/drm/xe/xe_vm_types.h
> +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> @@ -372,6 +372,16 @@ struct xe_vma_op_unmap_range {
> struct xe_svm_range *range;
> };
>
> +/** struct xe_vma_op_prefetch_range - VMA prefetch range operation */
> +struct xe_vma_op_prefetch_range {
> + /** @range: xarray for SVM ranges data */
> + struct xarray range;
> + /** @ranges_count: number of svm ranges to map */
> + u32 ranges_count;
> + /** @region: memory region to prefetch to */
> + u32 region;
> +};
> +
> /** enum xe_vma_op_flags - flags for VMA operation */
> enum xe_vma_op_flags {
> /** @XE_VMA_OP_COMMITTED: VMA operation committed */
> @@ -414,6 +424,8 @@ struct xe_vma_op {
> struct xe_vma_op_map_range map_range;
> /** @unmap_range: VMA unmap range operation specific data */
> struct xe_vma_op_unmap_range unmap_range;
> + /** @prefetch: VMA prefetch range operation specific data */
> + struct xe_vma_op_prefetch_range prefetch_range;
> };
> };
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 02/29] drm/xe: Make xe_svm_alloc_vram public
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
2025-03-14 8:01 ` [RFC 01/29] drm/xe: Introduce xe_vma_op_prefetch_range struct for prefetch of ranges Himal Prasad Ghimiray
@ 2025-03-14 8:01 ` Himal Prasad Ghimiray
2025-03-27 22:45 ` Matthew Brost
2025-03-14 8:02 ` [RFC 03/29] drm/xe/svm: Helper to add tile masks to svm ranges Himal Prasad Ghimiray
` (27 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:01 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
This function will be used in prefetch too, hence make it public.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_svm.c | 6 +++---
drivers/gpu/drm/xe/xe_svm.h | 13 +++++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index 516898e99b26..2d2b385b691e 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -655,9 +655,9 @@ static struct xe_vram_region *tile_to_vr(struct xe_tile *tile)
return &tile->mem.vram;
}
-static int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
- struct xe_svm_range *range,
- const struct drm_gpusvm_ctx *ctx)
+int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
+ struct xe_svm_range *range,
+ const struct drm_gpusvm_ctx *ctx)
{
struct mm_struct *mm = vm->svm.gpusvm.mm;
struct xe_vram_region *vr = tile_to_vr(tile);
diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
index e059590e5076..976059545173 100644
--- a/drivers/gpu/drm/xe/xe_svm.h
+++ b/drivers/gpu/drm/xe/xe_svm.h
@@ -72,6 +72,10 @@ bool xe_svm_has_mapping(struct xe_vm *vm, u64 start, u64 end);
int xe_svm_bo_evict(struct xe_bo *bo);
void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);
+
+int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
+ struct xe_svm_range *range,
+ const struct drm_gpusvm_ctx *ctx);
#else
static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
{
@@ -124,6 +128,15 @@ static inline
void xe_svm_range_debug(struct xe_svm_range *range, const char *operation)
{
}
+
+static inline
+int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
+ struct xe_svm_range *range,
+ const struct drm_gpusvm_ctx *ctx)
+{
+ return 0;
+}
+
#endif
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 02/29] drm/xe: Make xe_svm_alloc_vram public
2025-03-14 8:01 ` [RFC 02/29] drm/xe: Make xe_svm_alloc_vram public Himal Prasad Ghimiray
@ 2025-03-27 22:45 ` Matthew Brost
2025-03-28 7:51 ` Ghimiray, Himal Prasad
0 siblings, 1 reply; 52+ messages in thread
From: Matthew Brost @ 2025-03-27 22:45 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:31:59PM +0530, Himal Prasad Ghimiray wrote:
> This function will be used in prefetch too, hence make it public.
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_svm.c | 6 +++---
> drivers/gpu/drm/xe/xe_svm.h | 13 +++++++++++++
> 2 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
> index 516898e99b26..2d2b385b691e 100644
> --- a/drivers/gpu/drm/xe/xe_svm.c
> +++ b/drivers/gpu/drm/xe/xe_svm.c
> @@ -655,9 +655,9 @@ static struct xe_vram_region *tile_to_vr(struct xe_tile *tile)
> return &tile->mem.vram;
> }
>
> -static int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
> - struct xe_svm_range *range,
> - const struct drm_gpusvm_ctx *ctx)
All public functions need kernel doc. Patch LGTM though.
Matt
> +int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
> + struct xe_svm_range *range,
> + const struct drm_gpusvm_ctx *ctx)
> {
> struct mm_struct *mm = vm->svm.gpusvm.mm;
> struct xe_vram_region *vr = tile_to_vr(tile);
> diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
> index e059590e5076..976059545173 100644
> --- a/drivers/gpu/drm/xe/xe_svm.h
> +++ b/drivers/gpu/drm/xe/xe_svm.h
> @@ -72,6 +72,10 @@ bool xe_svm_has_mapping(struct xe_vm *vm, u64 start, u64 end);
> int xe_svm_bo_evict(struct xe_bo *bo);
>
> void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);
> +
> +int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
> + struct xe_svm_range *range,
> + const struct drm_gpusvm_ctx *ctx);
> #else
> static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
> {
> @@ -124,6 +128,15 @@ static inline
> void xe_svm_range_debug(struct xe_svm_range *range, const char *operation)
> {
> }
> +
> +static inline
> +int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
> + struct xe_svm_range *range,
> + const struct drm_gpusvm_ctx *ctx)
> +{
> + return 0;
> +}
> +
> #endif
>
> /**
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 02/29] drm/xe: Make xe_svm_alloc_vram public
2025-03-27 22:45 ` Matthew Brost
@ 2025-03-28 7:51 ` Ghimiray, Himal Prasad
0 siblings, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-03-28 7:51 UTC (permalink / raw)
To: Matthew Brost; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On 28-03-2025 04:15, Matthew Brost wrote:
> On Fri, Mar 14, 2025 at 01:31:59PM +0530, Himal Prasad Ghimiray wrote:
>> This function will be used in prefetch too, hence make it public.
>>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> ---
>> drivers/gpu/drm/xe/xe_svm.c | 6 +++---
>> drivers/gpu/drm/xe/xe_svm.h | 13 +++++++++++++
>> 2 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
>> index 516898e99b26..2d2b385b691e 100644
>> --- a/drivers/gpu/drm/xe/xe_svm.c
>> +++ b/drivers/gpu/drm/xe/xe_svm.c
>> @@ -655,9 +655,9 @@ static struct xe_vram_region *tile_to_vr(struct xe_tile *tile)
>> return &tile->mem.vram;
>> }
>>
>> -static int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
>> - struct xe_svm_range *range,
>> - const struct drm_gpusvm_ctx *ctx)
>
> All public functions need kernel doc. Patch LGTM though.
>
> Matt
Sure will add. Thanks
>
>> +int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
>> + struct xe_svm_range *range,
>> + const struct drm_gpusvm_ctx *ctx)
>> {
>> struct mm_struct *mm = vm->svm.gpusvm.mm;
>> struct xe_vram_region *vr = tile_to_vr(tile);
>> diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
>> index e059590e5076..976059545173 100644
>> --- a/drivers/gpu/drm/xe/xe_svm.h
>> +++ b/drivers/gpu/drm/xe/xe_svm.h
>> @@ -72,6 +72,10 @@ bool xe_svm_has_mapping(struct xe_vm *vm, u64 start, u64 end);
>> int xe_svm_bo_evict(struct xe_bo *bo);
>>
>> void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);
>> +
>> +int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
>> + struct xe_svm_range *range,
>> + const struct drm_gpusvm_ctx *ctx);
>> #else
>> static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
>> {
>> @@ -124,6 +128,15 @@ static inline
>> void xe_svm_range_debug(struct xe_svm_range *range, const char *operation)
>> {
>> }
>> +
>> +static inline
>> +int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
>> + struct xe_svm_range *range,
>> + const struct drm_gpusvm_ctx *ctx)
>> +{
>> + return 0;
>> +}
>> +
>> #endif
>>
>> /**
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 03/29] drm/xe/svm: Helper to add tile masks to svm ranges
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
2025-03-14 8:01 ` [RFC 01/29] drm/xe: Introduce xe_vma_op_prefetch_range struct for prefetch of ranges Himal Prasad Ghimiray
2025-03-14 8:01 ` [RFC 02/29] drm/xe: Make xe_svm_alloc_vram public Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 04/29] drm/xe/svm: Make to_xe_range a public function Himal Prasad Ghimiray
` (26 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Introduce a helper to add tile mask of binding present and invalidated
for the range. Add a lockdep_assert to ensure it is protected by GPU SVM
notifier lock.
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/xe/xe_pt.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index ffaf0d02dc7d..cf7a6ba2aec8 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -2178,6 +2178,16 @@ static void unbind_op_commit(struct xe_vm *vm, struct xe_tile *tile,
}
}
+static void range_present_and_invalidated_tile(struct xe_vm *vm,
+ struct xe_svm_range *range,
+ u8 tile_id)
+{
+ lockdep_assert_held(&vm->svm.gpusvm.notifier_lock);
+
+ range->tile_present |= BIT(tile_id);
+ range->tile_invalidated &= ~BIT(tile_id);
+}
+
static void op_commit(struct xe_vm *vm,
struct xe_tile *tile,
struct xe_vm_pgtable_update_ops *pt_update_ops,
@@ -2232,12 +2242,11 @@ static void op_commit(struct xe_vm *vm,
}
case DRM_GPUVA_OP_DRIVER:
{
- if (op->subop == XE_VMA_SUBOP_MAP_RANGE) {
- op->map_range.range->tile_present |= BIT(tile->id);
- op->map_range.range->tile_invalidated &= ~BIT(tile->id);
- } else if (op->subop == XE_VMA_SUBOP_UNMAP_RANGE) {
+ if (op->subop == XE_VMA_SUBOP_MAP_RANGE)
+ range_present_and_invalidated_tile(vm, op->map_range.range, tile->id);
+ else if (op->subop == XE_VMA_SUBOP_UNMAP_RANGE)
op->unmap_range.range->tile_present &= ~BIT(tile->id);
- }
+
break;
}
default:
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 04/29] drm/xe/svm: Make to_xe_range a public function
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (2 preceding siblings ...)
2025-03-14 8:02 ` [RFC 03/29] drm/xe/svm: Helper to add tile masks to svm ranges Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-28 2:57 ` Matthew Brost
2025-03-14 8:02 ` [RFC 05/29] drm/xe/svm: Make xe_svm_range_* end/start/size public Himal Prasad Ghimiray
` (25 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
The to_xe_range function will be used in other files. Therefore, make it
public and add kernel-doc documentation
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_svm.c | 5 -----
drivers/gpu/drm/xe/xe_svm.h | 14 ++++++++++++++
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index 2d2b385b691e..2b041f44730b 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -93,11 +93,6 @@ static void xe_svm_range_free(struct drm_gpusvm_range *range)
kfree(range);
}
-static struct xe_svm_range *to_xe_range(struct drm_gpusvm_range *r)
-{
- return container_of(r, struct xe_svm_range, base);
-}
-
static void
xe_svm_garbage_collector_add_range(struct xe_vm *vm, struct xe_svm_range *range,
const struct mmu_notifier_range *mmu_range)
diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
index 976059545173..1af245400799 100644
--- a/drivers/gpu/drm/xe/xe_svm.h
+++ b/drivers/gpu/drm/xe/xe_svm.h
@@ -139,6 +139,20 @@ int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
#endif
+/**
+ * to_xe_range - Convert a drm_gpusvm_range pointer to a xe_svm_range
+ * @r: Pointer to the drm_gpusvm_range structure
+ *
+ * This function takes a pointer to a drm_gpusvm_range structure and
+ * converts it to a pointer to the containing xe_svm_range structure.
+ *
+ * Return: Pointer to the xe_svm_range structure
+ */
+static inline struct xe_svm_range *to_xe_range(struct drm_gpusvm_range *r)
+{
+ return container_of(r, struct xe_svm_range, base);
+}
+
/**
* xe_svm_range_has_dma_mapping() - SVM range has DMA mapping
* @range: SVM range
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 04/29] drm/xe/svm: Make to_xe_range a public function
2025-03-14 8:02 ` [RFC 04/29] drm/xe/svm: Make to_xe_range a public function Himal Prasad Ghimiray
@ 2025-03-28 2:57 ` Matthew Brost
0 siblings, 0 replies; 52+ messages in thread
From: Matthew Brost @ 2025-03-28 2:57 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:01PM +0530, Himal Prasad Ghimiray wrote:
> The to_xe_range function will be used in other files. Therefore, make it
> public and add kernel-doc documentation
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> ---
> drivers/gpu/drm/xe/xe_svm.c | 5 -----
> drivers/gpu/drm/xe/xe_svm.h | 14 ++++++++++++++
> 2 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
> index 2d2b385b691e..2b041f44730b 100644
> --- a/drivers/gpu/drm/xe/xe_svm.c
> +++ b/drivers/gpu/drm/xe/xe_svm.c
> @@ -93,11 +93,6 @@ static void xe_svm_range_free(struct drm_gpusvm_range *range)
> kfree(range);
> }
>
> -static struct xe_svm_range *to_xe_range(struct drm_gpusvm_range *r)
> -{
> - return container_of(r, struct xe_svm_range, base);
> -}
> -
> static void
> xe_svm_garbage_collector_add_range(struct xe_vm *vm, struct xe_svm_range *range,
> const struct mmu_notifier_range *mmu_range)
> diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
> index 976059545173..1af245400799 100644
> --- a/drivers/gpu/drm/xe/xe_svm.h
> +++ b/drivers/gpu/drm/xe/xe_svm.h
> @@ -139,6 +139,20 @@ int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
>
> #endif
>
> +/**
> + * to_xe_range - Convert a drm_gpusvm_range pointer to a xe_svm_range
> + * @r: Pointer to the drm_gpusvm_range structure
> + *
> + * This function takes a pointer to a drm_gpusvm_range structure and
> + * converts it to a pointer to the containing xe_svm_range structure.
> + *
> + * Return: Pointer to the xe_svm_range structure
> + */
> +static inline struct xe_svm_range *to_xe_range(struct drm_gpusvm_range *r)
> +{
> + return container_of(r, struct xe_svm_range, base);
> +}
> +
> /**
> * xe_svm_range_has_dma_mapping() - SVM range has DMA mapping
> * @range: SVM range
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 05/29] drm/xe/svm: Make xe_svm_range_* end/start/size public
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (3 preceding siblings ...)
2025-03-14 8:02 ` [RFC 04/29] drm/xe/svm: Make to_xe_range a public function Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-27 22:46 ` Matthew Brost
2025-03-14 8:02 ` [RFC 06/29] drm/xe/vm: Update xe_vma_ops_incr_pt_update_ops to take an increment value Himal Prasad Ghimiray
` (24 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
These functions will be used in prefetch too, therefore make them public.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_svm.c | 15 ---------------
drivers/gpu/drm/xe/xe_svm.h | 32 ++++++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index 2b041f44730b..07511011aba6 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -35,21 +35,6 @@ static struct xe_vm *range_to_vm(struct drm_gpusvm_range *r)
return gpusvm_to_vm(r->gpusvm);
}
-static unsigned long xe_svm_range_start(struct xe_svm_range *range)
-{
- return drm_gpusvm_range_start(&range->base);
-}
-
-static unsigned long xe_svm_range_end(struct xe_svm_range *range)
-{
- return drm_gpusvm_range_end(&range->base);
-}
-
-static unsigned long xe_svm_range_size(struct xe_svm_range *range)
-{
- return drm_gpusvm_range_size(&range->base);
-}
-
#define range_debug(r__, operaton__) \
vm_dbg(&range_to_vm(&(r__)->base)->xe->drm, \
"%s: asid=%u, gpusvm=%p, vram=%d,%d, seqno=%lu, " \
diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
index 1af245400799..c8add37614ec 100644
--- a/drivers/gpu/drm/xe/xe_svm.h
+++ b/drivers/gpu/drm/xe/xe_svm.h
@@ -165,6 +165,38 @@ static inline bool xe_svm_range_has_dma_mapping(struct xe_svm_range *range)
return range->base.flags.has_dma_mapping;
}
+/**
+ * xe_svm_range_start() - SVM range start address
+ * @range: SVM range
+ *
+ * Return: start address of range.
+ */
+static inline unsigned long xe_svm_range_start(struct xe_svm_range *range)
+{
+ return drm_gpusvm_range_start(&range->base);
+}
+
+/**
+ * xe_svm_range_start() - SVM range end address
+ * @range: SVM range
+ *
+ * Return: end address of range.
+ */
+static inline unsigned long xe_svm_range_end(struct xe_svm_range *range)
+{
+ return drm_gpusvm_range_end(&range->base);
+}
+
+/**
+ * xe_svm_range_start() - SVM range size
+ * @range: SVM range
+ *
+ * Return: Size of range.
+ */
+static inline unsigned long xe_svm_range_size(struct xe_svm_range *range)
+{
+ return drm_gpusvm_range_size(&range->base);
+}
#define xe_svm_assert_in_notifier(vm__) \
lockdep_assert_held_write(&(vm__)->svm.gpusvm.notifier_lock)
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 05/29] drm/xe/svm: Make xe_svm_range_* end/start/size public
2025-03-14 8:02 ` [RFC 05/29] drm/xe/svm: Make xe_svm_range_* end/start/size public Himal Prasad Ghimiray
@ 2025-03-27 22:46 ` Matthew Brost
0 siblings, 0 replies; 52+ messages in thread
From: Matthew Brost @ 2025-03-27 22:46 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:02PM +0530, Himal Prasad Ghimiray wrote:
> These functions will be used in prefetch too, therefore make them public.
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_svm.c | 15 ---------------
> drivers/gpu/drm/xe/xe_svm.h | 32 ++++++++++++++++++++++++++++++++
> 2 files changed, 32 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
> index 2b041f44730b..07511011aba6 100644
> --- a/drivers/gpu/drm/xe/xe_svm.c
> +++ b/drivers/gpu/drm/xe/xe_svm.c
> @@ -35,21 +35,6 @@ static struct xe_vm *range_to_vm(struct drm_gpusvm_range *r)
> return gpusvm_to_vm(r->gpusvm);
> }
>
> -static unsigned long xe_svm_range_start(struct xe_svm_range *range)
> -{
> - return drm_gpusvm_range_start(&range->base);
> -}
> -
> -static unsigned long xe_svm_range_end(struct xe_svm_range *range)
> -{
> - return drm_gpusvm_range_end(&range->base);
> -}
> -
> -static unsigned long xe_svm_range_size(struct xe_svm_range *range)
> -{
> - return drm_gpusvm_range_size(&range->base);
> -}
> -
> #define range_debug(r__, operaton__) \
> vm_dbg(&range_to_vm(&(r__)->base)->xe->drm, \
> "%s: asid=%u, gpusvm=%p, vram=%d,%d, seqno=%lu, " \
> diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
> index 1af245400799..c8add37614ec 100644
> --- a/drivers/gpu/drm/xe/xe_svm.h
> +++ b/drivers/gpu/drm/xe/xe_svm.h
> @@ -165,6 +165,38 @@ static inline bool xe_svm_range_has_dma_mapping(struct xe_svm_range *range)
> return range->base.flags.has_dma_mapping;
> }
>
> +/**
> + * xe_svm_range_start() - SVM range start address
> + * @range: SVM range
> + *
> + * Return: start address of range.
> + */
> +static inline unsigned long xe_svm_range_start(struct xe_svm_range *range)
> +{
> + return drm_gpusvm_range_start(&range->base);
> +}
> +
> +/**
> + * xe_svm_range_start() - SVM range end address
> + * @range: SVM range
> + *
> + * Return: end address of range.
> + */
> +static inline unsigned long xe_svm_range_end(struct xe_svm_range *range)
> +{
> + return drm_gpusvm_range_end(&range->base);
> +}
> +
> +/**
> + * xe_svm_range_start() - SVM range size
> + * @range: SVM range
> + *
> + * Return: Size of range.
> + */
> +static inline unsigned long xe_svm_range_size(struct xe_svm_range *range)
> +{
> + return drm_gpusvm_range_size(&range->base);
> +}
Need an extra newline here.
With that:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> #define xe_svm_assert_in_notifier(vm__) \
> lockdep_assert_held_write(&(vm__)->svm.gpusvm.notifier_lock)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 06/29] drm/xe/vm: Update xe_vma_ops_incr_pt_update_ops to take an increment value
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (4 preceding siblings ...)
2025-03-14 8:02 ` [RFC 05/29] drm/xe/svm: Make xe_svm_range_* end/start/size public Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-28 2:56 ` Matthew Brost
2025-03-14 8:02 ` [RFC 07/29] drm/xe/vm: Add an identifier in xe_vma_ops for svm prefetch Himal Prasad Ghimiray
` (23 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Prefetch for SVM ranges can have more than one operation to increment,
hence modify the function to accept an increment value as input.
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 60303998bd61..53a80c0af8de 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -806,13 +806,13 @@ static void xe_vma_ops_fini(struct xe_vma_ops *vops)
kfree(vops->pt_update_ops[i].ops);
}
-static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask)
+static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask, u8 inc_val)
{
int i;
for (i = 0; i < XE_MAX_TILES_PER_DEVICE; ++i)
if (BIT(i) & tile_mask)
- ++vops->pt_update_ops[i].num_ops;
+ vops->pt_update_ops[i].num_ops += inc_val;
}
static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
@@ -842,7 +842,7 @@ static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma,
xe_vm_populate_rebind(op, vma, tile_mask);
list_add_tail(&op->link, &vops->list);
- xe_vma_ops_incr_pt_update_ops(vops, tile_mask);
+ xe_vma_ops_incr_pt_update_ops(vops, tile_mask, 1);
return 0;
}
@@ -977,7 +977,7 @@ xe_vm_ops_add_range_rebind(struct xe_vma_ops *vops,
xe_vm_populate_range_rebind(op, vma, range, tile_mask);
list_add_tail(&op->link, &vops->list);
- xe_vma_ops_incr_pt_update_ops(vops, tile_mask);
+ xe_vma_ops_incr_pt_update_ops(vops, tile_mask, 1);
return 0;
}
@@ -1062,7 +1062,7 @@ xe_vm_ops_add_range_unbind(struct xe_vma_ops *vops,
xe_vm_populate_range_unbind(op, range);
list_add_tail(&op->link, &vops->list);
- xe_vma_ops_incr_pt_update_ops(vops, range->tile_present);
+ xe_vma_ops_incr_pt_update_ops(vops, range->tile_present, 1);
return 0;
}
@@ -2475,7 +2475,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
if ((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&
!op->map.is_cpu_addr_mirror)
xe_vma_ops_incr_pt_update_ops(vops,
- op->tile_mask);
+ op->tile_mask, 1);
break;
}
case DRM_GPUVA_OP_REMAP:
@@ -2536,7 +2536,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
(ULL)op->remap.start,
(ULL)op->remap.range);
} else {
- xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
+ xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
}
}
@@ -2565,11 +2565,11 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
(ULL)op->remap.start,
(ULL)op->remap.range);
} else {
- xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
+ xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
}
}
if (!skip)
- xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
+ xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
break;
}
case DRM_GPUVA_OP_UNMAP:
@@ -2581,7 +2581,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
return -EBUSY;
if (!xe_vma_is_cpu_addr_mirror(vma))
- xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
+ xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
break;
case DRM_GPUVA_OP_PREFETCH:
vma = gpuva_to_vma(op->base.prefetch.va);
@@ -2593,7 +2593,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
}
if (!xe_vma_is_cpu_addr_mirror(vma))
- xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
+ xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
break;
default:
drm_warn(&vm->xe->drm, "NOT POSSIBLE");
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 06/29] drm/xe/vm: Update xe_vma_ops_incr_pt_update_ops to take an increment value
2025-03-14 8:02 ` [RFC 06/29] drm/xe/vm: Update xe_vma_ops_incr_pt_update_ops to take an increment value Himal Prasad Ghimiray
@ 2025-03-28 2:56 ` Matthew Brost
2025-03-28 7:52 ` Ghimiray, Himal Prasad
0 siblings, 1 reply; 52+ messages in thread
From: Matthew Brost @ 2025-03-28 2:56 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:03PM +0530, Himal Prasad Ghimiray wrote:
> Prefetch for SVM ranges can have more than one operation to increment,
> hence modify the function to accept an increment value as input.
>
> Suggested-by: Matthew Brost <matthew.brost@intel.com>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm.c | 22 +++++++++++-----------
> 1 file changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 60303998bd61..53a80c0af8de 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -806,13 +806,13 @@ static void xe_vma_ops_fini(struct xe_vma_ops *vops)
> kfree(vops->pt_update_ops[i].ops);
> }
>
> -static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask)
> +static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask, u8 inc_val)
> {
> int i;
>
> for (i = 0; i < XE_MAX_TILES_PER_DEVICE; ++i)
> if (BIT(i) & tile_mask)
> - ++vops->pt_update_ops[i].num_ops;
> + vops->pt_update_ops[i].num_ops += inc_val;
> }
>
> static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
> @@ -842,7 +842,7 @@ static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma,
>
> xe_vm_populate_rebind(op, vma, tile_mask);
> list_add_tail(&op->link, &vops->list);
> - xe_vma_ops_incr_pt_update_ops(vops, tile_mask);
> + xe_vma_ops_incr_pt_update_ops(vops, tile_mask, 1);
>
> return 0;
> }
> @@ -977,7 +977,7 @@ xe_vm_ops_add_range_rebind(struct xe_vma_ops *vops,
>
> xe_vm_populate_range_rebind(op, vma, range, tile_mask);
> list_add_tail(&op->link, &vops->list);
> - xe_vma_ops_incr_pt_update_ops(vops, tile_mask);
> + xe_vma_ops_incr_pt_update_ops(vops, tile_mask, 1);
>
> return 0;
> }
> @@ -1062,7 +1062,7 @@ xe_vm_ops_add_range_unbind(struct xe_vma_ops *vops,
>
> xe_vm_populate_range_unbind(op, range);
> list_add_tail(&op->link, &vops->list);
> - xe_vma_ops_incr_pt_update_ops(vops, range->tile_present);
> + xe_vma_ops_incr_pt_update_ops(vops, range->tile_present, 1);
>
> return 0;
> }
> @@ -2475,7 +2475,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
> if ((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&
> !op->map.is_cpu_addr_mirror)
> xe_vma_ops_incr_pt_update_ops(vops,
> - op->tile_mask);
> + op->tile_mask, 1);
> break;
> }
> case DRM_GPUVA_OP_REMAP:
> @@ -2536,7 +2536,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
> (ULL)op->remap.start,
> (ULL)op->remap.range);
> } else {
> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
> }
> }
>
> @@ -2565,11 +2565,11 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
> (ULL)op->remap.start,
> (ULL)op->remap.range);
> } else {
> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
> }
> }
> if (!skip)
> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
Maybe update the code here (REMAP case) to call
xe_vma_ops_incr_pt_update_ops once. I feel like that would be a bit
cleaner and use the new interface correctly.
Matt
> break;
> }
> case DRM_GPUVA_OP_UNMAP:
> @@ -2581,7 +2581,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
> return -EBUSY;
>
> if (!xe_vma_is_cpu_addr_mirror(vma))
> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
> break;
> case DRM_GPUVA_OP_PREFETCH:
> vma = gpuva_to_vma(op->base.prefetch.va);
> @@ -2593,7 +2593,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
> }
>
> if (!xe_vma_is_cpu_addr_mirror(vma))
> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
> break;
> default:
> drm_warn(&vm->xe->drm, "NOT POSSIBLE");
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 06/29] drm/xe/vm: Update xe_vma_ops_incr_pt_update_ops to take an increment value
2025-03-28 2:56 ` Matthew Brost
@ 2025-03-28 7:52 ` Ghimiray, Himal Prasad
0 siblings, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-03-28 7:52 UTC (permalink / raw)
To: Matthew Brost; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On 28-03-2025 08:26, Matthew Brost wrote:
> On Fri, Mar 14, 2025 at 01:32:03PM +0530, Himal Prasad Ghimiray wrote:
>> Prefetch for SVM ranges can have more than one operation to increment,
>> hence modify the function to accept an increment value as input.
>>
>> Suggested-by: Matthew Brost <matthew.brost@intel.com>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> ---
>> drivers/gpu/drm/xe/xe_vm.c | 22 +++++++++++-----------
>> 1 file changed, 11 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
>> index 60303998bd61..53a80c0af8de 100644
>> --- a/drivers/gpu/drm/xe/xe_vm.c
>> +++ b/drivers/gpu/drm/xe/xe_vm.c
>> @@ -806,13 +806,13 @@ static void xe_vma_ops_fini(struct xe_vma_ops *vops)
>> kfree(vops->pt_update_ops[i].ops);
>> }
>>
>> -static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask)
>> +static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask, u8 inc_val)
>> {
>> int i;
>>
>> for (i = 0; i < XE_MAX_TILES_PER_DEVICE; ++i)
>> if (BIT(i) & tile_mask)
>> - ++vops->pt_update_ops[i].num_ops;
>> + vops->pt_update_ops[i].num_ops += inc_val;
>> }
>>
>> static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
>> @@ -842,7 +842,7 @@ static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma,
>>
>> xe_vm_populate_rebind(op, vma, tile_mask);
>> list_add_tail(&op->link, &vops->list);
>> - xe_vma_ops_incr_pt_update_ops(vops, tile_mask);
>> + xe_vma_ops_incr_pt_update_ops(vops, tile_mask, 1);
>>
>> return 0;
>> }
>> @@ -977,7 +977,7 @@ xe_vm_ops_add_range_rebind(struct xe_vma_ops *vops,
>>
>> xe_vm_populate_range_rebind(op, vma, range, tile_mask);
>> list_add_tail(&op->link, &vops->list);
>> - xe_vma_ops_incr_pt_update_ops(vops, tile_mask);
>> + xe_vma_ops_incr_pt_update_ops(vops, tile_mask, 1);
>>
>> return 0;
>> }
>> @@ -1062,7 +1062,7 @@ xe_vm_ops_add_range_unbind(struct xe_vma_ops *vops,
>>
>> xe_vm_populate_range_unbind(op, range);
>> list_add_tail(&op->link, &vops->list);
>> - xe_vma_ops_incr_pt_update_ops(vops, range->tile_present);
>> + xe_vma_ops_incr_pt_update_ops(vops, range->tile_present, 1);
>>
>> return 0;
>> }
>> @@ -2475,7 +2475,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
>> if ((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&
>> !op->map.is_cpu_addr_mirror)
>> xe_vma_ops_incr_pt_update_ops(vops,
>> - op->tile_mask);
>> + op->tile_mask, 1);
>> break;
>> }
>> case DRM_GPUVA_OP_REMAP:
>> @@ -2536,7 +2536,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
>> (ULL)op->remap.start,
>> (ULL)op->remap.range);
>> } else {
>> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
>> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
>> }
>> }
>>
>> @@ -2565,11 +2565,11 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
>> (ULL)op->remap.start,
>> (ULL)op->remap.range);
>> } else {
>> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
>> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
>> }
>> }
>> if (!skip)
>> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
>> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
>
> Maybe update the code here (REMAP case) to call
> xe_vma_ops_incr_pt_update_ops once. I feel like that would be a bit
> cleaner and use the new interface correctly.
>
> Matt
Makes sense, will update in next version. Thanks
>
>> break;
>> }
>> case DRM_GPUVA_OP_UNMAP:
>> @@ -2581,7 +2581,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
>> return -EBUSY;
>>
>> if (!xe_vma_is_cpu_addr_mirror(vma))
>> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
>> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
>> break;
>> case DRM_GPUVA_OP_PREFETCH:
>> vma = gpuva_to_vma(op->base.prefetch.va);
>> @@ -2593,7 +2593,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
>> }
>>
>> if (!xe_vma_is_cpu_addr_mirror(vma))
>> - xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
>> + xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
>> break;
>> default:
>> drm_warn(&vm->xe->drm, "NOT POSSIBLE");
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 07/29] drm/xe/vm: Add an identifier in xe_vma_ops for svm prefetch
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (5 preceding siblings ...)
2025-03-14 8:02 ` [RFC 06/29] drm/xe/vm: Update xe_vma_ops_incr_pt_update_ops to take an increment value Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-27 22:49 ` Matthew Brost
2025-03-14 8:02 ` [RFC 08/29] drm/xe: Rename lookup_vma function to xe_find_vma_by_addr Himal Prasad Ghimiray
` (22 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Add a flag in xe_vma_ops to determine whether it has svm prefetch ops or
not.
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 1 +
drivers/gpu/drm/xe/xe_vm_types.h | 3 +++
2 files changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 53a80c0af8de..b83154d338c7 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3215,6 +3215,7 @@ static void xe_vma_ops_init(struct xe_vma_ops *vops, struct xe_vm *vm,
vops->q = q;
vops->syncs = syncs;
vops->num_syncs = num_syncs;
+ vops->flags = false;
}
static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo,
diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
index 93224a87ab03..0b02a37bd2f3 100644
--- a/drivers/gpu/drm/xe/xe_vm_types.h
+++ b/drivers/gpu/drm/xe/xe_vm_types.h
@@ -443,6 +443,9 @@ struct xe_vma_ops {
u32 num_syncs;
/** @pt_update_ops: page table update operations */
struct xe_vm_pgtable_update_ops pt_update_ops[XE_MAX_TILES_PER_DEVICE];
+ /** @flag: signify the properties within xe_vma_ops*/
+#define XE_VMA_OPS_HAS_SVM_PREFETCH BIT(0)
+ u32 flags;
#ifdef TEST_VM_OPS_ERROR
/** @inject_error: inject error to test error handling */
bool inject_error;
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 07/29] drm/xe/vm: Add an identifier in xe_vma_ops for svm prefetch
2025-03-14 8:02 ` [RFC 07/29] drm/xe/vm: Add an identifier in xe_vma_ops for svm prefetch Himal Prasad Ghimiray
@ 2025-03-27 22:49 ` Matthew Brost
2025-03-28 7:53 ` Ghimiray, Himal Prasad
0 siblings, 1 reply; 52+ messages in thread
From: Matthew Brost @ 2025-03-27 22:49 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:04PM +0530, Himal Prasad Ghimiray wrote:
> Add a flag in xe_vma_ops to determine whether it has svm prefetch ops or
> not.
>
> Suggested-by: Matthew Brost <matthew.brost@intel.com>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm.c | 1 +
> drivers/gpu/drm/xe/xe_vm_types.h | 3 +++
> 2 files changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 53a80c0af8de..b83154d338c7 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -3215,6 +3215,7 @@ static void xe_vma_ops_init(struct xe_vma_ops *vops, struct xe_vm *vm,
> vops->q = q;
> vops->syncs = syncs;
> vops->num_syncs = num_syncs;
> + vops->flags = false;
s/false/0 - I this static checkers will complain about this.
Matt
> }
>
> static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo,
> diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
> index 93224a87ab03..0b02a37bd2f3 100644
> --- a/drivers/gpu/drm/xe/xe_vm_types.h
> +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> @@ -443,6 +443,9 @@ struct xe_vma_ops {
> u32 num_syncs;
> /** @pt_update_ops: page table update operations */
> struct xe_vm_pgtable_update_ops pt_update_ops[XE_MAX_TILES_PER_DEVICE];
> + /** @flag: signify the properties within xe_vma_ops*/
> +#define XE_VMA_OPS_HAS_SVM_PREFETCH BIT(0)
> + u32 flags;
> #ifdef TEST_VM_OPS_ERROR
> /** @inject_error: inject error to test error handling */
> bool inject_error;
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 07/29] drm/xe/vm: Add an identifier in xe_vma_ops for svm prefetch
2025-03-27 22:49 ` Matthew Brost
@ 2025-03-28 7:53 ` Ghimiray, Himal Prasad
0 siblings, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-03-28 7:53 UTC (permalink / raw)
To: Matthew Brost; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On 28-03-2025 04:19, Matthew Brost wrote:
> On Fri, Mar 14, 2025 at 01:32:04PM +0530, Himal Prasad Ghimiray wrote:
>> Add a flag in xe_vma_ops to determine whether it has svm prefetch ops or
>> not.
>>
>> Suggested-by: Matthew Brost <matthew.brost@intel.com>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> ---
>> drivers/gpu/drm/xe/xe_vm.c | 1 +
>> drivers/gpu/drm/xe/xe_vm_types.h | 3 +++
>> 2 files changed, 4 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
>> index 53a80c0af8de..b83154d338c7 100644
>> --- a/drivers/gpu/drm/xe/xe_vm.c
>> +++ b/drivers/gpu/drm/xe/xe_vm.c
>> @@ -3215,6 +3215,7 @@ static void xe_vma_ops_init(struct xe_vma_ops *vops, struct xe_vm *vm,
>> vops->q = q;
>> vops->syncs = syncs;
>> vops->num_syncs = num_syncs;
>> + vops->flags = false;
>
> s/false/0 - I this static checkers will complain about this.
>
> Matt
Thanks. Will address this
>
>> }
>>
>> static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo,
>> diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
>> index 93224a87ab03..0b02a37bd2f3 100644
>> --- a/drivers/gpu/drm/xe/xe_vm_types.h
>> +++ b/drivers/gpu/drm/xe/xe_vm_types.h
>> @@ -443,6 +443,9 @@ struct xe_vma_ops {
>> u32 num_syncs;
>> /** @pt_update_ops: page table update operations */
>> struct xe_vm_pgtable_update_ops pt_update_ops[XE_MAX_TILES_PER_DEVICE];
>> + /** @flag: signify the properties within xe_vma_ops*/
>> +#define XE_VMA_OPS_HAS_SVM_PREFETCH BIT(0)
>> + u32 flags;
>> #ifdef TEST_VM_OPS_ERROR
>> /** @inject_error: inject error to test error handling */
>> bool inject_error;
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 08/29] drm/xe: Rename lookup_vma function to xe_find_vma_by_addr
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (6 preceding siblings ...)
2025-03-14 8:02 ` [RFC 07/29] drm/xe/vm: Add an identifier in xe_vma_ops for svm prefetch Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-04-03 21:02 ` Matthew Brost
2025-03-14 8:02 ` [RFC 09/29] drm/xe/svm: Allow unaligned addresses and ranges for prefetch Himal Prasad Ghimiray
` (21 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
This update renames the lookup_vma function to xe_vm_find_vma_by_addr and
makes it accessible externally. The function, which looks up a VMA by
its address within a specified VM, will be utilized in upcoming patches.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_gt_pagefault.c | 24 +----------------------
drivers/gpu/drm/xe/xe_vm.c | 29 ++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_vm.h | 2 ++
3 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
index c5ad9a0a89c2..3aaf4090fcfe 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -72,28 +72,6 @@ static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
!(BIT(tile->id) & vma->tile_invalidated);
}
-static bool vma_matches(struct xe_vma *vma, u64 page_addr)
-{
- if (page_addr > xe_vma_end(vma) - 1 ||
- page_addr + SZ_4K - 1 < xe_vma_start(vma))
- return false;
-
- return true;
-}
-
-static struct xe_vma *lookup_vma(struct xe_vm *vm, u64 page_addr)
-{
- struct xe_vma *vma = NULL;
-
- if (vm->usm.last_fault_vma) { /* Fast lookup */
- if (vma_matches(vm->usm.last_fault_vma, page_addr))
- vma = vm->usm.last_fault_vma;
- }
- if (!vma)
- vma = xe_vm_find_overlapping_vma(vm, page_addr, SZ_4K);
-
- return vma;
-}
static int xe_pf_begin(struct drm_exec *exec, struct xe_vma *vma,
bool atomic, unsigned int id)
@@ -231,7 +209,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
goto unlock_vm;
}
- vma = lookup_vma(vm, pf->page_addr);
+ vma = xe_vm_find_vma_by_addr(vm, pf->page_addr);
if (!vma) {
err = -EINVAL;
goto unlock_vm;
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index b83154d338c7..07cad2804b14 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2135,6 +2135,35 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
return err;
}
+static bool vma_matches(struct xe_vma *vma, u64 page_addr)
+{
+ if (page_addr > xe_vma_end(vma) - 1 ||
+ page_addr + SZ_4K - 1 < xe_vma_start(vma))
+ return false;
+
+ return true;
+}
+
+/**
+ * xe_vm_find_vma_by_addr() - Find a VMA by its address
+ *
+ * @vm: the xe_vm the vma belongs to
+ * @page_address: address to look up
+ */
+struct xe_vma *xe_vm_find_vma_by_addr(struct xe_vm *vm, u64 page_addr)
+{
+ struct xe_vma *vma = NULL;
+
+ if (vm->usm.last_fault_vma) { /* Fast lookup */
+ if (vma_matches(vm->usm.last_fault_vma, page_addr))
+ vma = vm->usm.last_fault_vma;
+ }
+ if (!vma)
+ vma = xe_vm_find_overlapping_vma(vm, page_addr, SZ_4K);
+
+ return vma;
+}
+
static const u32 region_to_mem_type[] = {
XE_PL_TT,
XE_PL_VRAM0,
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 0ef811fc2bde..99e164852f63 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -169,6 +169,8 @@ static inline bool xe_vma_is_userptr(struct xe_vma *vma)
!xe_vma_is_cpu_addr_mirror(vma);
}
+struct xe_vma *xe_vm_find_vma_by_addr(struct xe_vm *vm, u64 page_addr);
+
/**
* to_userptr_vma() - Return a pointer to an embedding userptr vma
* @vma: Pointer to the embedded struct xe_vma
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 08/29] drm/xe: Rename lookup_vma function to xe_find_vma_by_addr
2025-03-14 8:02 ` [RFC 08/29] drm/xe: Rename lookup_vma function to xe_find_vma_by_addr Himal Prasad Ghimiray
@ 2025-04-03 21:02 ` Matthew Brost
2025-04-07 6:16 ` Ghimiray, Himal Prasad
0 siblings, 1 reply; 52+ messages in thread
From: Matthew Brost @ 2025-04-03 21:02 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:05PM +0530, Himal Prasad Ghimiray wrote:
> This update renames the lookup_vma function to xe_vm_find_vma_by_addr and
> makes it accessible externally. The function, which looks up a VMA by
> its address within a specified VM, will be utilized in upcoming patches.
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Side note just noticed there are multiple version of the list of this
patch but no versioning which then I accidentally replied to older
patches. Next rev, please include versioning.
Matt
> ---
> drivers/gpu/drm/xe/xe_gt_pagefault.c | 24 +----------------------
> drivers/gpu/drm/xe/xe_vm.c | 29 ++++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_vm.h | 2 ++
> 3 files changed, 32 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> index c5ad9a0a89c2..3aaf4090fcfe 100644
> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
> @@ -72,28 +72,6 @@ static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
> !(BIT(tile->id) & vma->tile_invalidated);
> }
>
> -static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> -{
> - if (page_addr > xe_vma_end(vma) - 1 ||
> - page_addr + SZ_4K - 1 < xe_vma_start(vma))
> - return false;
> -
> - return true;
> -}
> -
> -static struct xe_vma *lookup_vma(struct xe_vm *vm, u64 page_addr)
> -{
> - struct xe_vma *vma = NULL;
> -
> - if (vm->usm.last_fault_vma) { /* Fast lookup */
> - if (vma_matches(vm->usm.last_fault_vma, page_addr))
> - vma = vm->usm.last_fault_vma;
> - }
> - if (!vma)
> - vma = xe_vm_find_overlapping_vma(vm, page_addr, SZ_4K);
> -
> - return vma;
> -}
>
> static int xe_pf_begin(struct drm_exec *exec, struct xe_vma *vma,
> bool atomic, unsigned int id)
> @@ -231,7 +209,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
> goto unlock_vm;
> }
>
> - vma = lookup_vma(vm, pf->page_addr);
> + vma = xe_vm_find_vma_by_addr(vm, pf->page_addr);
> if (!vma) {
> err = -EINVAL;
> goto unlock_vm;
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index b83154d338c7..07cad2804b14 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -2135,6 +2135,35 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
> return err;
> }
>
> +static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> +{
> + if (page_addr > xe_vma_end(vma) - 1 ||
> + page_addr + SZ_4K - 1 < xe_vma_start(vma))
> + return false;
> +
> + return true;
> +}
> +
> +/**
> + * xe_vm_find_vma_by_addr() - Find a VMA by its address
> + *
> + * @vm: the xe_vm the vma belongs to
> + * @page_address: address to look up
> + */
> +struct xe_vma *xe_vm_find_vma_by_addr(struct xe_vm *vm, u64 page_addr)
> +{
> + struct xe_vma *vma = NULL;
> +
> + if (vm->usm.last_fault_vma) { /* Fast lookup */
> + if (vma_matches(vm->usm.last_fault_vma, page_addr))
> + vma = vm->usm.last_fault_vma;
> + }
> + if (!vma)
> + vma = xe_vm_find_overlapping_vma(vm, page_addr, SZ_4K);
> +
> + return vma;
> +}
> +
> static const u32 region_to_mem_type[] = {
> XE_PL_TT,
> XE_PL_VRAM0,
> diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
> index 0ef811fc2bde..99e164852f63 100644
> --- a/drivers/gpu/drm/xe/xe_vm.h
> +++ b/drivers/gpu/drm/xe/xe_vm.h
> @@ -169,6 +169,8 @@ static inline bool xe_vma_is_userptr(struct xe_vma *vma)
> !xe_vma_is_cpu_addr_mirror(vma);
> }
>
> +struct xe_vma *xe_vm_find_vma_by_addr(struct xe_vm *vm, u64 page_addr);
> +
> /**
> * to_userptr_vma() - Return a pointer to an embedding userptr vma
> * @vma: Pointer to the embedded struct xe_vma
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 08/29] drm/xe: Rename lookup_vma function to xe_find_vma_by_addr
2025-04-03 21:02 ` Matthew Brost
@ 2025-04-07 6:16 ` Ghimiray, Himal Prasad
0 siblings, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-04-07 6:16 UTC (permalink / raw)
To: Matthew Brost; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On 04-04-2025 02:32, Matthew Brost wrote:
> On Fri, Mar 14, 2025 at 01:32:05PM +0530, Himal Prasad Ghimiray wrote:
>> This update renames the lookup_vma function to xe_vm_find_vma_by_addr and
>> makes it accessible externally. The function, which looks up a VMA by
>> its address within a specified VM, will be utilized in upcoming patches.
>>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>
> Reviewed-by: Matthew Brost <matthew.brost@intel.com>
>
> Side note just noticed there are multiple version of the list of this
> patch but no versioning which then I accidentally replied to older
> patches. Next rev, please include versioning.
Will make sure of it. Thanks
>
> Matt
>
>> ---
>> drivers/gpu/drm/xe/xe_gt_pagefault.c | 24 +----------------------
>> drivers/gpu/drm/xe/xe_vm.c | 29 ++++++++++++++++++++++++++++
>> drivers/gpu/drm/xe/xe_vm.h | 2 ++
>> 3 files changed, 32 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>> index c5ad9a0a89c2..3aaf4090fcfe 100644
>> --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
>> +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
>> @@ -72,28 +72,6 @@ static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
>> !(BIT(tile->id) & vma->tile_invalidated);
>> }
>>
>> -static bool vma_matches(struct xe_vma *vma, u64 page_addr)
>> -{
>> - if (page_addr > xe_vma_end(vma) - 1 ||
>> - page_addr + SZ_4K - 1 < xe_vma_start(vma))
>> - return false;
>> -
>> - return true;
>> -}
>> -
>> -static struct xe_vma *lookup_vma(struct xe_vm *vm, u64 page_addr)
>> -{
>> - struct xe_vma *vma = NULL;
>> -
>> - if (vm->usm.last_fault_vma) { /* Fast lookup */
>> - if (vma_matches(vm->usm.last_fault_vma, page_addr))
>> - vma = vm->usm.last_fault_vma;
>> - }
>> - if (!vma)
>> - vma = xe_vm_find_overlapping_vma(vm, page_addr, SZ_4K);
>> -
>> - return vma;
>> -}
>>
>> static int xe_pf_begin(struct drm_exec *exec, struct xe_vma *vma,
>> bool atomic, unsigned int id)
>> @@ -231,7 +209,7 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
>> goto unlock_vm;
>> }
>>
>> - vma = lookup_vma(vm, pf->page_addr);
>> + vma = xe_vm_find_vma_by_addr(vm, pf->page_addr);
>> if (!vma) {
>> err = -EINVAL;
>> goto unlock_vm;
>> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
>> index b83154d338c7..07cad2804b14 100644
>> --- a/drivers/gpu/drm/xe/xe_vm.c
>> +++ b/drivers/gpu/drm/xe/xe_vm.c
>> @@ -2135,6 +2135,35 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
>> return err;
>> }
>>
>> +static bool vma_matches(struct xe_vma *vma, u64 page_addr)
>> +{
>> + if (page_addr > xe_vma_end(vma) - 1 ||
>> + page_addr + SZ_4K - 1 < xe_vma_start(vma))
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +/**
>> + * xe_vm_find_vma_by_addr() - Find a VMA by its address
>> + *
>> + * @vm: the xe_vm the vma belongs to
>> + * @page_address: address to look up
>> + */
>> +struct xe_vma *xe_vm_find_vma_by_addr(struct xe_vm *vm, u64 page_addr)
>> +{
>> + struct xe_vma *vma = NULL;
>> +
>> + if (vm->usm.last_fault_vma) { /* Fast lookup */
>> + if (vma_matches(vm->usm.last_fault_vma, page_addr))
>> + vma = vm->usm.last_fault_vma;
>> + }
>> + if (!vma)
>> + vma = xe_vm_find_overlapping_vma(vm, page_addr, SZ_4K);
>> +
>> + return vma;
>> +}
>> +
>> static const u32 region_to_mem_type[] = {
>> XE_PL_TT,
>> XE_PL_VRAM0,
>> diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
>> index 0ef811fc2bde..99e164852f63 100644
>> --- a/drivers/gpu/drm/xe/xe_vm.h
>> +++ b/drivers/gpu/drm/xe/xe_vm.h
>> @@ -169,6 +169,8 @@ static inline bool xe_vma_is_userptr(struct xe_vma *vma)
>> !xe_vma_is_cpu_addr_mirror(vma);
>> }
>>
>> +struct xe_vma *xe_vm_find_vma_by_addr(struct xe_vm *vm, u64 page_addr);
>> +
>> /**
>> * to_userptr_vma() - Return a pointer to an embedding userptr vma
>> * @vma: Pointer to the embedded struct xe_vma
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 09/29] drm/xe/svm: Allow unaligned addresses and ranges for prefetch
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (7 preceding siblings ...)
2025-03-14 8:02 ` [RFC 08/29] drm/xe: Rename lookup_vma function to xe_find_vma_by_addr Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-04-03 20:52 ` Matthew Brost
2025-03-14 8:02 ` [RFC 10/29] drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm Himal Prasad Ghimiray
` (20 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
The SVM prefetch operation can handle unaligned addresses and range sizes.
This commit updates the ioctl parameter checks to accommodate unaligned
addresses and range sizes for SVM prefetch operations.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 07cad2804b14..c6343a629c02 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3086,6 +3086,16 @@ ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_execute, ERRNO);
#define XE_64K_PAGE_MASK 0xffffull
#define ALL_DRM_XE_SYNCS_FLAGS (DRM_XE_SYNCS_FLAG_WAIT_FOR_OP)
+static bool addr_not_in_cpu_addr_vma(struct xe_vm *vm, u64 addr)
+{
+ struct xe_vma *vma;
+
+ down_write(&vm->lock);
+ vma = xe_vm_find_vma_by_addr(vm, addr);
+ up_write(&vm->lock);
+ return !xe_vma_is_cpu_addr_mirror(vma);
+}
+
static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
struct drm_xe_vm_bind *args,
struct drm_xe_vm_bind_op **bind_ops)
@@ -3194,8 +3204,12 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
}
if (XE_IOCTL_DBG(xe, obj_offset & ~PAGE_MASK) ||
- XE_IOCTL_DBG(xe, addr & ~PAGE_MASK) ||
- XE_IOCTL_DBG(xe, range & ~PAGE_MASK) ||
+ XE_IOCTL_DBG(xe, (addr & ~PAGE_MASK) &&
+ (addr_not_in_cpu_addr_vma(vm, addr) ||
+ op != DRM_XE_VM_BIND_OP_PREFETCH)) ||
+ XE_IOCTL_DBG(xe, (range & ~PAGE_MASK) &&
+ (addr_not_in_cpu_addr_vma(vm, addr) ||
+ op != DRM_XE_VM_BIND_OP_PREFETCH)) ||
XE_IOCTL_DBG(xe, !range &&
op != DRM_XE_VM_BIND_OP_UNMAP_ALL)) {
err = -EINVAL;
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 09/29] drm/xe/svm: Allow unaligned addresses and ranges for prefetch
2025-03-14 8:02 ` [RFC 09/29] drm/xe/svm: Allow unaligned addresses and ranges for prefetch Himal Prasad Ghimiray
@ 2025-04-03 20:52 ` Matthew Brost
2025-04-07 6:15 ` Ghimiray, Himal Prasad
0 siblings, 1 reply; 52+ messages in thread
From: Matthew Brost @ 2025-04-03 20:52 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:06PM +0530, Himal Prasad Ghimiray wrote:
> The SVM prefetch operation can handle unaligned addresses and range sizes.
> This commit updates the ioctl parameter checks to accommodate unaligned
> addresses and range sizes for SVM prefetch operations.
>
Do we really want to allow unaligned to page size prefetches? That seems
rather odd use case. Was this a specific request from the UMD team?
Matt
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_vm.c | 18 ++++++++++++++++--
> 1 file changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 07cad2804b14..c6343a629c02 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -3086,6 +3086,16 @@ ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_execute, ERRNO);
> #define XE_64K_PAGE_MASK 0xffffull
> #define ALL_DRM_XE_SYNCS_FLAGS (DRM_XE_SYNCS_FLAG_WAIT_FOR_OP)
>
> +static bool addr_not_in_cpu_addr_vma(struct xe_vm *vm, u64 addr)
> +{
> + struct xe_vma *vma;
> +
> + down_write(&vm->lock);
> + vma = xe_vm_find_vma_by_addr(vm, addr);
> + up_write(&vm->lock);
> + return !xe_vma_is_cpu_addr_mirror(vma);
> +}
> +
> static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
> struct drm_xe_vm_bind *args,
> struct drm_xe_vm_bind_op **bind_ops)
> @@ -3194,8 +3204,12 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
> }
>
> if (XE_IOCTL_DBG(xe, obj_offset & ~PAGE_MASK) ||
> - XE_IOCTL_DBG(xe, addr & ~PAGE_MASK) ||
> - XE_IOCTL_DBG(xe, range & ~PAGE_MASK) ||
> + XE_IOCTL_DBG(xe, (addr & ~PAGE_MASK) &&
> + (addr_not_in_cpu_addr_vma(vm, addr) ||
> + op != DRM_XE_VM_BIND_OP_PREFETCH)) ||
> + XE_IOCTL_DBG(xe, (range & ~PAGE_MASK) &&
> + (addr_not_in_cpu_addr_vma(vm, addr) ||
> + op != DRM_XE_VM_BIND_OP_PREFETCH)) ||
> XE_IOCTL_DBG(xe, !range &&
> op != DRM_XE_VM_BIND_OP_UNMAP_ALL)) {
> err = -EINVAL;
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 09/29] drm/xe/svm: Allow unaligned addresses and ranges for prefetch
2025-04-03 20:52 ` Matthew Brost
@ 2025-04-07 6:15 ` Ghimiray, Himal Prasad
0 siblings, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-04-07 6:15 UTC (permalink / raw)
To: Matthew Brost; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On 04-04-2025 02:22, Matthew Brost wrote:
> On Fri, Mar 14, 2025 at 01:32:06PM +0530, Himal Prasad Ghimiray wrote:
>> The SVM prefetch operation can handle unaligned addresses and range sizes.
>> This commit updates the ioctl parameter checks to accommodate unaligned
>> addresses and range sizes for SVM prefetch operations.
>>
>
> Do we really want to allow unaligned to page size prefetches? That seems
> rather odd use case. Was this a specific request from the UMD team?
Yes, this came as a requirement from UMD team.
>
> Matt
>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> ---
>> drivers/gpu/drm/xe/xe_vm.c | 18 ++++++++++++++++--
>> 1 file changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
>> index 07cad2804b14..c6343a629c02 100644
>> --- a/drivers/gpu/drm/xe/xe_vm.c
>> +++ b/drivers/gpu/drm/xe/xe_vm.c
>> @@ -3086,6 +3086,16 @@ ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_execute, ERRNO);
>> #define XE_64K_PAGE_MASK 0xffffull
>> #define ALL_DRM_XE_SYNCS_FLAGS (DRM_XE_SYNCS_FLAG_WAIT_FOR_OP)
>>
>> +static bool addr_not_in_cpu_addr_vma(struct xe_vm *vm, u64 addr)
>> +{
>> + struct xe_vma *vma;
>> +
>> + down_write(&vm->lock);
>> + vma = xe_vm_find_vma_by_addr(vm, addr);
>> + up_write(&vm->lock);
>> + return !xe_vma_is_cpu_addr_mirror(vma);
>> +}
>> +
>> static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
>> struct drm_xe_vm_bind *args,
>> struct drm_xe_vm_bind_op **bind_ops)
>> @@ -3194,8 +3204,12 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
>> }
>>
>> if (XE_IOCTL_DBG(xe, obj_offset & ~PAGE_MASK) ||
>> - XE_IOCTL_DBG(xe, addr & ~PAGE_MASK) ||
>> - XE_IOCTL_DBG(xe, range & ~PAGE_MASK) ||
>> + XE_IOCTL_DBG(xe, (addr & ~PAGE_MASK) &&
>> + (addr_not_in_cpu_addr_vma(vm, addr) ||
>> + op != DRM_XE_VM_BIND_OP_PREFETCH)) ||
>> + XE_IOCTL_DBG(xe, (range & ~PAGE_MASK) &&
>> + (addr_not_in_cpu_addr_vma(vm, addr) ||
>> + op != DRM_XE_VM_BIND_OP_PREFETCH)) ||
>> XE_IOCTL_DBG(xe, !range &&
>> op != DRM_XE_VM_BIND_OP_UNMAP_ALL)) {
>> err = -EINVAL;
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 10/29] drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (8 preceding siblings ...)
2025-03-14 8:02 ` [RFC 09/29] drm/xe/svm: Allow unaligned addresses and ranges for prefetch Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-04-03 20:54 ` Matthew Brost
2025-03-14 8:02 ` [RFC 11/29] drm/xe/svm: Implement prefetch support for SVM ranges Himal Prasad Ghimiray
` (19 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Define xe_svm_range_find_or_insert function wrapping
drm_gpusvm_range_find_or_insert for reusing in prefetch.
Define xe_svm_range_get_pages function wrapping
drm_gpusvm_range_get_pages for reusing in prefetch.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_svm.c | 73 +++++++++++++++++++++++++++++++------
drivers/gpu/drm/xe/xe_svm.h | 20 ++++++++++
2 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index 07511011aba6..5a4cb14d608e 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -714,7 +714,6 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
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;
ktime_t end = 0;
@@ -729,13 +728,11 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
if (err)
return err;
- r = drm_gpusvm_range_find_or_insert(&vm->svm.gpusvm, fault_addr,
- xe_vma_start(vma), xe_vma_end(vma),
- &ctx);
- if (IS_ERR(r))
- return PTR_ERR(r);
+ range = xe_svm_range_find_or_insert(vm, fault_addr, vma);
+
+ if (IS_ERR(range))
+ return PTR_ERR(range);
- range = to_xe_range(r);
if (xe_svm_range_is_valid(range, tile))
return 0;
@@ -757,13 +754,9 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
}
range_debug(range, "GET PAGES");
- err = drm_gpusvm_range_get_pages(&vm->svm.gpusvm, r, &ctx);
+ err = xe_svm_range_get_pages(vm, range, &ctx);
/* Corner where CPU mappings have changed */
if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) {
- if (err == -EOPNOTSUPP) {
- range_debug(range, "PAGE FAULT - EVICT PAGES");
- drm_gpusvm_range_evict(&vm->svm.gpusvm, &range->base);
- }
drm_dbg(&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));
@@ -842,6 +835,62 @@ int xe_svm_bo_evict(struct xe_bo *bo)
return drm_gpusvm_evict_to_ram(&bo->devmem_allocation);
}
+/**
+ * xe_svm_range_find_or_insert- Find or insert GPU SVM range
+ * @vm: xe_vm pointer
+ * @addr: address for which range needs to be found/inserted
+ * @vma: Pointer to struct xe_vma which mirrors CPU
+ *
+ * This function finds or inserts a newly allocated a SVM range based on the
+ * address.
+ *
+ * Return: Pointer to the SVM range on success, ERR_PTR() on failure.
+ */
+struct xe_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
+ struct xe_vma *vma)
+{
+ struct drm_gpusvm_range *r;
+
+ 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,
+ };
+
+ r = drm_gpusvm_range_find_or_insert(&vm->svm.gpusvm, max(addr, xe_vma_start(vma)),
+ xe_vma_start(vma), xe_vma_end(vma), &ctx);
+ if (IS_ERR(r))
+ return ERR_PTR(PTR_ERR(r));
+
+ return to_xe_range(r);
+}
+
+/**
+ * xe_svm_range_get_pages() - Get pages for a SVM range
+ * @vm: Pointer to the struct xe_vm
+ * @range: Pointer to the xe SVM range structure
+ * @ctx: GPU SVM context
+ *
+ * This function gets pages for a SVM range and ensures they are mapped for
+ * DMA access. In case of failure with -EOPNOTSUPP, it evicts the range.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
+ struct drm_gpusvm_ctx *ctx)
+{
+ int err = 0;
+
+ err = drm_gpusvm_range_get_pages(&vm->svm.gpusvm, &range->base, ctx);
+ if (err == -EOPNOTSUPP) {
+ range_debug(range, "PAGE FAULT - EVICT PAGES");
+ drm_gpusvm_range_evict(&vm->svm.gpusvm, &range->base);
+ }
+
+ return err;
+}
+
#if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
static struct drm_pagemap_device_addr
xe_drm_pagemap_device_map(struct drm_pagemap *dpagemap,
diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
index c8add37614ec..6bb358bf62ad 100644
--- a/drivers/gpu/drm/xe/xe_svm.h
+++ b/drivers/gpu/drm/xe/xe_svm.h
@@ -76,6 +76,12 @@ void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);
int 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_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
+ struct xe_vma *vma);
+
+int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
+ struct drm_gpusvm_ctx *ctx);
#else
static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
{
@@ -137,6 +143,20 @@ int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
return 0;
}
+static inline
+struct xe_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
+ struct xe_vma *vma)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+static inline
+int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
+ struct drm_gpusvm_ctx *ctx)
+{
+ return -EINVAL;
+}
+
#endif
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 10/29] drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm
2025-03-14 8:02 ` [RFC 10/29] drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm Himal Prasad Ghimiray
@ 2025-04-03 20:54 ` Matthew Brost
2025-04-07 6:15 ` Ghimiray, Himal Prasad
0 siblings, 1 reply; 52+ messages in thread
From: Matthew Brost @ 2025-04-03 20:54 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:07PM +0530, Himal Prasad Ghimiray wrote:
> Define xe_svm_range_find_or_insert function wrapping
> drm_gpusvm_range_find_or_insert for reusing in prefetch.
>
> Define xe_svm_range_get_pages function wrapping
> drm_gpusvm_range_get_pages for reusing in prefetch.
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_svm.c | 73 +++++++++++++++++++++++++++++++------
> drivers/gpu/drm/xe/xe_svm.h | 20 ++++++++++
> 2 files changed, 81 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
> index 07511011aba6..5a4cb14d608e 100644
> --- a/drivers/gpu/drm/xe/xe_svm.c
> +++ b/drivers/gpu/drm/xe/xe_svm.c
> @@ -714,7 +714,6 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
> 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;
> ktime_t end = 0;
> @@ -729,13 +728,11 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
> if (err)
> return err;
>
> - r = drm_gpusvm_range_find_or_insert(&vm->svm.gpusvm, fault_addr,
> - xe_vma_start(vma), xe_vma_end(vma),
> - &ctx);
> - if (IS_ERR(r))
> - return PTR_ERR(r);
> + range = xe_svm_range_find_or_insert(vm, fault_addr, vma);
> +
> + if (IS_ERR(range))
> + return PTR_ERR(range);
>
> - range = to_xe_range(r);
> if (xe_svm_range_is_valid(range, tile))
> return 0;
>
> @@ -757,13 +754,9 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
> }
>
> range_debug(range, "GET PAGES");
> - err = drm_gpusvm_range_get_pages(&vm->svm.gpusvm, r, &ctx);
> + err = xe_svm_range_get_pages(vm, range, &ctx);
> /* Corner where CPU mappings have changed */
> if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) {
> - if (err == -EOPNOTSUPP) {
> - range_debug(range, "PAGE FAULT - EVICT PAGES");
> - drm_gpusvm_range_evict(&vm->svm.gpusvm, &range->base);
> - }
> drm_dbg(&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));
> @@ -842,6 +835,62 @@ int xe_svm_bo_evict(struct xe_bo *bo)
> return drm_gpusvm_evict_to_ram(&bo->devmem_allocation);
> }
>
> +/**
> + * xe_svm_range_find_or_insert- Find or insert GPU SVM range
> + * @vm: xe_vm pointer
> + * @addr: address for which range needs to be found/inserted
> + * @vma: Pointer to struct xe_vma which mirrors CPU
> + *
> + * This function finds or inserts a newly allocated a SVM range based on the
> + * address.
> + *
> + * Return: Pointer to the SVM range on success, ERR_PTR() on failure.
> + */
> +struct xe_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
> + struct xe_vma *vma)
I think you want a drm_gpusvm_ctx argument here. It is odd to duplicate
the context locally when the page fault handler has already set one up.
Matt
> +{
> + struct drm_gpusvm_range *r;
> +
> + 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,
> + };
> +
> + r = drm_gpusvm_range_find_or_insert(&vm->svm.gpusvm, max(addr, xe_vma_start(vma)),
> + xe_vma_start(vma), xe_vma_end(vma), &ctx);
> + if (IS_ERR(r))
> + return ERR_PTR(PTR_ERR(r));
> +
> + return to_xe_range(r);
> +}
> +
> +/**
> + * xe_svm_range_get_pages() - Get pages for a SVM range
> + * @vm: Pointer to the struct xe_vm
> + * @range: Pointer to the xe SVM range structure
> + * @ctx: GPU SVM context
> + *
> + * This function gets pages for a SVM range and ensures they are mapped for
> + * DMA access. In case of failure with -EOPNOTSUPP, it evicts the range.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
> + struct drm_gpusvm_ctx *ctx)
> +{
> + int err = 0;
> +
> + err = drm_gpusvm_range_get_pages(&vm->svm.gpusvm, &range->base, ctx);
> + if (err == -EOPNOTSUPP) {
> + range_debug(range, "PAGE FAULT - EVICT PAGES");
> + drm_gpusvm_range_evict(&vm->svm.gpusvm, &range->base);
> + }
> +
> + return err;
> +}
> +
> #if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
> static struct drm_pagemap_device_addr
> xe_drm_pagemap_device_map(struct drm_pagemap *dpagemap,
> diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
> index c8add37614ec..6bb358bf62ad 100644
> --- a/drivers/gpu/drm/xe/xe_svm.h
> +++ b/drivers/gpu/drm/xe/xe_svm.h
> @@ -76,6 +76,12 @@ void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);
> int 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_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
> + struct xe_vma *vma);
> +
> +int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
> + struct drm_gpusvm_ctx *ctx);
> #else
> static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
> {
> @@ -137,6 +143,20 @@ int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
> return 0;
> }
>
> +static inline
> +struct xe_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
> + struct xe_vma *vma)
> +{
> + return ERR_PTR(-EINVAL);
> +}
> +
> +static inline
> +int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
> + struct drm_gpusvm_ctx *ctx)
> +{
> + return -EINVAL;
> +}
> +
> #endif
>
> /**
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 10/29] drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm
2025-04-03 20:54 ` Matthew Brost
@ 2025-04-07 6:15 ` Ghimiray, Himal Prasad
0 siblings, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-04-07 6:15 UTC (permalink / raw)
To: Matthew Brost; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On 04-04-2025 02:24, Matthew Brost wrote:
> On Fri, Mar 14, 2025 at 01:32:07PM +0530, Himal Prasad Ghimiray wrote:
>> Define xe_svm_range_find_or_insert function wrapping
>> drm_gpusvm_range_find_or_insert for reusing in prefetch.
>>
>> Define xe_svm_range_get_pages function wrapping
>> drm_gpusvm_range_get_pages for reusing in prefetch.
>>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> ---
>> drivers/gpu/drm/xe/xe_svm.c | 73 +++++++++++++++++++++++++++++++------
>> drivers/gpu/drm/xe/xe_svm.h | 20 ++++++++++
>> 2 files changed, 81 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
>> index 07511011aba6..5a4cb14d608e 100644
>> --- a/drivers/gpu/drm/xe/xe_svm.c
>> +++ b/drivers/gpu/drm/xe/xe_svm.c
>> @@ -714,7 +714,6 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
>> 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;
>> ktime_t end = 0;
>> @@ -729,13 +728,11 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
>> if (err)
>> return err;
>>
>> - r = drm_gpusvm_range_find_or_insert(&vm->svm.gpusvm, fault_addr,
>> - xe_vma_start(vma), xe_vma_end(vma),
>> - &ctx);
>> - if (IS_ERR(r))
>> - return PTR_ERR(r);
>> + range = xe_svm_range_find_or_insert(vm, fault_addr, vma);
>> +
>> + if (IS_ERR(range))
>> + return PTR_ERR(range);
>>
>> - range = to_xe_range(r);
>> if (xe_svm_range_is_valid(range, tile))
>> return 0;
>>
>> @@ -757,13 +754,9 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
>> }
>>
>> range_debug(range, "GET PAGES");
>> - err = drm_gpusvm_range_get_pages(&vm->svm.gpusvm, r, &ctx);
>> + err = xe_svm_range_get_pages(vm, range, &ctx);
>> /* Corner where CPU mappings have changed */
>> if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) {
>> - if (err == -EOPNOTSUPP) {
>> - range_debug(range, "PAGE FAULT - EVICT PAGES");
>> - drm_gpusvm_range_evict(&vm->svm.gpusvm, &range->base);
>> - }
>> drm_dbg(&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));
>> @@ -842,6 +835,62 @@ int xe_svm_bo_evict(struct xe_bo *bo)
>> return drm_gpusvm_evict_to_ram(&bo->devmem_allocation);
>> }
>>
>> +/**
>> + * xe_svm_range_find_or_insert- Find or insert GPU SVM range
>> + * @vm: xe_vm pointer
>> + * @addr: address for which range needs to be found/inserted
>> + * @vma: Pointer to struct xe_vma which mirrors CPU
>> + *
>> + * This function finds or inserts a newly allocated a SVM range based on the
>> + * address.
>> + *
>> + * Return: Pointer to the SVM range on success, ERR_PTR() on failure.
>> + */
>> +struct xe_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
>> + struct xe_vma *vma)
>
> I think you want a drm_gpusvm_ctx argument here. It is odd to duplicate
> the context locally when the page fault handler has already set one up.
Makes sense. will fix in next version.
>
> Matt
>
>> +{
>> + struct drm_gpusvm_range *r;
>> +
>> + 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,
>> + };
>> +
>> + r = drm_gpusvm_range_find_or_insert(&vm->svm.gpusvm, max(addr, xe_vma_start(vma)),
>> + xe_vma_start(vma), xe_vma_end(vma), &ctx);
>> + if (IS_ERR(r))
>> + return ERR_PTR(PTR_ERR(r));
>> +
>> + return to_xe_range(r);
>> +}
>> +
>> +/**
>> + * xe_svm_range_get_pages() - Get pages for a SVM range
>> + * @vm: Pointer to the struct xe_vm
>> + * @range: Pointer to the xe SVM range structure
>> + * @ctx: GPU SVM context
>> + *
>> + * This function gets pages for a SVM range and ensures they are mapped for
>> + * DMA access. In case of failure with -EOPNOTSUPP, it evicts the range.
>> + *
>> + * Return: 0 on success, negative error code on failure.
>> + */
>> +int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
>> + struct drm_gpusvm_ctx *ctx)
>> +{
>> + int err = 0;
>> +
>> + err = drm_gpusvm_range_get_pages(&vm->svm.gpusvm, &range->base, ctx);
>> + if (err == -EOPNOTSUPP) {
>> + range_debug(range, "PAGE FAULT - EVICT PAGES");
>> + drm_gpusvm_range_evict(&vm->svm.gpusvm, &range->base);
>> + }
>> +
>> + return err;
>> +}
>> +
>> #if IS_ENABLED(CONFIG_DRM_XE_DEVMEM_MIRROR)
>> static struct drm_pagemap_device_addr
>> xe_drm_pagemap_device_map(struct drm_pagemap *dpagemap,
>> diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
>> index c8add37614ec..6bb358bf62ad 100644
>> --- a/drivers/gpu/drm/xe/xe_svm.h
>> +++ b/drivers/gpu/drm/xe/xe_svm.h
>> @@ -76,6 +76,12 @@ void xe_svm_range_debug(struct xe_svm_range *range, const char *operation);
>> int 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_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
>> + struct xe_vma *vma);
>> +
>> +int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
>> + struct drm_gpusvm_ctx *ctx);
>> #else
>> static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
>> {
>> @@ -137,6 +143,20 @@ int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
>> return 0;
>> }
>>
>> +static inline
>> +struct xe_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
>> + struct xe_vma *vma)
>> +{
>> + return ERR_PTR(-EINVAL);
>> +}
>> +
>> +static inline
>> +int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
>> + struct drm_gpusvm_ctx *ctx)
>> +{
>> + return -EINVAL;
>> +}
>> +
>> #endif
>>
>> /**
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 11/29] drm/xe/svm: Implement prefetch support for SVM ranges
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (9 preceding siblings ...)
2025-03-14 8:02 ` [RFC 10/29] drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 12/29] drm/xe/vm: Add debug prints for SVM range prefetch Himal Prasad Ghimiray
` (18 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
This commit adds prefetch support for SVM ranges, utilizing the
existing ioctl vm_bind functionality to achieve this.
Cc: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_pt.c | 62 +++++++++----
drivers/gpu/drm/xe/xe_vm.c | 177 +++++++++++++++++++++++++++++++++++--
2 files changed, 214 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index cf7a6ba2aec8..5574d3008a0d 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -1425,7 +1425,8 @@ static int xe_pt_svm_pre_commit(struct xe_migrate_pt_update *pt_update)
struct xe_vm *vm = pt_update->vops->vm;
struct xe_vma_ops *vops = pt_update->vops;
struct xe_vma_op *op;
- int err;
+ int ranges_count;
+ int err, i;
err = xe_pt_pre_commit(pt_update);
if (err)
@@ -1434,20 +1435,33 @@ static int xe_pt_svm_pre_commit(struct xe_migrate_pt_update *pt_update)
xe_svm_notifier_lock(vm);
list_for_each_entry(op, &vops->list, link) {
- struct xe_svm_range *range = op->map_range.range;
+ struct xe_svm_range *range = NULL;
if (op->subop == XE_VMA_SUBOP_UNMAP_RANGE)
continue;
- xe_svm_range_debug(range, "PRE-COMMIT");
+ if (op->base.op == DRM_GPUVA_OP_PREFETCH) {
+ xe_assert(vm->xe,
+ xe_vma_is_cpu_addr_mirror(gpuva_to_vma(op->base.prefetch.va)));
+ ranges_count = op->prefetch_range.ranges_count;
+ } else {
+ xe_assert(vm->xe, xe_vma_is_cpu_addr_mirror(op->map_range.vma));
+ xe_assert(vm->xe, op->subop == XE_VMA_SUBOP_MAP_RANGE);
+ ranges_count = 1;
+ }
- xe_assert(vm->xe, xe_vma_is_cpu_addr_mirror(op->map_range.vma));
- xe_assert(vm->xe, op->subop == XE_VMA_SUBOP_MAP_RANGE);
+ for (i = 0; i < ranges_count; i++) {
+ if (op->base.op == DRM_GPUVA_OP_PREFETCH)
+ range = xa_load(&op->prefetch_range.range, i);
+ else
+ range = op->map_range.range;
+ xe_svm_range_debug(range, "PRE-COMMIT");
- if (!xe_svm_range_pages_valid(range)) {
- xe_svm_range_debug(range, "PRE-COMMIT - RETRY");
- xe_svm_notifier_unlock(vm);
- return -EAGAIN;
+ if (!xe_svm_range_pages_valid(range)) {
+ xe_svm_range_debug(range, "PRE-COMMIT - RETRY");
+ xe_svm_notifier_unlock(vm);
+ return -EAGAIN;
+ }
}
}
@@ -2028,12 +2042,21 @@ static int op_prepare(struct xe_vm *vm,
case DRM_GPUVA_OP_PREFETCH:
{
struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va);
-
- if (xe_vma_is_cpu_addr_mirror(vma))
- break;
-
- err = bind_op_prepare(vm, tile, pt_update_ops, vma);
- pt_update_ops->wait_vm_kernel = true;
+ if (xe_vma_is_cpu_addr_mirror(vma)) {
+ struct xe_svm_range *range;
+ int i;
+
+ for (i = 0; i < op->prefetch_range.ranges_count; i++) {
+ range = xa_load(&op->prefetch_range.range, i);
+ err = bind_range_prepare(vm, tile, pt_update_ops,
+ vma, range);
+ if (err)
+ return err;
+ }
+ } else {
+ err = bind_op_prepare(vm, tile, pt_update_ops, vma);
+ pt_update_ops->wait_vm_kernel = true;
+ }
break;
}
case DRM_GPUVA_OP_DRIVER:
@@ -2235,9 +2258,16 @@ static void op_commit(struct xe_vm *vm,
{
struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va);
- if (!xe_vma_is_cpu_addr_mirror(vma))
+ if (xe_vma_is_cpu_addr_mirror(vma)) {
+ for (int i = 0 ; i < op->prefetch_range.ranges_count; i++) {
+ struct xe_svm_range *range = xa_load(&op->prefetch_range.range, i);
+
+ range_present_and_invalidated_tile(vm, range, tile->id);
+ }
+ } else {
bind_op_commit(vm, tile, pt_update_ops, vma, fence,
fence2);
+ }
break;
}
case DRM_GPUVA_OP_DRIVER:
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index c6343a629c02..360be74b2a28 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -798,10 +798,36 @@ static int xe_vma_ops_alloc(struct xe_vma_ops *vops, bool array_of_binds)
}
ALLOW_ERROR_INJECTION(xe_vma_ops_alloc, ERRNO);
+static void clean_svm_prefetch_op(struct xe_vma_op *op)
+{
+ struct xe_vma *vma;
+
+ vma = gpuva_to_vma(op->base.prefetch.va);
+
+ if (op->base.op == DRM_GPUVA_OP_PREFETCH && xe_vma_is_cpu_addr_mirror(vma)) {
+ xa_destroy(&op->prefetch_range.range);
+ op->prefetch_range.ranges_count = 0;
+ }
+}
+
+static void clean_svm_prefetch_in_vma_ops(struct xe_vma_ops *vops)
+{
+ struct xe_vma_op *op;
+
+ if (!(vops->flags & XE_VMA_OPS_HAS_SVM_PREFETCH))
+ return;
+
+ list_for_each_entry(op, &vops->list, link) {
+ clean_svm_prefetch_op(op);
+ }
+}
+
static void xe_vma_ops_fini(struct xe_vma_ops *vops)
{
int i;
+ clean_svm_prefetch_in_vma_ops(vops);
+
for (i = 0; i < XE_MAX_TILES_PER_DEVICE; ++i)
kfree(vops->pt_update_ops[i].ops);
}
@@ -2230,13 +2256,25 @@ static void print_op(struct xe_device *xe, struct drm_gpuva_op *op)
}
#endif
+static void clean_svm_prefetch_in_gpuva_ops(struct drm_gpuva_ops *ops)
+{
+ struct drm_gpuva_op *__op;
+
+ drm_gpuva_for_each_op(__op, ops) {
+ struct xe_vma_op *op = gpuva_op_to_vma_op(__op);
+
+ clean_svm_prefetch_op(op);
+ }
+}
+
/*
* Create operations list from IOCTL arguments, setup operations fields so parse
* and commit steps are decoupled from IOCTL arguments. This step can fail.
*/
static struct drm_gpuva_ops *
-vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo *bo,
- u64 bo_offset_or_userptr, u64 addr, u64 range,
+vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
+ struct xe_bo *bo, u64 bo_offset_or_userptr,
+ u64 addr, u64 range,
u32 operation, u32 flags,
u32 prefetch_region, u16 pat_index)
{
@@ -2244,6 +2282,7 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo *bo,
struct drm_gpuva_ops *ops;
struct drm_gpuva_op *__op;
struct drm_gpuvm_bo *vm_bo;
+ u64 range_end = addr + range;
int err;
lockdep_assert_held_write(&vm->lock);
@@ -2303,14 +2342,52 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo *bo,
op->map.dumpable = flags & DRM_XE_VM_BIND_FLAG_DUMPABLE;
op->map.pat_index = pat_index;
} else if (__op->op == DRM_GPUVA_OP_PREFETCH) {
- op->prefetch.region = prefetch_region;
- }
+ struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va);
+
+ if (!xe_vma_is_cpu_addr_mirror(vma)) {
+ op->prefetch.region = prefetch_region;
+ break;
+ }
+
+ op->prefetch_range.region = prefetch_region;
+ struct xe_svm_range *svm_range;
+ int i = 0;
+ xa_init(&op->prefetch_range.range);
+ op->prefetch_range.ranges_count = 0;
+alloc_next_range:
+ svm_range = xe_svm_range_find_or_insert(vm, addr, vma);
+
+ if (PTR_ERR(svm_range) == -ENOENT)
+ break;
+
+ if (IS_ERR(svm_range)) {
+ err = PTR_ERR(svm_range);
+ goto unwind_prefetch_ops;
+ }
+
+ xa_store(&op->prefetch_range.range, i, svm_range, GFP_KERNEL);
+ op->prefetch_range.ranges_count++;
+ vops->flags |= XE_VMA_OPS_HAS_SVM_PREFETCH;
+
+ if (range_end > xe_svm_range_end(svm_range) &&
+ xe_svm_range_end(svm_range) < xe_vma_end(vma)) {
+ i++;
+ addr = xe_svm_range_end(svm_range);
+ goto alloc_next_range;
+ }
+ }
print_op(vm->xe, __op);
}
return ops;
+
+unwind_prefetch_ops:
+ clean_svm_prefetch_in_gpuva_ops(ops);
+ drm_gpuva_ops_free(&vm->gpuvm, ops);
+ return ERR_PTR(err);
}
+
ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_create, ERRNO);
static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
@@ -2621,8 +2698,12 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
return err;
}
- if (!xe_vma_is_cpu_addr_mirror(vma))
+ if (xe_vma_is_cpu_addr_mirror(vma))
+ xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask,
+ op->prefetch_range.ranges_count);
+ else
xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask, 1);
+
break;
default:
drm_warn(&vm->xe->drm, "NOT POSSIBLE");
@@ -2748,6 +2829,59 @@ static int check_ufence(struct xe_vma *vma)
return 0;
}
+static int prefetch_ranges_lock_and_prep(struct xe_vm *vm,
+ struct xe_vma_op *op)
+{
+ int err = 0;
+
+ if (op->base.op == DRM_GPUVA_OP_PREFETCH) {
+ struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va);
+ 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 *svm_range;
+ struct xe_tile *tile;
+ u32 region;
+ int i;
+
+ if (!xe_vma_is_cpu_addr_mirror(vma))
+ return 0;
+
+ region = op->prefetch_range.region;
+
+ /* TODO: Threading the migration */
+ for (i = 0; i < op->prefetch_range.ranges_count; i++) {
+ svm_range = xa_load(&op->prefetch_range.range, i);
+ if (region && svm_range->base.flags.migrate_devmem &&
+ xe_svm_range_size(svm_range) >= SZ_64K) {
+ tile = &vm->xe->tiles[region_to_mem_type[region] - XE_PL_VRAM0];
+ err = xe_svm_alloc_vram(vm, tile, svm_range, &ctx);
+ if (err) {
+ drm_err(&vm->xe->drm, "VRAM allocation failed, can be retried from userspace, asid=%u, gpusvm=0x%016llx, errno=%pe\n",
+ vm->usm.asid, (u64)&vm->svm.gpusvm, ERR_PTR(err));
+ return -ENODATA;
+ }
+ }
+
+ err = xe_svm_range_get_pages(vm, svm_range, &ctx);
+ if (err) {
+ if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM)
+ err = -ENODATA;
+
+ drm_err(&vm->xe->drm, "Get pages failed, asid=%u, gpusvm=0x%016llx, errno=%pe\n",
+ vm->usm.asid, (u64)&vm->svm.gpusvm, ERR_PTR(err));
+ return err;
+ }
+ }
+ }
+ return err;
+}
+
static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
struct xe_vma_op *op)
{
@@ -2784,7 +2918,12 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
case DRM_GPUVA_OP_PREFETCH:
{
struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va);
- u32 region = op->prefetch.region;
+ u32 region;
+
+ if (xe_vma_is_cpu_addr_mirror(vma))
+ region = op->prefetch_range.region;
+ else
+ region = op->prefetch.region;
xe_assert(vm->xe, region <= ARRAY_SIZE(region_to_mem_type));
@@ -2803,6 +2942,23 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
return err;
}
+static int xe_vma_ops_execute_ready(struct xe_vm *vm, struct xe_vma_ops *vops)
+{
+ struct xe_vma_op *op;
+ int err;
+
+ if (!(vops->flags & XE_VMA_OPS_HAS_SVM_PREFETCH))
+ return 0;
+
+ list_for_each_entry(op, &vops->list, link) {
+ err = prefetch_ranges_lock_and_prep(vm, op);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int vm_bind_ioctl_ops_lock_and_prep(struct drm_exec *exec,
struct xe_vm *vm,
struct xe_vma_ops *vops)
@@ -2825,7 +2981,6 @@ static int vm_bind_ioctl_ops_lock_and_prep(struct drm_exec *exec,
vm->xe->vm_inject_error_position == FORCE_OP_ERROR_LOCK)
return -ENOSPC;
#endif
-
return 0;
}
@@ -3467,7 +3622,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
u32 prefetch_region = bind_ops[i].prefetch_mem_region_instance;
u16 pat_index = bind_ops[i].pat_index;
- ops[i] = vm_bind_ioctl_ops_create(vm, bos[i], obj_offset,
+ ops[i] = vm_bind_ioctl_ops_create(vm, &vops, bos[i], obj_offset,
addr, range, op, flags,
prefetch_region, pat_index);
if (IS_ERR(ops[i])) {
@@ -3500,6 +3655,10 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
if (err)
goto unwind_ops;
+ err = xe_vma_ops_execute_ready(vm, &vops);
+ if (err)
+ goto unwind_ops;
+
fence = vm_bind_ioctl_ops_execute(vm, &vops);
if (IS_ERR(fence))
err = PTR_ERR(fence);
@@ -3569,7 +3728,7 @@ struct dma_fence *xe_vm_bind_kernel_bo(struct xe_vm *vm, struct xe_bo *bo,
xe_vma_ops_init(&vops, vm, q, NULL, 0);
- ops = vm_bind_ioctl_ops_create(vm, bo, 0, addr, bo->size,
+ ops = vm_bind_ioctl_ops_create(vm, &vops, bo, 0, addr, bo->size,
DRM_XE_VM_BIND_OP_MAP, 0, 0,
vm->xe->pat.idx[cache_lvl]);
if (IS_ERR(ops)) {
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 12/29] drm/xe/vm: Add debug prints for SVM range prefetch
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (10 preceding siblings ...)
2025-03-14 8:02 ` [RFC 11/29] drm/xe/svm: Implement prefetch support for SVM ranges Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations Himal Prasad Ghimiray
` (17 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Introduce debug logs for the prefetch operation of SVM ranges.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 360be74b2a28..f63dd4eb1ae8 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2369,6 +2369,7 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
xa_store(&op->prefetch_range.range, i, svm_range, GFP_KERNEL);
op->prefetch_range.ranges_count++;
vops->flags |= XE_VMA_OPS_HAS_SVM_PREFETCH;
+ xe_svm_range_debug(svm_range, "PREFETCH - RANGE CREATED");
if (range_end > xe_svm_range_end(svm_range) &&
xe_svm_range_end(svm_range) < xe_vma_end(vma)) {
@@ -2866,6 +2867,7 @@ static int prefetch_ranges_lock_and_prep(struct xe_vm *vm,
vm->usm.asid, (u64)&vm->svm.gpusvm, ERR_PTR(err));
return -ENODATA;
}
+ xe_svm_range_debug(svm_range, "PREFETCH - RANGE MIGRATED TO VRAM");
}
err = xe_svm_range_get_pages(vm, svm_range, &ctx);
@@ -2877,6 +2879,7 @@ static int prefetch_ranges_lock_and_prep(struct xe_vm *vm,
vm->usm.asid, (u64)&vm->svm.gpusvm, ERR_PTR(err));
return err;
}
+ xe_svm_range_debug(svm_range, "PREFETCH - RANGE GET PAGES DONE");
}
}
return err;
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (11 preceding siblings ...)
2025-03-14 8:02 ` [RFC 12/29] drm/xe/vm: Add debug prints for SVM range prefetch Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:46 ` Ghimiray, Himal Prasad
2025-03-17 14:27 ` Danilo Krummrich
2025-03-14 8:02 ` [RFC 14/29] drm/xe/uapi: Add madvise interface Himal Prasad Ghimiray
` (16 subsequent siblings)
29 siblings, 2 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe
Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray,
Danilo Krummrich
Introduce MADVISE operations that do not unmap the GPU VMA. These
operations split VMAs if the start or end addresses fall within existing
VMAs. The operations can create up to 2 REMAPS and 2 MAPs.
If the input range is within the existing range, it creates REMAP:UNMAP,
REMAP:PREV, REMAP:NEXT, and MAP operations for the input range.
Example:
Input Range: 0x00007f0a54000000 to 0x00007f0a54400000
GPU VMA: 0x0000000000000000 to 0x0000800000000000
Operations Result:
- REMAP:UNMAP: addr=0x0000000000000000, range=0x0000800000000000
- REMAP:PREV: addr=0x0000000000000000, range=0x00007f0a54000000
- REMAP:NEXT: addr=0x00007f0a54400000, range=0x000000f5abc00000
- MAP: addr=0x00007f0a54000000, range=0x0000000000400000
If the input range starts at the beginning of one GPU VMA and ends at
the end of another VMA, covering multiple VMAs, the operations do nothing.
Example:
Input Range: 0x00007fc898800000 to 0x00007fc899000000
GPU VMAs:
- 0x0000000000000000 to 0x00007fc898800000
- 0x00007fc898800000 to 0x00007fc898a00000
- 0x00007fc898a00000 to 0x00007fc898c00000
- 0x00007fc898c00000 to 0x00007fc899000000
- 0x00007fc899000000 to 0x00007fc899200000
Operations Result: None
Cc: Danilo Krummrich <dakr@redhat.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/drm_gpuvm.c | 175 +++++++++++++++++++++++++++++++++++-
include/drm/drm_gpuvm.h | 6 ++
2 files changed, 180 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
index f9eb56f24bef..904a26641b21 100644
--- a/drivers/gpu/drm/drm_gpuvm.c
+++ b/drivers/gpu/drm/drm_gpuvm.c
@@ -2230,7 +2230,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
ret = op_remap_cb(ops, priv, NULL, &n, &u);
if (ret)
return ret;
- break;
+ return 0;
}
}
}
@@ -2240,6 +2240,143 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
req_obj, req_offset);
}
+static int
+__drm_gpuvm_skip_split_map(struct drm_gpuvm *gpuvm,
+ const struct drm_gpuvm_ops *ops, void *priv,
+ u64 req_addr, u64 req_range,
+ bool skip_gem_obj_va, u64 req_offset)
+{
+ struct drm_gpuva *va, *next;
+ u64 req_end = req_addr + req_range;
+ int ret;
+
+ if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range)))
+ return -EINVAL;
+
+ drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) {
+ struct drm_gem_object *obj = va->gem.obj;
+ u64 offset = va->gem.offset;
+ u64 addr = va->va.addr;
+ u64 range = va->va.range;
+ u64 end = addr + range;
+
+ if (addr == req_addr) {
+ if (end == req_end)
+ return 0;
+
+ if (end < req_end)
+ continue;
+
+ if (end > req_end) {
+ if (skip_gem_obj_va && !!obj)
+ return 0;
+
+ struct drm_gpuva_op_map n = {
+ .va.addr = req_end,
+ .va.range = range - req_range,
+ .gem.obj = obj,
+ .gem.offset = offset + req_range,
+ };
+ struct drm_gpuva_op_unmap u = {
+ .va = va,
+ .keep = false,
+ };
+
+ ret = op_remap_cb(ops, priv, NULL, &n, &u);
+ if (ret)
+ return ret;
+
+ break;
+ }
+ } else if (addr < req_addr) {
+ u64 ls_range = req_addr - addr;
+ struct drm_gpuva_op_map p = {
+ .va.addr = addr,
+ .va.range = ls_range,
+ .gem.obj = obj,
+ .gem.offset = offset,
+ };
+ struct drm_gpuva_op_unmap u = { .va = va, .keep = false, };
+
+ if (end == req_end) {
+ if (skip_gem_obj_va && !!obj)
+ return 0;
+
+ ret = op_remap_cb(ops, priv, &p, NULL, &u);
+ if (ret)
+ return ret;
+ break;
+ }
+
+ if (end < req_end) {
+ if (skip_gem_obj_va && !!obj)
+ continue;
+
+ ret = op_remap_cb(ops, priv, &p, NULL, &u);
+ if (ret)
+ return ret;
+
+ ret = op_map_cb(ops, priv, req_addr,
+ min(end - req_addr, req_end - end),
+ NULL, req_offset);
+ if (ret)
+ return ret;
+ continue;
+ }
+
+ if (end > req_end) {
+ if (skip_gem_obj_va && !!obj)
+ return 0;
+
+ struct drm_gpuva_op_map n = {
+ .va.addr = req_end,
+ .va.range = end - req_end,
+ .gem.obj = obj,
+ .gem.offset = offset + ls_range +
+ req_range,
+ };
+
+ ret = op_remap_cb(ops, priv, &p, &n, &u);
+ if (ret)
+ return ret;
+ break;
+ }
+ } else if (addr > req_addr) {
+ if (end == req_end)
+ return 0;
+
+ if (end < req_end)
+ continue;
+
+ if (end > req_end) {
+ if (skip_gem_obj_va && !!obj)
+ return 0;
+
+ struct drm_gpuva_op_map n = {
+ .va.addr = req_end,
+ .va.range = end - req_end,
+ .gem.obj = obj,
+ .gem.offset = offset + req_end - addr,
+ };
+ struct drm_gpuva_op_unmap u = {
+ .va = va,
+ .keep = false,
+ };
+
+ ret = op_remap_cb(ops, priv, NULL, &n, &u);
+ if (ret)
+ return ret;
+ return op_map_cb(ops, priv, addr,
+ (req_end - addr), NULL, req_offset);
+ }
+ }
+ }
+
+ return op_map_cb(ops, priv,
+ req_addr, req_range,
+ NULL, req_offset);
+}
+
static int
__drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm,
const struct drm_gpuvm_ops *ops, void *priv,
@@ -2548,6 +2685,42 @@ drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
}
EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_ops_create);
+struct drm_gpuva_ops *
+drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm,
+ u64 req_addr, u64 req_range,
+ bool skip_gem_obj_va, u64 req_offset)
+{
+ struct drm_gpuva_ops *ops;
+ struct {
+ struct drm_gpuvm *vm;
+ struct drm_gpuva_ops *ops;
+ } args;
+ int ret;
+
+ ops = kzalloc(sizeof(*ops), GFP_KERNEL);
+ if (unlikely(!ops))
+ return ERR_PTR(-ENOMEM);
+
+ INIT_LIST_HEAD(&ops->list);
+
+ args.vm = gpuvm;
+ args.ops = ops;
+
+ ret = __drm_gpuvm_skip_split_map(gpuvm, &gpuvm_list_ops, &args,
+ req_addr, req_range,
+ skip_gem_obj_va, req_offset);
+
+ if (ret || list_empty(&ops->list))
+ goto err_free_ops;
+
+ return ops;
+
+err_free_ops:
+ drm_gpuva_ops_free(gpuvm, ops);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(drm_gpuvm_madvise_ops_create);
+
/**
* drm_gpuvm_sm_unmap_ops_create() - creates the &drm_gpuva_ops to split on
* unmap
diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
index 2a9629377633..e521ebabab9e 100644
--- a/include/drm/drm_gpuvm.h
+++ b/include/drm/drm_gpuvm.h
@@ -1062,6 +1062,12 @@ struct drm_gpuva_ops *
drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
u64 addr, u64 range,
struct drm_gem_object *obj, u64 offset);
+
+struct drm_gpuva_ops *
+drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm,
+ u64 addr, u64 range,
+ bool skip_gem_obj_va, u64 offset);
+
struct drm_gpuva_ops *
drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm,
u64 addr, u64 range);
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations
2025-03-14 8:02 ` [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations Himal Prasad Ghimiray
@ 2025-03-14 8:46 ` Ghimiray, Himal Prasad
2025-03-17 14:27 ` Danilo Krummrich
1 sibling, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-03-14 8:46 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Danilo Krummrich
On 14-03-2025 13:32, Himal Prasad Ghimiray wrote:
> Introduce MADVISE operations that do not unmap the GPU VMA. These
> operations split VMAs if the start or end addresses fall within existing
> VMAs. The operations can create up to 2 REMAPS and 2 MAPs.
>
> If the input range is within the existing range, it creates REMAP:UNMAP,
> REMAP:PREV, REMAP:NEXT, and MAP operations for the input range.
> Example:
> Input Range: 0x00007f0a54000000 to 0x00007f0a54400000
> GPU VMA: 0x0000000000000000 to 0x0000800000000000
> Operations Result:
> - REMAP:UNMAP: addr=0x0000000000000000, range=0x0000800000000000
> - REMAP:PREV: addr=0x0000000000000000, range=0x00007f0a54000000
> - REMAP:NEXT: addr=0x00007f0a54400000, range=0x000000f5abc00000
> - MAP: addr=0x00007f0a54000000, range=0x0000000000400000
>
> If the input range starts at the beginning of one GPU VMA and ends at
> the end of another VMA, covering multiple VMAs, the operations do nothing.
> Example:
> Input Range: 0x00007fc898800000 to 0x00007fc899000000
> GPU VMAs:
> - 0x0000000000000000 to 0x00007fc898800000
> - 0x00007fc898800000 to 0x00007fc898a00000
> - 0x00007fc898a00000 to 0x00007fc898c00000
> - 0x00007fc898c00000 to 0x00007fc899000000
> - 0x00007fc899000000 to 0x00007fc899200000
> Operations Result: None
>
> Cc: Danilo Krummrich <dakr@redhat.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/drm_gpuvm.c | 175 +++++++++++++++++++++++++++++++++++-
> include/drm/drm_gpuvm.h | 6 ++
> 2 files changed, 180 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
> index f9eb56f24bef..904a26641b21 100644
> --- a/drivers/gpu/drm/drm_gpuvm.c
> +++ b/drivers/gpu/drm/drm_gpuvm.c
> @@ -2230,7 +2230,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
> ret = op_remap_cb(ops, priv, NULL, &n, &u);
> if (ret)
> return ret;
> - break;
> + return 0;
> - break;
> + return 0;
Incorrectly left in patch, ignore this part.
> }
> }
> }
> @@ -2240,6 +2240,143 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
> req_obj, req_offset);
> }
>
> +static int
> +__drm_gpuvm_skip_split_map(struct drm_gpuvm *gpuvm,
> + const struct drm_gpuvm_ops *ops, void *priv,
> + u64 req_addr, u64 req_range,
> + bool skip_gem_obj_va, u64 req_offset)
> +{
> + struct drm_gpuva *va, *next;
> + u64 req_end = req_addr + req_range;
> + int ret;
> +
> + if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range)))
> + return -EINVAL;
> +
> + drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) {
> + struct drm_gem_object *obj = va->gem.obj;
> + u64 offset = va->gem.offset;
> + u64 addr = va->va.addr;
> + u64 range = va->va.range;
> + u64 end = addr + range;
> +
> + if (addr == req_addr) {
> + if (end == req_end)
> + return 0;
> +
> + if (end < req_end)
> + continue;
> +
> + if (end > req_end) {
> + if (skip_gem_obj_va && !!obj)
> + return 0;
> +
> + struct drm_gpuva_op_map n = {
> + .va.addr = req_end,
> + .va.range = range - req_range,
> + .gem.obj = obj,
> + .gem.offset = offset + req_range,
> + };
> + struct drm_gpuva_op_unmap u = {
> + .va = va,
> + .keep = false,
> + };
> +
> + ret = op_remap_cb(ops, priv, NULL, &n, &u);
> + if (ret)
> + return ret;
> +
> + break;
> + }
> + } else if (addr < req_addr) {
> + u64 ls_range = req_addr - addr;
> + struct drm_gpuva_op_map p = {
> + .va.addr = addr,
> + .va.range = ls_range,
> + .gem.obj = obj,
> + .gem.offset = offset,
> + };
> + struct drm_gpuva_op_unmap u = { .va = va, .keep = false, };
> +
> + if (end == req_end) {
> + if (skip_gem_obj_va && !!obj)
> + return 0;
> +
> + ret = op_remap_cb(ops, priv, &p, NULL, &u);
> + if (ret)
> + return ret;
> + break;
> + }
> +
> + if (end < req_end) {
> + if (skip_gem_obj_va && !!obj)
> + continue;
> +
> + ret = op_remap_cb(ops, priv, &p, NULL, &u);
> + if (ret)
> + return ret;
> +
> + ret = op_map_cb(ops, priv, req_addr,
> + min(end - req_addr, req_end - end),
> + NULL, req_offset);
> + if (ret)
> + return ret;
> + continue;
> + }
> +
> + if (end > req_end) {
> + if (skip_gem_obj_va && !!obj)
> + return 0;
> +
> + struct drm_gpuva_op_map n = {
> + .va.addr = req_end,
> + .va.range = end - req_end,
> + .gem.obj = obj,
> + .gem.offset = offset + ls_range +
> + req_range,
> + };
> +
> + ret = op_remap_cb(ops, priv, &p, &n, &u);
> + if (ret)
> + return ret;
> + break;
> + }
> + } else if (addr > req_addr) {
> + if (end == req_end)
> + return 0;
> +
> + if (end < req_end)
> + continue;
> +
> + if (end > req_end) {
> + if (skip_gem_obj_va && !!obj)
> + return 0;
> +
> + struct drm_gpuva_op_map n = {
> + .va.addr = req_end,
> + .va.range = end - req_end,
> + .gem.obj = obj,
> + .gem.offset = offset + req_end - addr,
> + };
> + struct drm_gpuva_op_unmap u = {
> + .va = va,
> + .keep = false,
> + };
> +
> + ret = op_remap_cb(ops, priv, NULL, &n, &u);
> + if (ret)
> + return ret;
> + return op_map_cb(ops, priv, addr,
> + (req_end - addr), NULL, req_offset);
> + }
> + }
> + }
> +
> + return op_map_cb(ops, priv,
> + req_addr, req_range,
> + NULL, req_offset);
> +}
> +
> static int
> __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm,
> const struct drm_gpuvm_ops *ops, void *priv,
> @@ -2548,6 +2685,42 @@ drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
> }
> EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_ops_create);
>
> +struct drm_gpuva_ops *
> +drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm,
> + u64 req_addr, u64 req_range,
> + bool skip_gem_obj_va, u64 req_offset)
> +{
> + struct drm_gpuva_ops *ops;
> + struct {
> + struct drm_gpuvm *vm;
> + struct drm_gpuva_ops *ops;
> + } args;
> + int ret;
> +
> + ops = kzalloc(sizeof(*ops), GFP_KERNEL);
> + if (unlikely(!ops))
> + return ERR_PTR(-ENOMEM);
> +
> + INIT_LIST_HEAD(&ops->list);
> +
> + args.vm = gpuvm;
> + args.ops = ops;
> +
> + ret = __drm_gpuvm_skip_split_map(gpuvm, &gpuvm_list_ops, &args,
> + req_addr, req_range,
> + skip_gem_obj_va, req_offset);
> +
> + if (ret || list_empty(&ops->list))
> + goto err_free_ops;
> +
> + return ops;
> +
> +err_free_ops:
> + drm_gpuva_ops_free(gpuvm, ops);
> + return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL_GPL(drm_gpuvm_madvise_ops_create);
> +
> /**
> * drm_gpuvm_sm_unmap_ops_create() - creates the &drm_gpuva_ops to split on
> * unmap
> diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
> index 2a9629377633..e521ebabab9e 100644
> --- a/include/drm/drm_gpuvm.h
> +++ b/include/drm/drm_gpuvm.h
> @@ -1062,6 +1062,12 @@ struct drm_gpuva_ops *
> drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
> u64 addr, u64 range,
> struct drm_gem_object *obj, u64 offset);
> +
> +struct drm_gpuva_ops *
> +drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm,
> + u64 addr, u64 range,
> + bool skip_gem_obj_va, u64 offset);
> +
> struct drm_gpuva_ops *
> drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm,
> u64 addr, u64 range);
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations
2025-03-14 8:02 ` [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations Himal Prasad Ghimiray
2025-03-14 8:46 ` Ghimiray, Himal Prasad
@ 2025-03-17 14:27 ` Danilo Krummrich
2025-03-18 11:58 ` Ghimiray, Himal Prasad
1 sibling, 1 reply; 52+ messages in thread
From: Danilo Krummrich @ 2025-03-17 14:27 UTC (permalink / raw)
To: Himal Prasad Ghimiray
Cc: intel-xe, matthew.brost, thomas.hellstrom, oak.zeng, dri-devel,
bbrezillon
(Cc: dri-devel@lists.freedesktop.org, Boris)
Hi Himal,
Please make sure to copy in dri-devel for such patches.
On Fri, Mar 14, 2025 at 01:32:10PM +0530, Himal Prasad Ghimiray wrote:
> Introduce MADVISE operations that do not unmap the GPU VMA. These
> operations split VMAs if the start or end addresses fall within existing
> VMAs. The operations can create up to 2 REMAPS and 2 MAPs.
Can you please add some more motivation details for this patch? What exactly is
it used for?
>
> If the input range is within the existing range, it creates REMAP:UNMAP,
> REMAP:PREV, REMAP:NEXT, and MAP operations for the input range.
> Example:
> Input Range: 0x00007f0a54000000 to 0x00007f0a54400000
> GPU VMA: 0x0000000000000000 to 0x0000800000000000
> Operations Result:
> - REMAP:UNMAP: addr=0x0000000000000000, range=0x0000800000000000
> - REMAP:PREV: addr=0x0000000000000000, range=0x00007f0a54000000
> - REMAP:NEXT: addr=0x00007f0a54400000, range=0x000000f5abc00000
> - MAP: addr=0x00007f0a54000000, range=0x0000000000400000
This would be much easier to read if you'd pick some more human readable
numbers.
>
> If the input range starts at the beginning of one GPU VMA and ends at
> the end of another VMA, covering multiple VMAs, the operations do nothing.
> Example:
> Input Range: 0x00007fc898800000 to 0x00007fc899000000
> GPU VMAs:
> - 0x0000000000000000 to 0x00007fc898800000
> - 0x00007fc898800000 to 0x00007fc898a00000
> - 0x00007fc898a00000 to 0x00007fc898c00000
> - 0x00007fc898c00000 to 0x00007fc899000000
> - 0x00007fc899000000 to 0x00007fc899200000
> Operations Result: None
Same here.
>
> Cc: Danilo Krummrich <dakr@redhat.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/drm_gpuvm.c | 175 +++++++++++++++++++++++++++++++++++-
> include/drm/drm_gpuvm.h | 6 ++
> 2 files changed, 180 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
> index f9eb56f24bef..904a26641b21 100644
> --- a/drivers/gpu/drm/drm_gpuvm.c
> +++ b/drivers/gpu/drm/drm_gpuvm.c
> @@ -2230,7 +2230,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
> ret = op_remap_cb(ops, priv, NULL, &n, &u);
> if (ret)
> return ret;
> - break;
> + return 0;
> }
> }
> }
> @@ -2240,6 +2240,143 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
> req_obj, req_offset);
> }
>
> +static int
> +__drm_gpuvm_skip_split_map(struct drm_gpuvm *gpuvm,
> + const struct drm_gpuvm_ops *ops, void *priv,
> + u64 req_addr, u64 req_range,
> + bool skip_gem_obj_va, u64 req_offset)
This looks like a full copy of __drm_gpuvm_sm_map(). I think you should extend
__drm_gpuvm_sm_map() instead and add an optional flags parameter, e.g.
enum drm_gpuvm_madvise_flags {
DRM_GPUVM_SKIP_GEM_OBJ_VA = BIT(0),
}
Not sure whether "SKIP_GEM_OBJ_VA" is a good name, but I haven't gone through
this to such extend that I could propose something better.
> +struct drm_gpuva_ops *
> +drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm,
> + u64 req_addr, u64 req_range,
> + bool skip_gem_obj_va, u64 req_offset)
Same here, I don't think we need a new function for this, but just the
corresponding flags argument to the existing one.
Besides that, when adding new functionality, please extend the documentation of
drm_gpuvm accordingly. It's fine you didn't do so for the RFC of course. :)
^ permalink raw reply [flat|nested] 52+ messages in thread* Re: [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations
2025-03-17 14:27 ` Danilo Krummrich
@ 2025-03-18 11:58 ` Ghimiray, Himal Prasad
0 siblings, 0 replies; 52+ messages in thread
From: Ghimiray, Himal Prasad @ 2025-03-18 11:58 UTC (permalink / raw)
To: Danilo Krummrich
Cc: intel-xe, matthew.brost, thomas.hellstrom, oak.zeng, dri-devel,
bbrezillon
Hi Danilo,
On 17-03-2025 19:57, Danilo Krummrich wrote:
> (Cc: dri-devel@lists.freedesktop.org, Boris)
>
> Hi Himal,
>
> Please make sure to copy in dri-devel for such patches.
Thanks for taking time for this. Will make sure to do same in future.
>
> On Fri, Mar 14, 2025 at 01:32:10PM +0530, Himal Prasad Ghimiray wrote:
>> Introduce MADVISE operations that do not unmap the GPU VMA. These
>> operations split VMAs if the start or end addresses fall within existing
>> VMAs. The operations can create up to 2 REMAPS and 2 MAPs.
>
> Can you please add some more motivation details for this patch? What exactly is
> it used for?
We are working on defining the madvise ioctl within the Xe driver,
which sets or unsets attributes to control page placement and PTE
(Page Table Entry) encoding for GPUVMA's within a user-provided
range.
The goal of this patch is to introduce drm_gpuva_ops, which will
create a drm_gpuva_op to cover the user-defined input range.
Let's assume there are multiple gpuvma's within a to d:
drm_gpuva1 drm_gpuva2
attr_1 = x attr_1 = x1
attr_2 = y attr_2 = y1
attr_3 = z attr_3 = z1
[a----------------------------b-1][b-------------------c-1]
drm_gpuva3
attr_1 = x2
attr_2 = y2
attr_3 = z2
[c-------------------d-1]
Case 1)
In this case, the start and end of the user-provided range
lie within drm_gpuva1 a and b-1. We need to update attr_1 to x'.
drm_gpuva1:pre drm_gpuva:New map drm_gpuva1:next
attr_1 = x attr_1 = x' attr_1 = x
attr_2 = y attr_2 = y attr_2 = y
attr_3 = z attr_3 = z attr_3 = z
[a---------start-1][start------- end-1][end---------------b-1]
In this scenario, behavior for ops_create is same as
drm_gpuvm_sm_map_ops_create
REMAP:UNMAP drm_gpuva1 a to b
REMAP:PREV a to start -1
REMAP:NEXT end to b-1
MAP: start to end
Case 2)
User provided input range covers multiple drm_gpuva's.
Start is in between a and b (drm_gpuva1). End is in between c and
d-1 (drm_gpuva2). We need to update attr_2 to y'.
drm_gpuva1:pre drm_gpuva:Map1 drm_gpuva2
attr_1 = x attr_1 = x attr_1 = x1
attr_2 = y attr_2 = y' attr_2 = y'
attr_3 = z attr_3 = z attr_3 = z1
[a----------start-1][start-------------b-1][b-------------c - 1]
drm_gpuva:Map2 drm_gpuva3:Next
attr_1 = x2 attr_1 = x2
attr_2 = y' attr_2 = y2
attr_3 = z2 attr_3 = z2
[c------ end-1][end------------d-1]
In this scenario:
REMAP:UNMAP drm_gpuva1 a to b
REMAP:PREV a to start -1
MAP: start to b
REMAP:UNMAP drm_gpuva3 a to b
REMAP:NEXT end+1 to e
MAP: d+1 to end
Behavior is entirely different than drm_gpuvm_sm_map_ops_create.
Case 3) Either of start or end lies within gpuvma and will have one
REMAP and one MAP.
Case 4) Both start and end are lying on existing drm_gpuva's
start/end. No OPS.
The behavior is not same as drm_gpuvm_sm_map_ops_create. Here we
don't merge the drm_gpuva's and there are no unmaps.
Currently, we don't want split to happen on bo backed vma's,
therefore skip_gem_obj_va is added.
[1] and [2] are the patches within driver using the ops and defining the
ioctl
[1]
https://lore.kernel.org/intel-xe/20250314080226.2059819-1-himal.prasad.ghimiray@intel.com/T/#m77dd9ea3507ed15bfcd2a1c410f9df17f79c69e1
[2]
https://lore.kernel.org/intel-xe/20250314080226.2059819-1-himal.prasad.ghimiray@intel.com/T/#m2c49bf11661dec9d52edb8bf1bf9a553a709682e
>
>>
>> If the input range is within the existing range, it creates REMAP:UNMAP,
>> REMAP:PREV, REMAP:NEXT, and MAP operations for the input range.
>> Example:
>> Input Range: 0x00007f0a54000000 to 0x00007f0a54400000
>> GPU VMA: 0x0000000000000000 to 0x0000800000000000
>> Operations Result:
>> - REMAP:UNMAP: addr=0x0000000000000000, range=0x0000800000000000
>> - REMAP:PREV: addr=0x0000000000000000, range=0x00007f0a54000000
>> - REMAP:NEXT: addr=0x00007f0a54400000, range=0x000000f5abc00000
>> - MAP: addr=0x00007f0a54000000, range=0x0000000000400000
>
> This would be much easier to read if you'd pick some more human readable
> numbers.
This was the output which I printed from within the driver. Should have
ensured it to be more explanatory. Can you provide some input on how can
I make it more readable ?
>
>>
>> If the input range starts at the beginning of one GPU VMA and ends at
>> the end of another VMA, covering multiple VMAs, the operations do nothing.
>> Example:
>> Input Range: 0x00007fc898800000 to 0x00007fc899000000
>> GPU VMAs:
>> - 0x0000000000000000 to 0x00007fc898800000
>> - 0x00007fc898800000 to 0x00007fc898a00000
>> - 0x00007fc898a00000 to 0x00007fc898c00000
>> - 0x00007fc898c00000 to 0x00007fc899000000
>> - 0x00007fc899000000 to 0x00007fc899200000
>> Operations Result: None
>
> Same here.
>
>>
>> Cc: Danilo Krummrich <dakr@redhat.com>
>> Cc: Matthew Brost <matthew.brost@intel.com>
>> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> ---
>> drivers/gpu/drm/drm_gpuvm.c | 175 +++++++++++++++++++++++++++++++++++-
>> include/drm/drm_gpuvm.h | 6 ++
>> 2 files changed, 180 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
>> index f9eb56f24bef..904a26641b21 100644
>> --- a/drivers/gpu/drm/drm_gpuvm.c
>> +++ b/drivers/gpu/drm/drm_gpuvm.c
>> @@ -2230,7 +2230,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
>> ret = op_remap_cb(ops, priv, NULL, &n, &u);
>> if (ret)
>> return ret;
>> - break;
>> + return 0;
>> }
>> }
>> }
>> @@ -2240,6 +2240,143 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
>> req_obj, req_offset);
>> }
>>
>> +static int
>> +__drm_gpuvm_skip_split_map(struct drm_gpuvm *gpuvm,
>> + const struct drm_gpuvm_ops *ops, void *priv,
>> + u64 req_addr, u64 req_range,
>> + bool skip_gem_obj_va, u64 req_offset)
>
> This looks like a full copy of __drm_gpuvm_sm_map(). I think you should extend
> __drm_gpuvm_sm_map() instead and add an optional flags parameter, e.g.
Unlike __drm_gpuvm_sm_map() this wont have any unmaps and merging of
drm_gpuva's, hence I thought keeping it as separate ops is better. If
you are of the opinion modifying __drm_gpuvm_sm_map on the basis of flag
is more cleaner and maintainable, will change to it.
>
> enum drm_gpuvm_madvise_flags {
> DRM_GPUVM_SKIP_GEM_OBJ_VA = BIT(0),
> }
>
> Not sure whether "SKIP_GEM_OBJ_VA" is a good name, but I haven't gone through
> this to such extend that I could propose something better.
>
>> +struct drm_gpuva_ops *
>> +drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm,
>> + u64 req_addr, u64 req_range,
>> + bool skip_gem_obj_va, u64 req_offset)
>
> Same here, I don't think we need a new function for this, but just the
> corresponding flags argument to the existing one.
Same as above
>
> Besides that, when adding new functionality, please extend the documentation of
> drm_gpuvm accordingly. It's fine you didn't do so for the RFC of course. :)
Thanks for reminding. I Will definitely add proper documentation with
conclusion on further design, just wanted to have opinions on this with
RFC.
- Himal
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 14/29] drm/xe/uapi: Add madvise interface
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (12 preceding siblings ...)
2025-03-14 8:02 ` [RFC 13/29] drm/gpuvm: Introduce MADVISE Operations Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 15/29] drm/xe/vm: Add attributes struct as member of vma Himal Prasad Ghimiray
` (15 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
This commit introduces a new madvise interface to support
driver-specific ioctl operations. The madvise interface allows for more
efficient memory management by providing hints to the driver about the
expected memory usage and pte update policy for gpuvma.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
include/uapi/drm/xe_drm.h | 97 +++++++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 616916985e3f..70e79fe35834 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -81,6 +81,7 @@ extern "C" {
* - &DRM_IOCTL_XE_EXEC
* - &DRM_IOCTL_XE_WAIT_USER_FENCE
* - &DRM_IOCTL_XE_OBSERVATION
+ * - &DRM_IOCTL_XE_MADVISE
*/
/*
@@ -102,6 +103,7 @@ extern "C" {
#define DRM_XE_EXEC 0x09
#define DRM_XE_WAIT_USER_FENCE 0x0a
#define DRM_XE_OBSERVATION 0x0b
+#define DRM_XE_MADVISE 0x0c
/* Must be kept compact -- no holes */
@@ -117,6 +119,7 @@ extern "C" {
#define DRM_IOCTL_XE_EXEC DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec)
#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
#define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
+#define DRM_IOCTL_XE_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_MADVISE, struct drm_xe_madvise)
/**
* DOC: Xe IOCTL Extensions
@@ -1961,6 +1964,100 @@ struct drm_xe_query_eu_stall {
__u64 sampling_rates[];
};
+struct drm_xe_madvise_ops {
+ /** @start: start of the virtual address range */
+ __u64 start;
+
+ /** @size: size of the virtual address range */
+ __u64 range;
+
+#define DRM_XE_VMA_ATTR_PREFERRED_LOC 0
+#define DRM_XE_VMA_ATTR_ATOMIC 1
+#define DRM_XE_VMA_ATTR_PAT 2
+#define DRM_XE_VMA_ATTR_PURGEABLE_STATE 3
+ /** @type: type of attribute */
+ __u32 type;
+
+ /** @pad: MBZ */
+ __u32 pad;
+
+ union {
+ struct {
+#define DRM_XE_VMA_ATOMIC_UNDEFINED 0
+#define DRM_XE_VMA_ATOMIC_DEVICE 1
+#define DRM_XE_VMA_ATOMIC_GLOBAL 2
+#define DRM_XE_VMA_ATOMIC_CPU 3
+ /** @val: value of atomic operation*/
+ __u32 val;
+
+ /** @reserved: Reserved */
+ __u32 reserved;
+ } atomic;
+
+ struct {
+#define DRM_XE_VMA_PURGEABLE_STATE_WILLNEED 0
+#define DRM_XE_VMA_PURGEABLE_STATE_DONTNEED 1
+#define DRM_XE_VMA_PURGEABLE_STATE_PURGED 2
+ /** @val: value for DRM_XE_VMA_ATTR_PURGEABLE_STATE */
+ __u32 val;
+
+ /** @reserved: Reserved */
+ __u32 reserved;
+ } purge_state_val;
+
+ struct {
+ /** @pat_index */
+ __u32 val;
+
+ /** @reserved: Reserved */
+ __u32 reserved;
+ } pat_index;
+
+ /** @preferred_mem_loc: preferred memory location */
+ struct {
+ __u32 devmem_fd;
+
+#define MIGRATE_ALL_PAGES 0
+#define MIGRATE_ONLY_SYSTEM_PAGES 1
+ __u32 migration_policy;
+ } preferred_mem_loc;
+ };
+
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+};
+
+/**
+ * struct drm_xe_madvise - Input of &DRM_IOCTL_XE_MADVISE
+ *
+ * Set memory attributes to a virtual address range
+ */
+struct drm_xe_madvise {
+ /** @extensions: Pointer to the first extension struct, if any */
+ __u64 extensions;
+
+ /** @vm_id: vm_id of the virtual range */
+ __u32 vm_id;
+
+ /** @num_ops: number of madvises in ioctl */
+ __u32 num_ops;
+
+ union {
+ /** @ops: used if num_ops == 1 */
+ struct drm_xe_madvise_ops ops;
+
+ /**
+ * @vector_of_ops: userptr to array of struct
+ * drm_xe_vm_madvise_op if num_ops > 1
+ */
+ __u64 vector_of_ops;
+ };
+
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+
+};
+
#if defined(__cplusplus)
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 15/29] drm/xe/vm: Add attributes struct as member of vma
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (13 preceding siblings ...)
2025-03-14 8:02 ` [RFC 14/29] drm/xe/uapi: Add madvise interface Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 16/29] drm/xe/vma: Move pat_index to vma attributes Himal Prasad Ghimiray
` (14 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
The attribute of xe_vma will determine the migration policy and the
encoding of the page table entries (PTEs) for that vma.
This attribute helps manage how memory pages are moved and how their
addresses are translated. It will be used by madvise to set the
behavior of the vma.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 6 ++++++
drivers/gpu/drm/xe/xe_vm_types.h | 20 ++++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index f63dd4eb1ae8..369a9527af79 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2440,6 +2440,12 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
vma = ERR_PTR(err);
}
+ /*TODO: assign devmem_fd of local vram once multi device
+ * support is added.
+ */
+ vma->attr.preferred_loc.devmem_fd = 1;
+ vma->attr.atomic_access = DRM_XE_VMA_ATOMIC_UNDEFINED;
+
return vma;
}
diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
index 0b02a37bd2f3..b69dfe1646ed 100644
--- a/drivers/gpu/drm/xe/xe_vm_types.h
+++ b/drivers/gpu/drm/xe/xe_vm_types.h
@@ -77,6 +77,19 @@ struct xe_userptr {
#endif
};
+/**
+ * struct xe_vma_mem_attr - memory attributes associated with vma
+ */
+struct xe_vma_mem_attr {
+ /** @preferred_loc: perferred memory_location*/
+ struct {
+ u32 migration_policy; /* represents migration policies */
+ u32 devmem_fd; /* devmem_fd used for determining pagemap_fd requested by user */
+ } preferred_loc;
+ /** @atomic_access: The atomic access type for the vma */
+ u32 atomic_access;
+};
+
struct xe_vma {
/** @gpuva: Base GPUVA object */
struct drm_gpuva gpuva;
@@ -128,6 +141,13 @@ struct xe_vma {
* Needs to be signalled before UNMAP can be processed.
*/
struct xe_user_fence *ufence;
+
+ /**
+ * @attr: The attributes of vma which determines the migration policy
+ * and encoding of the PTEs for this vma.
+ */
+ struct xe_vma_mem_attr attr;
+
};
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 16/29] drm/xe/vma: Move pat_index to vma attributes
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (14 preceding siblings ...)
2025-03-14 8:02 ` [RFC 15/29] drm/xe/vm: Add attributes struct as member of vma Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 17/29] drm/xe/vma: Modify new_vma to accept struct xe_vma_mem_attr as parameter Himal Prasad Ghimiray
` (13 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
The PAT index determines how PTEs are encoded and can be modified by
madvise. Therefore, it is now part of the vma attributes.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_pt.c | 2 +-
drivers/gpu/drm/xe/xe_vm.c | 6 +++---
drivers/gpu/drm/xe/xe_vm_types.h | 10 ++++------
3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 5574d3008a0d..d51f7d1c86cf 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -503,7 +503,7 @@ xe_pt_stage_bind_entry(struct xe_ptw *parent, pgoff_t offset,
{
struct xe_pt_stage_bind_walk *xe_walk =
container_of(walk, typeof(*xe_walk), base);
- u16 pat_index = xe_walk->vma->pat_index;
+ u16 pat_index = xe_walk->vma->attr.pat_index;
struct xe_pt *xe_parent = container_of(parent, typeof(*xe_parent), base);
struct xe_vm *vm = xe_walk->vm;
struct xe_pt *xe_child;
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 369a9527af79..a428562d9eb8 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -1221,7 +1221,7 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
if (vm->xe->info.has_atomic_enable_pte_bit)
vma->gpuva.flags |= XE_VMA_ATOMIC_PTE_BIT;
- vma->pat_index = pat_index;
+ vma->attr.pat_index = pat_index;
if (bo) {
struct drm_gpuvm_bo *vm_bo;
@@ -2625,7 +2625,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
if (op->base.remap.prev) {
vma = new_vma(vm, op->base.remap.prev,
- old->pat_index, flags);
+ old->attr.pat_index, flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
@@ -2655,7 +2655,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
if (op->base.remap.next) {
vma = new_vma(vm, op->base.remap.next,
- old->pat_index, flags);
+ old->attr.pat_index, flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
index b69dfe1646ed..43fa5bad7290 100644
--- a/drivers/gpu/drm/xe/xe_vm_types.h
+++ b/drivers/gpu/drm/xe/xe_vm_types.h
@@ -88,6 +88,10 @@ struct xe_vma_mem_attr {
} preferred_loc;
/** @atomic_access: The atomic access type for the vma */
u32 atomic_access;
+ /**
+ * @pat_index: The pat index to use when encoding the PTEs for this vma.
+ */
+ u16 pat_index;
};
struct xe_vma {
@@ -131,11 +135,6 @@ struct xe_vma {
/** @tile_staged: bind is staged for this VMA */
u8 tile_staged;
- /**
- * @pat_index: The pat index to use when encoding the PTEs for this vma.
- */
- u16 pat_index;
-
/**
* @ufence: The user fence that was provided with MAP.
* Needs to be signalled before UNMAP can be processed.
@@ -147,7 +146,6 @@ struct xe_vma {
* and encoding of the PTEs for this vma.
*/
struct xe_vma_mem_attr attr;
-
};
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 17/29] drm/xe/vma: Modify new_vma to accept struct xe_vma_mem_attr as parameter
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (15 preceding siblings ...)
2025-03-14 8:02 ` [RFC 16/29] drm/xe/vma: Move pat_index to vma attributes Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 18/29] drm/gpusvm: Make drm_gpusvm_for_each_* macros public Himal Prasad Ghimiray
` (12 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
This change simplifies the logic by ensuring that remapped previous or
next VMAs are created with the same memory attributes as the original VMA.
By passing struct xe_vma_mem_attr as a parameter, we maintain consistency
in memory attributes.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index a428562d9eb8..b892b43d6665 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2391,8 +2391,16 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_create, ERRNO);
+static void cp_mem_attr(struct xe_vma_mem_attr *dst, struct xe_vma_mem_attr *src)
+{
+ dst->preferred_loc.migration_policy = src->preferred_loc.migration_policy;
+ dst->preferred_loc.devmem_fd = dst->preferred_loc.devmem_fd;
+ dst->atomic_access = src->atomic_access;
+ dst->pat_index = src->pat_index;
+}
+
static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
- u16 pat_index, unsigned int flags)
+ struct xe_vma_mem_attr attr, unsigned int flags)
{
struct xe_bo *bo = op->gem.obj ? gem_to_xe_bo(op->gem.obj) : NULL;
struct drm_exec exec;
@@ -2421,7 +2429,7 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
}
vma = xe_vma_create(vm, bo, op->gem.offset,
op->va.addr, op->va.addr +
- op->va.range - 1, pat_index, flags);
+ op->va.range - 1, attr.pat_index, flags);
if (IS_ERR(vma))
goto err_unlock;
@@ -2440,11 +2448,7 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
vma = ERR_PTR(err);
}
- /*TODO: assign devmem_fd of local vram once multi device
- * support is added.
- */
- vma->attr.preferred_loc.devmem_fd = 1;
- vma->attr.atomic_access = DRM_XE_VMA_ATOMIC_UNDEFINED;
+ cp_mem_attr(&vma->attr, &attr);
return vma;
}
@@ -2570,6 +2574,17 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
switch (op->base.op) {
case DRM_GPUVA_OP_MAP:
{
+ struct xe_vma_mem_attr default_attr = {
+ .preferred_loc = {
+ /*TODO: assign devmem_fd of local vram
+ * once multi device support is added.
+ */
+ .devmem_fd = IS_DGFX(vm->xe) ? 1 : 0,
+ .migration_policy = 1, },
+ .atomic_access = DRM_XE_VMA_ATOMIC_UNDEFINED,
+ .pat_index = op->map.pat_index
+ };
+
flags |= op->map.read_only ?
VMA_CREATE_FLAG_READ_ONLY : 0;
flags |= op->map.is_null ?
@@ -2579,7 +2594,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
flags |= op->map.is_cpu_addr_mirror ?
VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR : 0;
- vma = new_vma(vm, &op->base.map, op->map.pat_index,
+ vma = new_vma(vm, &op->base.map, default_attr,
flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
@@ -2625,7 +2640,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
if (op->base.remap.prev) {
vma = new_vma(vm, op->base.remap.prev,
- old->attr.pat_index, flags);
+ old->attr, flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
@@ -2655,7 +2670,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
if (op->base.remap.next) {
vma = new_vma(vm, op->base.remap.next,
- old->attr.pat_index, flags);
+ old->attr, flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 18/29] drm/gpusvm: Make drm_gpusvm_for_each_* macros public
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (16 preceding siblings ...)
2025-03-14 8:02 ` [RFC 17/29] drm/xe/vma: Modify new_vma to accept struct xe_vma_mem_attr as parameter Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 19/29] drm/xe/svm: Split system allocator vma incase of madvise call Himal Prasad Ghimiray
` (11 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
The drm_gpusvm_for_each_notifier, drm_gpusvm_for_each_notifier_safe and
drm_gpusvm_for_each_range_safe macros are useful for locating notifiers
and ranges within a user-specified range. By making these macros public,
we enable broader access and utility for developers who need to leverage
them in their implementations.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/drm_gpusvm.c | 89 +--------------------------------
include/drm/drm_gpusvm.h | 96 +++++++++++++++++++++++++++++++++++-
2 files changed, 96 insertions(+), 89 deletions(-)
diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c
index 2451c816edd5..d338f2ed62b3 100644
--- a/drivers/gpu/drm/drm_gpusvm.c
+++ b/drivers/gpu/drm/drm_gpusvm.c
@@ -391,97 +391,10 @@ struct drm_gpusvm_range *
drm_gpusvm_range_find(struct drm_gpusvm_notifier *notifier, unsigned long start,
unsigned long end)
{
- struct interval_tree_node *itree;
-
- itree = interval_tree_iter_first(¬ifier->root, start, end - 1);
-
- if (itree)
- return container_of(itree, struct drm_gpusvm_range, itree);
- else
- return NULL;
+ return __drm_gpusvm_range_find(notifier, start, end);
}
EXPORT_SYMBOL_GPL(drm_gpusvm_range_find);
-/**
- * drm_gpusvm_for_each_range_safe() - Safely iterate over GPU SVM ranges in a notifier
- * @range__: Iterator variable for the ranges
- * @next__: Iterator variable for the ranges temporay storage
- * @notifier__: Pointer to the GPU SVM notifier
- * @start__: Start address of the range
- * @end__: End address of the range
- *
- * This macro is used to iterate over GPU SVM ranges in a notifier while
- * removing ranges from it.
- */
-#define drm_gpusvm_for_each_range_safe(range__, next__, notifier__, start__, end__) \
- for ((range__) = drm_gpusvm_range_find((notifier__), (start__), (end__)), \
- (next__) = __drm_gpusvm_range_next(range__); \
- (range__) && (drm_gpusvm_range_start(range__) < (end__)); \
- (range__) = (next__), (next__) = __drm_gpusvm_range_next(range__))
-
-/**
- * __drm_gpusvm_notifier_next() - get the next drm_gpusvm_notifier in the list
- * @notifier: a pointer to the current drm_gpusvm_notifier
- *
- * Return: A pointer to the next drm_gpusvm_notifier if available, or NULL if
- * the current notifier is the last one or if the input notifier is
- * NULL.
- */
-static struct drm_gpusvm_notifier *
-__drm_gpusvm_notifier_next(struct drm_gpusvm_notifier *notifier)
-{
- if (notifier && !list_is_last(¬ifier->entry,
- ¬ifier->gpusvm->notifier_list))
- return list_next_entry(notifier, entry);
-
- return NULL;
-}
-
-static struct drm_gpusvm_notifier *
-notifier_iter_first(struct rb_root_cached *root, unsigned long start,
- unsigned long last)
-{
- struct interval_tree_node *itree;
-
- itree = interval_tree_iter_first(root, start, last);
-
- if (itree)
- return container_of(itree, struct drm_gpusvm_notifier, itree);
- else
- return NULL;
-}
-
-/**
- * drm_gpusvm_for_each_notifier() - Iterate over GPU SVM notifiers in a gpusvm
- * @notifier__: Iterator variable for the notifiers
- * @notifier__: Pointer to the GPU SVM notifier
- * @start__: Start address of the notifier
- * @end__: End address of the notifier
- *
- * This macro is used to iterate over GPU SVM notifiers in a gpusvm.
- */
-#define drm_gpusvm_for_each_notifier(notifier__, gpusvm__, start__, end__) \
- for ((notifier__) = notifier_iter_first(&(gpusvm__)->root, (start__), (end__) - 1); \
- (notifier__) && (drm_gpusvm_notifier_start(notifier__) < (end__)); \
- (notifier__) = __drm_gpusvm_notifier_next(notifier__))
-
-/**
- * drm_gpusvm_for_each_notifier_safe() - Safely iterate over GPU SVM notifiers in a gpusvm
- * @notifier__: Iterator variable for the notifiers
- * @next__: Iterator variable for the notifiers temporay storage
- * @notifier__: Pointer to the GPU SVM notifier
- * @start__: Start address of the notifier
- * @end__: End address of the notifier
- *
- * This macro is used to iterate over GPU SVM notifiers in a gpusvm while
- * removing notifiers from it.
- */
-#define drm_gpusvm_for_each_notifier_safe(notifier__, next__, gpusvm__, start__, end__) \
- for ((notifier__) = notifier_iter_first(&(gpusvm__)->root, (start__), (end__) - 1), \
- (next__) = __drm_gpusvm_notifier_next(notifier__); \
- (notifier__) && (drm_gpusvm_notifier_start(notifier__) < (end__)); \
- (notifier__) = (next__), (next__) = __drm_gpusvm_notifier_next(notifier__))
-
/**
* drm_gpusvm_notifier_invalidate() - Invalidate a GPU SVM notifier.
* @mni: Pointer to the mmu_interval_notifier structure.
diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h
index df120b4d1f83..9bd03cb67d0e 100644
--- a/include/drm/drm_gpusvm.h
+++ b/include/drm/drm_gpusvm.h
@@ -489,6 +489,20 @@ __drm_gpusvm_range_next(struct drm_gpusvm_range *range)
return NULL;
}
+static inline struct drm_gpusvm_range *
+__drm_gpusvm_range_find(struct drm_gpusvm_notifier *notifier,
+ unsigned long start, unsigned long end)
+{
+ struct interval_tree_node *itree;
+
+ itree = interval_tree_iter_first(¬ifier->root, start, end - 1);
+
+ if (itree)
+ return container_of(itree, struct drm_gpusvm_range, itree);
+ else
+ return NULL;
+}
+
/**
* drm_gpusvm_for_each_range() - Iterate over GPU SVM ranges in a notifier
* @range__: Iterator variable for the ranges. If set, it indicates the start of
@@ -502,8 +516,88 @@ __drm_gpusvm_range_next(struct drm_gpusvm_range *range)
*/
#define drm_gpusvm_for_each_range(range__, notifier__, start__, end__) \
for ((range__) = (range__) ?: \
- drm_gpusvm_range_find((notifier__), (start__), (end__)); \
+ __drm_gpusvm_range_find((notifier__), (start__), (end__)); \
(range__) && (drm_gpusvm_range_start(range__) < (end__)); \
(range__) = __drm_gpusvm_range_next(range__))
+/**
+ * drm_gpusvm_for_each_range_safe() - Safely iterate over GPU SVM ranges in a notifier
+ * @range__: Iterator variable for the ranges
+ * @next__: Iterator variable for the ranges temporay storage
+ * @notifier__: Pointer to the GPU SVM notifier
+ * @start__: Start address of the range
+ * @end__: End address of the range
+ *
+ * This macro is used to iterate over GPU SVM ranges in a notifier while
+ * removing ranges from it.
+ */
+#define drm_gpusvm_for_each_range_safe(range__, next__, notifier__, start__, end__) \
+ for ((range__) = __drm_gpusvm_range_find((notifier__), (start__), (end__)), \
+ (next__) = __drm_gpusvm_range_next(range__); \
+ (range__) && (drm_gpusvm_range_start(range__) < (end__)); \
+ (range__) = (next__), (next__) = __drm_gpusvm_range_next(range__))
+
+/**
+ * __drm_gpusvm_notifier_next() - get the next drm_gpusvm_notifier in the list
+ * @notifier: a pointer to the current drm_gpusvm_notifier
+ *
+ * Return: A pointer to the next drm_gpusvm_notifier if available, or NULL if
+ * the current notifier is the last one or if the input notifier is
+ * NULL.
+ */
+static inline struct drm_gpusvm_notifier *
+__drm_gpusvm_notifier_next(struct drm_gpusvm_notifier *notifier)
+{
+ if (notifier && !list_is_last(¬ifier->entry,
+ ¬ifier->gpusvm->notifier_list))
+ return list_next_entry(notifier, entry);
+
+ return NULL;
+}
+
+static inline struct drm_gpusvm_notifier *
+notifier_iter_first(struct rb_root_cached *root, unsigned long start,
+ unsigned long last)
+{
+ struct interval_tree_node *itree;
+
+ itree = interval_tree_iter_first(root, start, last);
+
+ if (itree)
+ return container_of(itree, struct drm_gpusvm_notifier, itree);
+ else
+ return NULL;
+}
+
+/**
+ * drm_gpusvm_for_each_notifier() - Iterate over GPU SVM notifiers in a gpusvm
+ * @notifier__: Iterator variable for the notifiers
+ * @notifier__: Pointer to the GPU SVM notifier
+ * @start__: Start address of the notifier
+ * @end__: End address of the notifier
+ *
+ * This macro is used to iterate over GPU SVM notifiers in a gpusvm.
+ */
+#define drm_gpusvm_for_each_notifier(notifier__, gpusvm__, start__, end__) \
+ for ((notifier__) = notifier_iter_first(&(gpusvm__)->root, (start__), (end__) - 1); \
+ (notifier__) && (drm_gpusvm_notifier_start(notifier__) < (end__)); \
+ (notifier__) = __drm_gpusvm_notifier_next(notifier__))
+
+/**
+ * drm_gpusvm_for_each_notifier_safe() - Safely iterate over GPU SVM notifiers in a gpusvm
+ * @notifier__: Iterator variable for the notifiers
+ * @next__: Iterator variable for the notifiers temporay storage
+ * @notifier__: Pointer to the GPU SVM notifier
+ * @start__: Start address of the notifier
+ * @end__: End address of the notifier
+ *
+ * This macro is used to iterate over GPU SVM notifiers in a gpusvm while
+ * removing notifiers from it.
+ */
+#define drm_gpusvm_for_each_notifier_safe(notifier__, next__, gpusvm__, start__, end__) \
+ for ((notifier__) = notifier_iter_first(&(gpusvm__)->root, (start__), (end__) - 1), \
+ (next__) = __drm_gpusvm_notifier_next(notifier__); \
+ (notifier__) && (drm_gpusvm_notifier_start(notifier__) < (end__)); \
+ (notifier__) = (next__), (next__) = __drm_gpusvm_notifier_next(notifier__))
+
#endif /* __DRM_GPUSVM_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 19/29] drm/xe/svm: Split system allocator vma incase of madvise call
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (17 preceding siblings ...)
2025-03-14 8:02 ` [RFC 18/29] drm/gpusvm: Make drm_gpusvm_for_each_* macros public Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 20/29] drm/xe: Implement madvise ioctl for xe Himal Prasad Ghimiray
` (10 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
If the start or end of input address range lies within system allocator
vma split the vma to create new vma's as per input range.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 79 ++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_vm.h | 2 +
2 files changed, 81 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index b892b43d6665..b24bd078aeec 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -4093,3 +4093,82 @@ void xe_vm_snapshot_free(struct xe_vm_snapshot *snap)
}
kvfree(snap);
}
+
+int xe_vm_alloc_madvise_vma(struct xe_vm *vm, uint64_t start, uint64_t range)
+{
+ struct xe_vma_ops vops;
+ struct drm_gpuva_ops *ops = NULL;
+ struct drm_gpuva_op *__op;
+ bool is_cpu_addr_mirror = false;
+ int err;
+
+ vm_dbg(&vm->xe->drm, "MADVISE IN: addr=0x%016llx, size=0x%016llx", start, range);
+
+ if (start & ~PAGE_MASK)
+ start = ALIGN_DOWN(start, SZ_4K);
+
+ if (range & ~PAGE_MASK)
+ range = ALIGN(range, SZ_4K);
+
+ vm_dbg(&vm->xe->drm, "MADVISE_OPS_CREATE: addr=0x%016llx, size=0x%016llx", start, range);
+ ops = drm_gpuvm_madvise_ops_create(&vm->gpuvm, start, range, true, start);
+ if (!ops)
+ return 0;
+
+ if (IS_ERR(ops)) {
+ err = PTR_ERR(ops);
+ goto unwind_ops;
+ }
+
+ drm_gpuva_for_each_op(__op, ops) {
+ struct xe_vma_op *op = gpuva_op_to_vma_op(__op);
+
+ if (__op->op == DRM_GPUVA_OP_REMAP) {
+ 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_MAP)
+ op->map.is_cpu_addr_mirror = is_cpu_addr_mirror;
+
+ print_op(vm->xe, __op);
+ }
+
+ xe_vma_ops_init(&vops, vm, NULL, NULL, 0);
+ err = vm_bind_ioctl_ops_parse(vm, ops, &vops);
+ if (err)
+ goto unwind_ops;
+
+ xe_vm_lock(vm, false);
+
+ drm_gpuva_for_each_op(__op, ops) {
+ struct xe_vma_op *op = gpuva_op_to_vma_op(__op);
+ struct xe_vma *vma;
+ struct xe_vma_mem_attr temp_attr;
+
+ if (__op->op == DRM_GPUVA_OP_UNMAP) {
+ /* There should be no unmap */
+ xe_assert(vm->xe, true);
+ xe_vma_destroy(gpuva_to_vma(op->base.unmap.va), NULL);
+ } else if (__op->op == DRM_GPUVA_OP_REMAP) {
+ vma = gpuva_to_vma(op->base.remap.unmap->va);
+ cp_mem_attr(&temp_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;
+ cp_mem_attr(&vma->attr, &temp_attr);
+ }
+ }
+
+ xe_vm_unlock(vm);
+ drm_gpuva_ops_free(&vm->gpuvm, ops);
+ return 0;
+
+unwind_ops:
+ vm_bind_ioctl_ops_unwind(vm, &ops, 1);
+ if (ops)
+ drm_gpuva_ops_free(&vm->gpuvm, ops);
+ return err;
+}
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 99e164852f63..4e45230b7205 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -171,6 +171,8 @@ static inline bool xe_vma_is_userptr(struct xe_vma *vma)
struct xe_vma *xe_vm_find_vma_by_addr(struct xe_vm *vm, u64 page_addr);
+int xe_vm_alloc_madvise_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
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 20/29] drm/xe: Implement madvise ioctl for xe
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (18 preceding siblings ...)
2025-03-14 8:02 ` [RFC 19/29] drm/xe/svm: Split system allocator vma incase of madvise call Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 21/29] drm/xe: Allow CPU address mirror VMA unbind with gpu bindings for madvise Himal Prasad Ghimiray
` (9 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
This driver-specific ioctl enables UMDs to control the memory attributes
for GPU VMAs within a specified input range. If the start or end
addresses fall within an existing VMA, the VMA is split accordingly. The
attributes of the VMA are modified as provided by the users. The old
mappings of the VMAs are invalidated, and TLB invalidation is performed
if necessary.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/Makefile | 1 +
drivers/gpu/drm/xe/xe_device.c | 2 +
drivers/gpu/drm/xe/xe_vm_madvise.c | 309 +++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_vm_madvise.h | 15 ++
4 files changed, 327 insertions(+)
create mode 100644 drivers/gpu/drm/xe/xe_vm_madvise.c
create mode 100644 drivers/gpu/drm/xe/xe_vm_madvise.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 75a79390a0e3..ec7a3edf467a 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -116,6 +116,7 @@ xe-y += xe_bb.o \
xe_uc.o \
xe_uc_fw.o \
xe_vm.o \
+ xe_vm_madvise.o \
xe_vram.o \
xe_vram_freq.o \
xe_vsec.o \
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 2f7d727c9392..91687679cf14 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -57,6 +57,7 @@
#include "xe_ttm_stolen_mgr.h"
#include "xe_ttm_sys_mgr.h"
#include "xe_vm.h"
+#include "xe_vm_madvise.h"
#include "xe_vram.h"
#include "xe_vsec.h"
#include "xe_wait_user_fence.h"
@@ -193,6 +194,7 @@ static const struct drm_ioctl_desc xe_ioctls[] = {
DRM_IOCTL_DEF_DRV(XE_WAIT_USER_FENCE, xe_wait_user_fence_ioctl,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(XE_MADVISE, xe_vm_madvise_ioctl, DRM_RENDER_ALLOW),
};
static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
new file mode 100644
index 000000000000..ef50031649e0
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include "xe_vm_madvise.h"
+
+#include <linux/nospec.h>
+#include <drm/ttm/ttm_tt.h>
+#include <drm/xe_drm.h>
+
+#include "xe_bo.h"
+#include "xe_gt_tlb_invalidation.h"
+#include "xe_pt.h"
+#include "xe_svm.h"
+
+static struct xe_vma **get_vmas(struct xe_vm *vm, int *num_vmas,
+ u64 addr, u64 range)
+{
+ struct xe_vma **vmas, **__vmas;
+ struct drm_gpuva *gpuva;
+ int max_vmas = 8;
+
+ lockdep_assert_held(&vm->lock);
+
+ *num_vmas = 0;
+ vmas = kmalloc_array(max_vmas, sizeof(*vmas), GFP_KERNEL);
+ if (!vmas)
+ return NULL;
+
+ vm_dbg(&vm->xe->drm, "VMA's in range: start=0x%016llx, end=0x%016llx", addr, addr + range);
+
+ drm_gpuvm_for_each_va_range(gpuva, &vm->gpuvm, addr, addr + range) {
+ struct xe_vma *vma = gpuva_to_vma(gpuva);
+
+ if (*num_vmas == max_vmas) {
+ max_vmas <<= 1;
+ __vmas = krealloc(vmas, max_vmas * sizeof(*vmas), GFP_KERNEL);
+ if (!__vmas) {
+ kfree(vmas);
+ return NULL;
+ }
+ vmas = __vmas;
+ }
+
+ vmas[*num_vmas] = vma;
+ (*num_vmas)++;
+ }
+
+ vm_dbg(&vm->xe->drm, "*num_vmas = %d\n", *num_vmas);
+
+ if (!*num_vmas) {
+ kfree(vmas);
+ return NULL;
+ }
+
+ return vmas;
+}
+
+static int madvise_preferred_mem_loc(struct xe_device *xe, struct xe_vm *vm,
+ struct xe_vma **vmas, int num_vmas,
+ struct drm_xe_madvise_ops ops)
+{
+ /* Implementation pending */
+ return 0;
+}
+
+static int madvise_atomic(struct xe_device *xe, struct xe_vm *vm,
+ struct xe_vma **vmas, int num_vmas,
+ struct drm_xe_madvise_ops ops)
+{
+ /* Implementation pending */
+ return 0;
+}
+
+static int madvise_pat_index(struct xe_device *xe, struct xe_vm *vm,
+ struct xe_vma **vmas, int num_vmas,
+ struct drm_xe_madvise_ops ops)
+{
+ /* Implementation pending */
+ return 0;
+}
+
+static int madvise_purgeable_state(struct xe_device *xe, struct xe_vm *vm,
+ struct xe_vma **vmas, int num_vmas,
+ struct drm_xe_madvise_ops ops)
+{
+ /* Implementation pending */
+ return 0;
+}
+
+typedef int (*madvise_func)(struct xe_device *xe, struct xe_vm *vm,
+ struct xe_vma **vmas, int num_vmas, struct drm_xe_madvise_ops ops);
+
+static const madvise_func madvise_funcs[] = {
+ [DRM_XE_VMA_ATTR_PREFERRED_LOC] = madvise_preferred_mem_loc,
+ [DRM_XE_VMA_ATTR_ATOMIC] = madvise_atomic,
+ [DRM_XE_VMA_ATTR_PAT] = madvise_pat_index,
+ [DRM_XE_VMA_ATTR_PURGEABLE_STATE] = madvise_purgeable_state,
+};
+
+static void xe_zap_ptes_in_madvise_range(struct xe_vm *vm, u64 start, u64 end, u8 *tile_mask)
+{
+ struct drm_gpusvm_notifier *notifier;
+ struct drm_gpuva *gpuva;
+ struct xe_svm_range *range;
+ struct xe_tile *tile;
+ u64 adj_start, adj_end;
+ u8 id;
+
+ lockdep_assert_held(&vm->lock);
+
+ if (dma_resv_wait_timeout(xe_vm_resv(vm), DMA_RESV_USAGE_BOOKKEEP,
+ false, MAX_SCHEDULE_TIMEOUT) <= 0)
+ XE_WARN_ON(1);
+
+ down_write(&vm->svm.gpusvm.notifier_lock);
+
+ drm_gpusvm_for_each_notifier(notifier, &vm->svm.gpusvm, start, end) {
+ struct drm_gpusvm_range *r = NULL;
+
+ adj_start = max(start, notifier->itree.start);
+ adj_end = min(end, notifier->itree.last + 1);
+ drm_gpusvm_for_each_range(r, notifier, adj_start, adj_end) {
+ range = to_xe_range(r);
+ for_each_tile(tile, vm->xe, id) {
+ if (xe_pt_zap_ptes_range(tile, vm, range)) {
+ *tile_mask |= BIT(id);
+ range->tile_invalidated |= BIT(id);
+ }
+ }
+ }
+ }
+
+ up_write(&vm->svm.gpusvm.notifier_lock);
+
+ drm_gpuvm_for_each_va_range(gpuva, &vm->gpuvm, start, end) {
+ struct xe_vma *vma = gpuva_to_vma(gpuva);
+
+ if (xe_vma_is_cpu_addr_mirror(vma))
+ continue;
+
+ if (xe_vma_is_userptr(vma)) {
+ WARN_ON_ONCE(!mmu_interval_check_retry
+ (&to_userptr_vma(vma)->userptr.notifier,
+ to_userptr_vma(vma)->userptr.notifier_seq));
+
+ WARN_ON_ONCE(!dma_resv_test_signaled(xe_vm_resv(xe_vma_vm(vma)),
+ DMA_RESV_USAGE_BOOKKEEP));
+ }
+
+ if (xe_vma_bo(vma))
+ xe_bo_lock(xe_vma_bo(vma), false);
+
+ for_each_tile(tile, vm->xe, id) {
+ if (xe_pt_zap_ptes(tile, vma))
+ *tile_mask |= BIT(id);
+ }
+
+ if (xe_vma_bo(vma))
+ xe_bo_unlock(xe_vma_bo(vma));
+ }
+}
+
+static void xe_vm_invalidate_madvise_range(struct xe_vm *vm, u64 start, u64 end)
+{
+ struct xe_gt_tlb_invalidation_fence
+ fence[XE_MAX_TILES_PER_DEVICE * XE_MAX_GT_PER_TILE];
+ struct xe_tile *tile;
+ u32 fence_id = 0;
+ u8 tile_mask = 0;
+ u8 id;
+
+ xe_zap_ptes_in_madvise_range(vm, start, end, &tile_mask);
+ if (!tile_mask)
+ return;
+
+ xe_device_wmb(vm->xe);
+
+ for_each_tile(tile, vm->xe, id) {
+ if (tile_mask & BIT(id)) {
+ int err;
+
+ xe_gt_tlb_invalidation_fence_init(tile->primary_gt,
+ &fence[fence_id], true);
+
+ err = xe_gt_tlb_invalidation_range(tile->primary_gt,
+ &fence[fence_id],
+ start,
+ end,
+ vm->usm.asid);
+ if (WARN_ON_ONCE(err < 0))
+ goto wait;
+ ++fence_id;
+
+ if (!tile->media_gt)
+ continue;
+
+ xe_gt_tlb_invalidation_fence_init(tile->media_gt,
+ &fence[fence_id], true);
+
+ err = xe_gt_tlb_invalidation_range(tile->media_gt,
+ &fence[fence_id],
+ start,
+ end,
+ vm->usm.asid);
+ if (WARN_ON_ONCE(err < 0))
+ goto wait;
+ ++fence_id;
+ }
+ }
+
+wait:
+ for (id = 0; id < fence_id; ++id)
+ xe_gt_tlb_invalidation_fence_wait(&fence[id]);
+}
+
+static int input_ranges_same(struct drm_xe_madvise_ops *old,
+ struct drm_xe_madvise_ops *new)
+{
+ return (new->start == old->start && new->range == old->range);
+}
+
+int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct xe_device *xe = to_xe_device(dev);
+ struct xe_file *xef = to_xe_file(file);
+ struct drm_xe_madvise_ops *advs_ops;
+ struct drm_xe_madvise *args = data;
+ struct xe_vm *vm;
+ struct xe_vma **vmas = NULL;
+ int num_vmas, err = 0;
+ int i, j, attr_type;
+
+ if (XE_IOCTL_DBG(xe, args->num_ops < 1))
+ return -EINVAL;
+
+ vm = xe_vm_lookup(xef, args->vm_id);
+ if (XE_IOCTL_DBG(xe, !vm))
+ return -EINVAL;
+
+ if (XE_IOCTL_DBG(xe, !xe_vm_in_fault_mode(vm))) {
+ err = -EINVAL;
+ goto put_vm;
+ }
+
+ down_write(&vm->lock);
+
+ if (XE_IOCTL_DBG(xe, xe_vm_is_closed_or_banned(vm))) {
+ err = -ENOENT;
+ goto unlock_vm;
+ }
+
+ if (args->num_ops > 1) {
+ u64 __user *madvise_user = u64_to_user_ptr(args->vector_of_ops);
+
+ advs_ops = kvmalloc_array(args->num_ops, sizeof(struct drm_xe_madvise_ops),
+ GFP_KERNEL | __GFP_ACCOUNT |
+ __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
+ if (!advs_ops)
+ return args->num_ops > 1 ? -ENOBUFS : -ENOMEM;
+
+ err = __copy_from_user(advs_ops, madvise_user,
+ sizeof(struct drm_xe_madvise_ops) *
+ args->num_ops);
+ if (XE_IOCTL_DBG(xe, err)) {
+ err = -EFAULT;
+ goto free_advs_ops;
+ }
+ } else {
+ advs_ops = &args->ops;
+ }
+
+ for (i = 0; i < args->num_ops; i++) {
+ xe_vm_alloc_madvise_vma(vm, advs_ops[i].start, advs_ops[i].range);
+
+ vmas = get_vmas(vm, &num_vmas, advs_ops[i].start, advs_ops[i].range);
+ if (!vmas) {
+ err = -ENOMEM;
+ goto unlock_vm;
+ }
+
+ attr_type = array_index_nospec(advs_ops[i].type, ARRAY_SIZE(madvise_funcs));
+ err = madvise_funcs[attr_type](xe, vm, vmas, num_vmas, advs_ops[i]);
+
+ kfree(vmas);
+ vmas = NULL;
+
+ if (err)
+ break;
+ }
+
+ for (i = 0; i < args->num_ops; i++) {
+ for (j = i + 1; j < args->num_ops; ++j) {
+ if (input_ranges_same(&advs_ops[j], &advs_ops[i]))
+ break;
+ }
+ xe_vm_invalidate_madvise_range(vm, advs_ops[i].start,
+ advs_ops[i].start + advs_ops[i].range);
+ }
+free_advs_ops:
+ if (args->num_ops > 1)
+ kvfree(advs_ops);
+unlock_vm:
+ up_write(&vm->lock);
+put_vm:
+ xe_vm_put(vm);
+ return err;
+}
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.h b/drivers/gpu/drm/xe/xe_vm_madvise.h
new file mode 100644
index 000000000000..c5cdd058c322
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef _XE_VM_MADVISE_H_
+#define _XE_VM_MADVISE_H_
+
+struct drm_device;
+struct drm_file;
+
+int xe_vm_madvise_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
+
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 21/29] drm/xe: Allow CPU address mirror VMA unbind with gpu bindings for madvise
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (19 preceding siblings ...)
2025-03-14 8:02 ` [RFC 20/29] drm/xe: Implement madvise ioctl for xe Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 22/29] drm/xe/svm : Add svm ranges migration policy on atomic access Himal Prasad Ghimiray
` (8 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
In the case of the MADVISE ioctl, if the start or end addresses fall
within a VMA and existing SVM ranges are present, remove the existing
SVM mappings. Then, continue with ops_parse to create new VMAs by REMAP
unmapping of old one.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_svm.c | 25 +++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_svm.h | 7 +++++++
drivers/gpu/drm/xe/xe_vm.c | 18 +++++++++++++++++-
3 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index 5a4cb14d608e..b181b9bbfa5e 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -821,6 +821,31 @@ bool xe_svm_has_mapping(struct xe_vm *vm, u64 start, u64 end)
return drm_gpusvm_has_mapping(&vm->svm.gpusvm, start, end);
}
+/**
+ * xe_svm_range_clean_if_addr_within - Clean SVM mappings and ranges
+ * @start: start addr
+ * @end: end addr
+ *
+ * This function cleans up svm ranges if start or end address are inside them.
+ */
+void xe_svm_range_clean_if_addr_within(struct xe_vm *vm, u64 start, u64 end)
+{
+ struct drm_gpusvm_notifier *notifier, *next;
+
+ drm_gpusvm_for_each_notifier_safe(notifier, next, &vm->svm.gpusvm, start, end) {
+ struct drm_gpusvm_range *range, *__next;
+
+ drm_gpusvm_for_each_range_safe(range, __next, notifier, start, end) {
+ if (start > drm_gpusvm_range_start(range) ||
+ end < drm_gpusvm_range_end(range)) {
+ if (IS_DGFX(vm->xe) && xe_svm_range_in_vram(to_xe_range(range)))
+ drm_gpusvm_range_evict(&vm->svm.gpusvm, range);
+ __xe_svm_garbage_collector(vm, to_xe_range(range));
+ }
+ }
+ }
+}
+
/**
* xe_svm_bo_evict() - SVM evict BO to system memory
* @bo: BO to evict
diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
index 6bb358bf62ad..d57d7cc851ee 100644
--- a/drivers/gpu/drm/xe/xe_svm.h
+++ b/drivers/gpu/drm/xe/xe_svm.h
@@ -82,6 +82,8 @@ struct xe_svm_range *xe_svm_range_find_or_insert(struct xe_vm *vm, u64 addr,
int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
struct drm_gpusvm_ctx *ctx);
+
+void xe_svm_range_clean_if_addr_within(struct xe_vm *vm, u64 start, u64 end);
#else
static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
{
@@ -157,6 +159,11 @@ int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
return -EINVAL;
}
+static inline
+void xe_svm_range_clean_if_addr_within(struct xe_vm *vm, u64 start, u64 end)
+{
+}
+
#endif
/**
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index b24bd078aeec..f3e9c3f31fe7 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2341,6 +2341,22 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR;
op->map.dumpable = flags & DRM_XE_VM_BIND_FLAG_DUMPABLE;
op->map.pat_index = pat_index;
+ } else if (__op->op == DRM_GPUVA_OP_REMAP) {
+ struct xe_vma *old =
+ gpuva_to_vma(op->base.remap.unmap->va);
+ u64 start = xe_vma_start(old), end = xe_vma_end(old);
+
+ if (op->base.remap.prev)
+ start = op->base.remap.prev->va.addr +
+ op->base.remap.prev->va.range;
+ if (op->base.remap.next)
+ end = op->base.remap.next->va.addr;
+
+ if (xe_vma_is_cpu_addr_mirror(old) &&
+ xe_svm_has_mapping(vm, start, end)) {
+ drm_gpuva_ops_free(&vm->gpuvm, ops);
+ return ERR_PTR(-EBUSY);
+ }
} else if (__op->op == DRM_GPUVA_OP_PREFETCH) {
struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va);
@@ -2621,7 +2637,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
if (xe_vma_is_cpu_addr_mirror(old) &&
xe_svm_has_mapping(vm, start, end))
- return -EBUSY;
+ xe_svm_range_clean_if_addr_within(vm, start, end);
op->remap.start = xe_vma_start(old);
op->remap.range = xe_vma_size(old);
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 22/29] drm/xe/svm : Add svm ranges migration policy on atomic access
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (20 preceding siblings ...)
2025-03-14 8:02 ` [RFC 21/29] drm/xe: Allow CPU address mirror VMA unbind with gpu bindings for madvise Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 23/29] drm/xe/madvise: Update migration policy based on preferred location Himal Prasad Ghimiray
` (7 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
If the platform does not support atomic access on system memory, and the
ranges are in system memory, but the user requires atomic accesses on
the VMA, then migrate the ranges to VRAM. Apply this policy for prefetch
operations as well.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_pt.c | 3 +-
drivers/gpu/drm/xe/xe_svm.c | 85 ++++++++++++++++++++++++++----
drivers/gpu/drm/xe/xe_svm.h | 10 ++++
drivers/gpu/drm/xe/xe_vm.c | 5 +-
drivers/gpu/drm/xe/xe_vm_madvise.c | 11 +++-
5 files changed, 101 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index d51f7d1c86cf..88ceff3250e3 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -700,7 +700,8 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
* gets migrated to LMEM, bind such allocations with
* device atomics enabled.
*/
- else if (is_devmem)
+ else if (is_devmem || (xe->info.has_device_atomics_on_smem &&
+ vma->attr.atomic_access == DRM_XE_VMA_ATOMIC_DEVICE))
xe_walk.default_pte |= XE_USM_PPGTT_PTE_AE;
} else {
xe_walk.default_pte |= XE_USM_PPGTT_PTE_AE;
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index b181b9bbfa5e..cb876000411f 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -689,6 +689,62 @@ int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
return err;
}
+static bool migrate_to_support_atomic(struct xe_device *xe, struct xe_vma *vma)
+{
+ if (vma->attr.atomic_access == DRM_XE_VMA_ATOMIC_UNDEFINED ||
+ (xe->info.has_device_atomics_on_smem &&
+ vma->attr.atomic_access == DRM_XE_VMA_ATOMIC_DEVICE))
+ return false;
+
+ return true;
+}
+
+static bool supports_4K_migration(struct xe_device *xe)
+{
+ if (xe->info.platform == XE_BATTLEMAGE)
+ return true;
+
+ return false;
+}
+
+/**
+ * xe_svm_range_needs_migrate_to_vram() - SVM range needs migrate to VRAM or not
+ * @range: SVM range for which migration needs to be decided
+ * @vma: vma which has range
+ * @region: default placement for range
+ *
+ * Return: True for range needing migration and migration is supported else false
+ */
+bool xe_svm_range_needs_migrate_to_vram(struct xe_svm_range *range, struct xe_vma *vma,
+ u32 region)
+{
+ struct xe_vm *vm = range_to_vm(&range->base);
+ u64 range_size = xe_svm_range_size(range);
+ bool needs_migrate = false;
+
+ if (!range->base.flags.migrate_devmem)
+ return false;
+
+ needs_migrate = migrate_to_support_atomic(vm->xe, vma) || region;
+
+ if (needs_migrate && !IS_DGFX(vm->xe)) {
+ drm_warn(&vm->xe->drm, "Platform doesn't support VRAM\n");
+ return false;
+ }
+
+ if (needs_migrate && xe_svm_range_in_vram(range)) {
+ drm_info(&vm->xe->drm, "Range is already in VRAM\n");
+ return false;
+ }
+
+ if (needs_migrate && range_size <= SZ_64K && !supports_4K_migration(vm->xe)) {
+ drm_warn(&vm->xe->drm, "Platform doesn't support SZ_4K range migration\n");
+ return false;
+ }
+
+ return needs_migrate;
+}
+
/**
* xe_svm_handle_pagefault() - SVM handle page fault
* @vm: The VM.
@@ -718,6 +774,8 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
struct dma_fence *fence;
ktime_t end = 0;
int err;
+ int migrate_try_count = 3;
+ u32 region;
lockdep_assert_held_write(&vm->lock);
xe_assert(vm->xe, xe_vma_is_cpu_addr_mirror(vma));
@@ -738,18 +796,27 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
range_debug(range, "PAGE FAULT");
- /* XXX: Add migration policy, for now migrate range once */
- if (!range->skip_migrate && range->base.flags.migrate_devmem &&
- xe_svm_range_size(range) >= SZ_64K) {
- range->skip_migrate = true;
+ /* for gpu pagefault always migrate to local vram unless
+ * preferred location provided by madvise
+ */
+ region = 1;
+
+ if (xe_svm_range_needs_migrate_to_vram(range, vma, region)) {
+ migrate_try_count--;
err = xe_svm_alloc_vram(vm, tile, range, &ctx);
if (err) {
- drm_dbg(&vm->xe->drm,
- "VRAM allocation failed, falling back to "
- "retrying fault, asid=%u, errno=%pe\n",
- vm->usm.asid, ERR_PTR(err));
- goto retry;
+ if (migrate_try_count) {
+ drm_dbg(&vm->xe->drm,
+ "VRAM allocation failed, falling back to retrying fault, asid=%u, errno=%pe\n",
+ vm->usm.asid, ERR_PTR(err));
+ goto retry;
+ } else {
+ drm_err(&vm->xe->drm,
+ "VRAM allocation failed, retry count exceeded, asid=%u, errno=%pe\n",
+ vm->usm.asid, ERR_PTR(err));
+ return err;
+ }
}
}
diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h
index d57d7cc851ee..da14a0e2344c 100644
--- a/drivers/gpu/drm/xe/xe_svm.h
+++ b/drivers/gpu/drm/xe/xe_svm.h
@@ -84,6 +84,9 @@ int xe_svm_range_get_pages(struct xe_vm *vm, struct xe_svm_range *range,
struct drm_gpusvm_ctx *ctx);
void xe_svm_range_clean_if_addr_within(struct xe_vm *vm, u64 start, u64 end);
+
+bool xe_svm_range_needs_migrate_to_vram(struct xe_svm_range *range, struct xe_vma *vma,
+ u32 prefetch_region);
#else
static inline bool xe_svm_range_pages_valid(struct xe_svm_range *range)
{
@@ -164,6 +167,13 @@ void xe_svm_range_clean_if_addr_within(struct xe_vm *vm, u64 start, u64 end)
{
}
+static inline
+bool xe_svm_range_needs_migrate_to_vram(struct xe_svm_range *range, struct xe_vma *vma,
+ u32 prefetch_region)
+{
+ return false;
+}
+
#endif
/**
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index f3e9c3f31fe7..5e36975258a3 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2895,8 +2895,9 @@ static int prefetch_ranges_lock_and_prep(struct xe_vm *vm,
/* TODO: Threading the migration */
for (i = 0; i < op->prefetch_range.ranges_count; i++) {
svm_range = xa_load(&op->prefetch_range.range, i);
- if (region && svm_range->base.flags.migrate_devmem &&
- xe_svm_range_size(svm_range) >= SZ_64K) {
+
+ if (xe_svm_range_needs_migrate_to_vram(svm_range, vma, region)) {
+ region = region ? region : 1;
tile = &vm->xe->tiles[region_to_mem_type[region] - XE_PL_VRAM0];
err = xe_svm_alloc_vram(vm, tile, svm_range, &ctx);
if (err) {
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index ef50031649e0..7e1a95106cb9 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -69,7 +69,16 @@ static int madvise_atomic(struct xe_device *xe, struct xe_vm *vm,
struct xe_vma **vmas, int num_vmas,
struct drm_xe_madvise_ops ops)
{
- /* Implementation pending */
+ int i;
+
+ xe_assert(vm->xe, ops.type == DRM_XE_VMA_ATTR_ATOMIC);
+ xe_assert(vm->xe, ops.atomic.val > DRM_XE_VMA_ATOMIC_UNDEFINED &&
+ ops.atomic.val <= DRM_XE_VMA_ATOMIC_CPU);
+ vm_dbg(&xe->drm, "attr_value = %d", ops.atomic.val);
+
+ for (i = 0; i < num_vmas; i++)
+ vmas[i]->attr.atomic_access = ops.atomic.val;
+ /*TODO: handle bo backed vmas */
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 23/29] drm/xe/madvise: Update migration policy based on preferred location
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (21 preceding siblings ...)
2025-03-14 8:02 ` [RFC 22/29] drm/xe/svm : Add svm ranges migration policy on atomic access Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 24/29] drm/xe/svm: Support DRM_XE_SVM_ATTR_PAT memory attribute Himal Prasad Ghimiray
` (6 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
When the user sets the valid devmem_fd as a preferred location, GPU fault
will trigger migration to tile of device associated with devmem_fd.
If the user sets an invalid devmem_fd the preferred location is current
placement only.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_svm.c | 14 ++++++++++----
drivers/gpu/drm/xe/xe_vm.h | 3 +++
drivers/gpu/drm/xe/xe_vm_madvise.c | 20 +++++++++++++++++++-
3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index cb876000411f..ed7f0cfbb546 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -745,6 +745,12 @@ bool xe_svm_range_needs_migrate_to_vram(struct xe_svm_range *range, struct xe_vm
return needs_migrate;
}
+static const u32 region_to_mem_type[] = {
+ XE_PL_TT,
+ XE_PL_VRAM0,
+ XE_PL_VRAM1,
+};
+
/**
* xe_svm_handle_pagefault() - SVM handle page fault
* @vm: The VM.
@@ -796,13 +802,13 @@ int xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
range_debug(range, "PAGE FAULT");
- /* for gpu pagefault always migrate to local vram unless
- * preferred location provided by madvise
- */
- region = 1;
+ region = vma->attr.preferred_loc.devmem_fd;
if (xe_svm_range_needs_migrate_to_vram(range, vma, region)) {
migrate_try_count--;
+ region = region ? region : 1;
+ /* Need rework for multigpu */
+ tile = &vm->xe->tiles[region_to_mem_type[region] - XE_PL_VRAM0];
err = xe_svm_alloc_vram(vm, tile, range, &ctx);
if (err) {
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 4e45230b7205..377f62f859b7 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -220,6 +220,9 @@ int __xe_vm_userptr_needs_repin(struct xe_vm *vm);
int xe_vm_userptr_check_repin(struct xe_vm *vm);
+bool xe_vma_has_preferred_mem_loc(struct xe_vma *vma,
+ u32 *mem_region, u32 *devmem_fd);
+
int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker);
struct dma_fence *xe_vma_rebind(struct xe_vm *vm, struct xe_vma *vma,
u8 tile_mask);
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index 7e1a95106cb9..f870e8642190 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -61,7 +61,25 @@ static int madvise_preferred_mem_loc(struct xe_device *xe, struct xe_vm *vm,
struct xe_vma **vmas, int num_vmas,
struct drm_xe_madvise_ops ops)
{
- /* Implementation pending */
+ s32 devmem_fd;
+ u32 migration_policy;
+ int i;
+
+ xe_assert(vm->xe, ops.type == DRM_XE_VMA_ATTR_PREFERRED_LOC);
+ vm_dbg(&xe->drm, "migration policy = %d, devmem_fd = %d\n",
+ ops.preferred_mem_loc.migration_policy,
+ ops.preferred_mem_loc.devmem_fd);
+
+ devmem_fd = (s32)ops.preferred_mem_loc.devmem_fd;
+ devmem_fd = (devmem_fd < 0) ? 0 : devmem_fd;
+
+ migration_policy = ops.preferred_mem_loc.migration_policy;
+
+ for (i = 0; i < num_vmas; i++) {
+ vmas[i]->attr.preferred_loc.devmem_fd = devmem_fd;
+ vmas[i]->attr.preferred_loc.migration_policy = migration_policy;
+ }
+
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 24/29] drm/xe/svm: Support DRM_XE_SVM_ATTR_PAT memory attribute
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (22 preceding siblings ...)
2025-03-14 8:02 ` [RFC 23/29] drm/xe/madvise: Update migration policy based on preferred location Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 25/29] drm/xe/uapi: Add flag for consulting madvise hints on svm prefetch Himal Prasad Ghimiray
` (5 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
This attributes sets the pat_index for the svm used vma range, which is
utilized to ascertain the coherence.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm_madvise.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index f870e8642190..f4e0545937b0 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -104,7 +104,14 @@ static int madvise_pat_index(struct xe_device *xe, struct xe_vm *vm,
struct xe_vma **vmas, int num_vmas,
struct drm_xe_madvise_ops ops)
{
- /* Implementation pending */
+ int i;
+
+ xe_assert(vm->xe, ops.type == DRM_XE_VMA_ATTR_PAT);
+ vm_dbg(&xe->drm, "attr_value = %d", ops.pat_index.val);
+
+ for (i = 0; i < num_vmas; i++)
+ vmas[i]->attr.pat_index = ops.pat_index.val;
+
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 25/29] drm/xe/uapi: Add flag for consulting madvise hints on svm prefetch
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (23 preceding siblings ...)
2025-03-14 8:02 ` [RFC 24/29] drm/xe/svm: Support DRM_XE_SVM_ATTR_PAT memory attribute Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-05-14 19:26 ` Matthew Brost
2025-03-14 8:02 ` [RFC 26/29] drm/xe/svm: Consult madvise preferred location in prefetch Himal Prasad Ghimiray
` (4 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Introduce flag DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC to ensure prefetching
in madvise-advised memory regions
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
include/uapi/drm/xe_drm.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 70e79fe35834..f30d0cb5b054 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1107,6 +1107,7 @@ struct drm_xe_vm_bind_op {
/** @flags: Bind flags */
__u32 flags;
+#define DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC -1
/**
* @prefetch_mem_region_instance: Memory region to prefetch VMA to.
* It is a region instance, not a mask.
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 25/29] drm/xe/uapi: Add flag for consulting madvise hints on svm prefetch
2025-03-14 8:02 ` [RFC 25/29] drm/xe/uapi: Add flag for consulting madvise hints on svm prefetch Himal Prasad Ghimiray
@ 2025-05-14 19:26 ` Matthew Brost
0 siblings, 0 replies; 52+ messages in thread
From: Matthew Brost @ 2025-05-14 19:26 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:22PM +0530, Himal Prasad Ghimiray wrote:
> Introduce flag DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC to ensure prefetching
> in madvise-advised memory regions
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> include/uapi/drm/xe_drm.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
> index 70e79fe35834..f30d0cb5b054 100644
> --- a/include/uapi/drm/xe_drm.h
> +++ b/include/uapi/drm/xe_drm.h
> @@ -1107,6 +1107,7 @@ struct drm_xe_vm_bind_op {
> /** @flags: Bind flags */
> __u32 flags;
>
> +#define DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC -1
Kernel doc for this.
Matt
> /**
> * @prefetch_mem_region_instance: Memory region to prefetch VMA to.
> * It is a region instance, not a mask.
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 26/29] drm/xe/svm: Consult madvise preferred location in prefetch
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (24 preceding siblings ...)
2025-03-14 8:02 ` [RFC 25/29] drm/xe/uapi: Add flag for consulting madvise hints on svm prefetch Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 8:02 ` [RFC 27/29] drm/xe/uapi: Add uapi for vma count and mem attributes Himal Prasad Ghimiray
` (3 subsequent siblings)
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
When prefetch region is DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, prefetch svm
ranges to preferred location provided by madvise.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_vm.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 5e36975258a3..36546c82df06 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2890,9 +2890,12 @@ static int prefetch_ranges_lock_and_prep(struct xe_vm *vm,
if (!xe_vma_is_cpu_addr_mirror(vma))
return 0;
- region = op->prefetch_range.region;
+ region = (op->prefetch_range.region == DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC) ?
+ vma->attr.preferred_loc.devmem_fd : op->prefetch_range.region;
- /* TODO: Threading the migration */
+ /* TODO: Threading the migration
+ * TODO: Multigpu support migration
+ */
for (i = 0; i < op->prefetch_range.ranges_count; i++) {
svm_range = xa_load(&op->prefetch_range.range, i);
@@ -2966,7 +2969,8 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
else
region = op->prefetch.region;
- xe_assert(vm->xe, region <= ARRAY_SIZE(region_to_mem_type));
+ xe_assert(vm->xe, region == DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC ||
+ region <= ARRAY_SIZE(region_to_mem_type));
err = vma_lock_and_validate(exec,
gpuva_to_vma(op->base.prefetch.va),
@@ -3391,8 +3395,9 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
op == DRM_XE_VM_BIND_OP_PREFETCH) ||
XE_IOCTL_DBG(xe, prefetch_region &&
op != DRM_XE_VM_BIND_OP_PREFETCH) ||
- XE_IOCTL_DBG(xe, !(BIT(prefetch_region) &
- xe->info.mem_region_mask)) ||
+ XE_IOCTL_DBG(xe, (is_cpu_addr_mirror &&
+ prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC) &&
+ !(BIT(prefetch_region) & xe->info.mem_region_mask)) ||
XE_IOCTL_DBG(xe, obj &&
op == DRM_XE_VM_BIND_OP_UNMAP)) {
err = -EINVAL;
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* [RFC 27/29] drm/xe/uapi: Add uapi for vma count and mem attributes
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (25 preceding siblings ...)
2025-03-14 8:02 ` [RFC 26/29] drm/xe/svm: Consult madvise preferred location in prefetch Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-05-14 19:39 ` Matthew Brost
2025-03-14 8:02 ` [RFC 28/29] drm/xe/bo: Add attributes field to xe_bo Himal Prasad Ghimiray
` (2 subsequent siblings)
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
-DRM_IOCTL_XE_VM_QUERY_VMAS: Return number of VMAs in user-specified range.
-DRM_IOCTL_XE_VM_QUERY_VMAS_ATTRS: Fill VMA attributes in user-provided
buffer.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_device.c | 2 +
drivers/gpu/drm/xe/xe_vm.c | 94 +++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_vm.h | 3 +-
include/uapi/drm/xe_drm.h | 115 +++++++++++++++++++++++++++++++++
4 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 91687679cf14..8ad5e5523e38 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -195,6 +195,8 @@ static const struct drm_ioctl_desc xe_ioctls[] = {
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(XE_MADVISE, xe_vm_madvise_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(XE_VM_QUERY_VMAS, xe_vm_query_vmas_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(XE_VM_QUERY_VMAS_ATTRS, xe_vm_query_vmas_attrs_ioctl, DRM_RENDER_ALLOW),
};
static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 36546c82df06..349481b13546 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -2161,6 +2161,100 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
return err;
}
+int xe_vm_query_vmas_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct xe_device *xe = to_xe_device(dev);
+ struct xe_file *xef = to_xe_file(file);
+ struct drm_xe_vm_query_num_vmas *args = data;
+ struct drm_gpuva *gpuva;
+ struct xe_vm *vm;
+
+ vm = xe_vm_lookup(xef, args->vm_id);
+ if (XE_IOCTL_DBG(xe, !vm))
+ return -EINVAL;
+
+ args->num_vmas = 0;
+ down_write(&vm->lock);
+
+ drm_gpuvm_for_each_va_range(gpuva, &vm->gpuvm, args->start, args->start + args->range)
+ args->num_vmas++;
+
+ up_write(&vm->lock);
+ return 0;
+}
+
+static int get_mem_attrs(struct xe_vm *vm, u32 *num_vmas, u64 start,
+ u64 end, struct drm_xe_vma_mem_attr *mem_attrs)
+{
+ struct drm_gpuva *gpuva;
+ int i = 0;
+
+ lockdep_assert_held(&vm->lock);
+
+ drm_gpuvm_for_each_va_range(gpuva, &vm->gpuvm, start, end) {
+ struct xe_vma *vma = gpuva_to_vma(gpuva);
+
+ if (i == *num_vmas)
+ return -EINVAL;
+
+ mem_attrs[i].start = xe_vma_start(vma);
+ mem_attrs[i].end = xe_vma_end(vma);
+ mem_attrs[i].atomic.val = vma->attr.atomic_access;
+ mem_attrs[i].pat_index.val = vma->attr.pat_index;
+ mem_attrs[i].preferred_mem_loc.devmem_fd = vma->attr.preferred_loc.devmem_fd;
+ mem_attrs[i].preferred_mem_loc.migration_policy = vma->attr.preferred_loc.migration_policy;
+
+ i++;
+ }
+
+ if (i < (*num_vmas - 1))
+ *num_vmas = i;
+ return 0;
+}
+
+int xe_vm_query_vmas_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct xe_device *xe = to_xe_device(dev);
+ struct xe_file *xef = to_xe_file(file);
+ struct drm_xe_vma_mem_attr *mem_attrs;
+ struct drm_xe_vm_query_vmas_attr *args = data;
+ u64 __user *attrs_user = NULL;
+ struct xe_vm *vm;
+ int err;
+
+ if (XE_IOCTL_DBG(xe, args->num_vmas < 1))
+ return -EINVAL;
+
+ vm = xe_vm_lookup(xef, args->vm_id);
+ if (XE_IOCTL_DBG(xe, !vm))
+ return -EINVAL;
+
+ down_write(&vm->lock);
+
+ attrs_user = u64_to_user_ptr(args->vector_of_vma_mem_attr);
+ mem_attrs = kvmalloc_array(args->num_vmas, sizeof(struct drm_xe_vma_mem_attr),
+ GFP_KERNEL | __GFP_ACCOUNT |
+ __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
+ if (!mem_attrs)
+ return args->num_vmas > 1 ? -ENOBUFS : -ENOMEM;
+
+ err = get_mem_attrs(vm, &args->num_vmas, args->start,
+ args->start + args->range, mem_attrs);
+ if (err)
+ goto free_mem_attrs;
+
+ err = __copy_to_user(attrs_user, mem_attrs,
+ sizeof(struct drm_xe_vma_mem_attr) * args->num_vmas);
+
+free_mem_attrs:
+ kvfree(mem_attrs);
+
+ up_write(&vm->lock);
+
+ return err;
+}
+
static bool vma_matches(struct xe_vma *vma, u64 page_addr)
{
if (page_addr > xe_vma_end(vma) - 1 ||
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 377f62f859b7..0b2d6e9f77ef 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -193,7 +193,8 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
int xe_vm_bind_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
-
+int xe_vm_query_vmas_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+int xe_vm_query_vmas_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
void xe_vm_close_and_put(struct xe_vm *vm);
static inline bool xe_vm_in_fault_mode(struct xe_vm *vm)
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index f30d0cb5b054..68c447db9f2e 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -82,6 +82,8 @@ extern "C" {
* - &DRM_IOCTL_XE_WAIT_USER_FENCE
* - &DRM_IOCTL_XE_OBSERVATION
* - &DRM_IOCTL_XE_MADVISE
+ * - &DRM_IOCTL_XE_VM_QUERY_VMAS
+ * - &DRM_IOCTL_XE_VM_QUERY_VMAS_ATTRS
*/
/*
@@ -104,6 +106,8 @@ extern "C" {
#define DRM_XE_WAIT_USER_FENCE 0x0a
#define DRM_XE_OBSERVATION 0x0b
#define DRM_XE_MADVISE 0x0c
+#define DRM_XE_VM_QUERY_VMAS 0x0d
+#define DRM_XE_VM_QUERY_VMAS_ATTRS 0x0e
/* Must be kept compact -- no holes */
@@ -120,6 +124,8 @@ extern "C" {
#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
#define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
#define DRM_IOCTL_XE_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_MADVISE, struct drm_xe_madvise)
+#define DRM_IOCTL_XE_VM_QUERY_VMAS DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_QUERY_VMAS, struct drm_xe_vm_query_num_vmas)
+#define DRM_IOCTL_XE_VM_QUERY_VMAS_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_QUERY_VMAS_ATTRS, struct drm_xe_vm_query_vmas_attr)
/**
* DOC: Xe IOCTL Extensions
@@ -2059,6 +2065,115 @@ struct drm_xe_madvise {
};
+/**
+ * struct drm_xe_vm_query_num_vmas - Input of &DRM_IOCTL_XE_VM_QUERY_VMAS
+ *
+ * Get number of vmas in virtual range of vm_id
+ */
+struct drm_xe_vm_query_num_vmas {
+ /** @extensions: Pointer to the first extension struct, if any */
+ __u64 extensions;
+
+ /** @vm_id: vm_id of the virtual range */
+ __u32 vm_id;
+
+ /** @num_vmas: number of vmas in range returned in @num_vmas */
+ __u32 num_vmas;
+
+ /** @start: start of the virtual address range */
+ __u64 start;
+
+ /** @size: size of the virtual address range */
+ __u64 range;
+
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+};
+
+struct drm_xe_vma_mem_attr {
+ /** @extensions: Pointer to the first extension struct, if any */
+ __u64 extensions;
+
+ /** @start: start of the vma */
+ __u64 start;
+
+ /** @size: end of the vma */
+ __u64 end;
+
+ struct {
+ struct {
+ /** @val: value of atomic operation*/
+ __u32 val;
+
+ /** @reserved: Reserved */
+ __u32 reserved;
+ } atomic;
+
+ struct {
+ /** @val: value for DRM_XE_VMA_ATTR_PURGEABLE_STATE */
+ __u32 val;
+
+ /** @reserved: Reserved */
+ __u32 reserved;
+ } purge_state_val;
+
+ struct {
+ /** @pat_index */
+ __u32 val;
+
+ /** @reserved: Reserved */
+ __u32 reserved;
+ } pat_index;
+
+ /** @preferred_mem_loc: preferred memory location */
+ struct {
+ __u32 devmem_fd;
+
+ __u32 migration_policy;
+ } preferred_mem_loc;
+ };
+
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+};
+
+/**
+ * struct drm_xe_vm_query_vmas_attr - Input of &DRM_IOCTL_XE_VM_QUERY_MEM_ATTRIBUTES
+ *
+ * Get memory attributes to a virtual address range
+ */
+struct drm_xe_vm_query_vmas_attr {
+ /** @extensions: Pointer to the first extension struct, if any */
+ __u64 extensions;
+
+ /** @vm_id: vm_id of the virtual range */
+ __u32 vm_id;
+
+ /** @num_vmas: number of vmas in range returned in @num_vmas */
+ __u32 num_vmas;
+
+ /** @start: start of the virtual address range */
+ __u64 start;
+
+ /** @size: size of the virtual address range */
+ __u64 range;
+
+ union {
+ /** @num_vmas: used if num_vmas == 1 */
+ struct drm_xe_vma_mem_attr attr;
+
+ /**
+ * @vector_of_ops: userptr to array of struct
+ * drm_xe_vma_mem_attr if num_vmas > 1
+ */
+ __u64 vector_of_vma_mem_attr;
+ };
+
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+
+};
+
#if defined(__cplusplus)
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 27/29] drm/xe/uapi: Add uapi for vma count and mem attributes
2025-03-14 8:02 ` [RFC 27/29] drm/xe/uapi: Add uapi for vma count and mem attributes Himal Prasad Ghimiray
@ 2025-05-14 19:39 ` Matthew Brost
0 siblings, 0 replies; 52+ messages in thread
From: Matthew Brost @ 2025-05-14 19:39 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:24PM +0530, Himal Prasad Ghimiray wrote:
> -DRM_IOCTL_XE_VM_QUERY_VMAS: Return number of VMAs in user-specified range.
> -DRM_IOCTL_XE_VM_QUERY_VMAS_ATTRS: Fill VMA attributes in user-provided
> buffer.
>
I can't remember if landed on if this needed? I thought the answer was,
no not needed.
If it is needed could be make this a single IOCTL. e.g. Call in once
with num_vmas == 0 + NULL vector, IOCTL returns num_vmas, then called
again with num_vmas != 0 + non-NULL vector.
Matt
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> ---
> drivers/gpu/drm/xe/xe_device.c | 2 +
> drivers/gpu/drm/xe/xe_vm.c | 94 +++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_vm.h | 3 +-
> include/uapi/drm/xe_drm.h | 115 +++++++++++++++++++++++++++++++++
> 4 files changed, 213 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> index 91687679cf14..8ad5e5523e38 100644
> --- a/drivers/gpu/drm/xe/xe_device.c
> +++ b/drivers/gpu/drm/xe/xe_device.c
> @@ -195,6 +195,8 @@ static const struct drm_ioctl_desc xe_ioctls[] = {
> DRM_RENDER_ALLOW),
> DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),
> DRM_IOCTL_DEF_DRV(XE_MADVISE, xe_vm_madvise_ioctl, DRM_RENDER_ALLOW),
> + DRM_IOCTL_DEF_DRV(XE_VM_QUERY_VMAS, xe_vm_query_vmas_ioctl, DRM_RENDER_ALLOW),
> + DRM_IOCTL_DEF_DRV(XE_VM_QUERY_VMAS_ATTRS, xe_vm_query_vmas_attrs_ioctl, DRM_RENDER_ALLOW),
> };
>
> static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 36546c82df06..349481b13546 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -2161,6 +2161,100 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
> return err;
> }
>
> +int xe_vm_query_vmas_ioctl(struct drm_device *dev, void *data,
> + struct drm_file *file)
> +{
> + struct xe_device *xe = to_xe_device(dev);
> + struct xe_file *xef = to_xe_file(file);
> + struct drm_xe_vm_query_num_vmas *args = data;
> + struct drm_gpuva *gpuva;
> + struct xe_vm *vm;
> +
> + vm = xe_vm_lookup(xef, args->vm_id);
> + if (XE_IOCTL_DBG(xe, !vm))
> + return -EINVAL;
> +
> + args->num_vmas = 0;
> + down_write(&vm->lock);
> +
> + drm_gpuvm_for_each_va_range(gpuva, &vm->gpuvm, args->start, args->start + args->range)
> + args->num_vmas++;
> +
> + up_write(&vm->lock);
> + return 0;
> +}
> +
> +static int get_mem_attrs(struct xe_vm *vm, u32 *num_vmas, u64 start,
> + u64 end, struct drm_xe_vma_mem_attr *mem_attrs)
> +{
> + struct drm_gpuva *gpuva;
> + int i = 0;
> +
> + lockdep_assert_held(&vm->lock);
> +
> + drm_gpuvm_for_each_va_range(gpuva, &vm->gpuvm, start, end) {
> + struct xe_vma *vma = gpuva_to_vma(gpuva);
> +
> + if (i == *num_vmas)
> + return -EINVAL;
> +
> + mem_attrs[i].start = xe_vma_start(vma);
> + mem_attrs[i].end = xe_vma_end(vma);
> + mem_attrs[i].atomic.val = vma->attr.atomic_access;
> + mem_attrs[i].pat_index.val = vma->attr.pat_index;
> + mem_attrs[i].preferred_mem_loc.devmem_fd = vma->attr.preferred_loc.devmem_fd;
> + mem_attrs[i].preferred_mem_loc.migration_policy = vma->attr.preferred_loc.migration_policy;
> +
> + i++;
> + }
> +
> + if (i < (*num_vmas - 1))
> + *num_vmas = i;
> + return 0;
> +}
> +
> +int xe_vm_query_vmas_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
> +{
> + struct xe_device *xe = to_xe_device(dev);
> + struct xe_file *xef = to_xe_file(file);
> + struct drm_xe_vma_mem_attr *mem_attrs;
> + struct drm_xe_vm_query_vmas_attr *args = data;
> + u64 __user *attrs_user = NULL;
> + struct xe_vm *vm;
> + int err;
> +
> + if (XE_IOCTL_DBG(xe, args->num_vmas < 1))
> + return -EINVAL;
> +
> + vm = xe_vm_lookup(xef, args->vm_id);
> + if (XE_IOCTL_DBG(xe, !vm))
> + return -EINVAL;
> +
> + down_write(&vm->lock);
> +
> + attrs_user = u64_to_user_ptr(args->vector_of_vma_mem_attr);
> + mem_attrs = kvmalloc_array(args->num_vmas, sizeof(struct drm_xe_vma_mem_attr),
> + GFP_KERNEL | __GFP_ACCOUNT |
> + __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
> + if (!mem_attrs)
> + return args->num_vmas > 1 ? -ENOBUFS : -ENOMEM;
> +
> + err = get_mem_attrs(vm, &args->num_vmas, args->start,
> + args->start + args->range, mem_attrs);
> + if (err)
> + goto free_mem_attrs;
> +
> + err = __copy_to_user(attrs_user, mem_attrs,
> + sizeof(struct drm_xe_vma_mem_attr) * args->num_vmas);
> +
> +free_mem_attrs:
> + kvfree(mem_attrs);
> +
> + up_write(&vm->lock);
> +
> + return err;
> +}
> +
> static bool vma_matches(struct xe_vma *vma, u64 page_addr)
> {
> if (page_addr > xe_vma_end(vma) - 1 ||
> diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
> index 377f62f859b7..0b2d6e9f77ef 100644
> --- a/drivers/gpu/drm/xe/xe_vm.h
> +++ b/drivers/gpu/drm/xe/xe_vm.h
> @@ -193,7 +193,8 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
> struct drm_file *file);
> int xe_vm_bind_ioctl(struct drm_device *dev, void *data,
> struct drm_file *file);
> -
> +int xe_vm_query_vmas_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
> +int xe_vm_query_vmas_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
> void xe_vm_close_and_put(struct xe_vm *vm);
>
> static inline bool xe_vm_in_fault_mode(struct xe_vm *vm)
> diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
> index f30d0cb5b054..68c447db9f2e 100644
> --- a/include/uapi/drm/xe_drm.h
> +++ b/include/uapi/drm/xe_drm.h
> @@ -82,6 +82,8 @@ extern "C" {
> * - &DRM_IOCTL_XE_WAIT_USER_FENCE
> * - &DRM_IOCTL_XE_OBSERVATION
> * - &DRM_IOCTL_XE_MADVISE
> + * - &DRM_IOCTL_XE_VM_QUERY_VMAS
> + * - &DRM_IOCTL_XE_VM_QUERY_VMAS_ATTRS
> */
>
> /*
> @@ -104,6 +106,8 @@ extern "C" {
> #define DRM_XE_WAIT_USER_FENCE 0x0a
> #define DRM_XE_OBSERVATION 0x0b
> #define DRM_XE_MADVISE 0x0c
> +#define DRM_XE_VM_QUERY_VMAS 0x0d
> +#define DRM_XE_VM_QUERY_VMAS_ATTRS 0x0e
>
> /* Must be kept compact -- no holes */
>
> @@ -120,6 +124,8 @@ extern "C" {
> #define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
> #define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
> #define DRM_IOCTL_XE_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_MADVISE, struct drm_xe_madvise)
> +#define DRM_IOCTL_XE_VM_QUERY_VMAS DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_QUERY_VMAS, struct drm_xe_vm_query_num_vmas)
> +#define DRM_IOCTL_XE_VM_QUERY_VMAS_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_QUERY_VMAS_ATTRS, struct drm_xe_vm_query_vmas_attr)
>
> /**
> * DOC: Xe IOCTL Extensions
> @@ -2059,6 +2065,115 @@ struct drm_xe_madvise {
>
> };
>
> +/**
> + * struct drm_xe_vm_query_num_vmas - Input of &DRM_IOCTL_XE_VM_QUERY_VMAS
> + *
> + * Get number of vmas in virtual range of vm_id
> + */
> +struct drm_xe_vm_query_num_vmas {
> + /** @extensions: Pointer to the first extension struct, if any */
> + __u64 extensions;
> +
> + /** @vm_id: vm_id of the virtual range */
> + __u32 vm_id;
> +
> + /** @num_vmas: number of vmas in range returned in @num_vmas */
> + __u32 num_vmas;
> +
> + /** @start: start of the virtual address range */
> + __u64 start;
> +
> + /** @size: size of the virtual address range */
> + __u64 range;
> +
> + /** @reserved: Reserved */
> + __u64 reserved[2];
> +};
> +
> +struct drm_xe_vma_mem_attr {
> + /** @extensions: Pointer to the first extension struct, if any */
> + __u64 extensions;
> +
> + /** @start: start of the vma */
> + __u64 start;
> +
> + /** @size: end of the vma */
> + __u64 end;
> +
> + struct {
> + struct {
> + /** @val: value of atomic operation*/
> + __u32 val;
> +
> + /** @reserved: Reserved */
> + __u32 reserved;
> + } atomic;
> +
> + struct {
> + /** @val: value for DRM_XE_VMA_ATTR_PURGEABLE_STATE */
> + __u32 val;
> +
> + /** @reserved: Reserved */
> + __u32 reserved;
> + } purge_state_val;
> +
> + struct {
> + /** @pat_index */
> + __u32 val;
> +
> + /** @reserved: Reserved */
> + __u32 reserved;
> + } pat_index;
> +
> + /** @preferred_mem_loc: preferred memory location */
> + struct {
> + __u32 devmem_fd;
> +
> + __u32 migration_policy;
> + } preferred_mem_loc;
> + };
> +
> + /** @reserved: Reserved */
> + __u64 reserved[2];
> +};
> +
> +/**
> + * struct drm_xe_vm_query_vmas_attr - Input of &DRM_IOCTL_XE_VM_QUERY_MEM_ATTRIBUTES
> + *
> + * Get memory attributes to a virtual address range
> + */
> +struct drm_xe_vm_query_vmas_attr {
> + /** @extensions: Pointer to the first extension struct, if any */
> + __u64 extensions;
> +
> + /** @vm_id: vm_id of the virtual range */
> + __u32 vm_id;
> +
> + /** @num_vmas: number of vmas in range returned in @num_vmas */
> + __u32 num_vmas;
> +
> + /** @start: start of the virtual address range */
> + __u64 start;
> +
> + /** @size: size of the virtual address range */
> + __u64 range;
> +
> + union {
> + /** @num_vmas: used if num_vmas == 1 */
> + struct drm_xe_vma_mem_attr attr;
> +
> + /**
> + * @vector_of_ops: userptr to array of struct
> + * drm_xe_vma_mem_attr if num_vmas > 1
> + */
> + __u64 vector_of_vma_mem_attr;
> + };
> +
> + /** @reserved: Reserved */
> + __u64 reserved[2];
> +
> +};
> +
> #if defined(__cplusplus)
> }
> #endif
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 28/29] drm/xe/bo: Add attributes field to xe_bo
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (26 preceding siblings ...)
2025-03-14 8:02 ` [RFC 27/29] drm/xe/uapi: Add uapi for vma count and mem attributes Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-05-14 19:35 ` Matthew Brost
2025-03-14 8:02 ` [RFC 29/29] drm/xe/bo : Update atomic_access attribute on madvise Himal Prasad Ghimiray
2025-03-14 15:00 ` ✗ CI.Patch_applied: failure for PREFETCH and MADVISE for SVM ranges (rev2) Patchwork
29 siblings, 1 reply; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
A single BO can be linked to multiple VMAs, making VMA attributes
insufficient for determining the placement and PTE update attributes
of the BO. To address this, an attributes field has been added to the
BO.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_bo_types.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h
index 15a92e3d4898..bac21a4f6805 100644
--- a/drivers/gpu/drm/xe/xe_bo_types.h
+++ b/drivers/gpu/drm/xe/xe_bo_types.h
@@ -58,6 +58,11 @@ struct xe_bo {
*/
struct list_head client_link;
#endif
+ /** @attr: User controlled attributes for bo */
+ struct {
+ /** @atomic_access: type of atomic access bo needs */
+ u32 atomic_access;
+ } attr;
/**
* @pxp_key_instance: PXP key instance this BO was created against. A
* 0 in this variable indicates that the BO does not use PXP encryption.
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* Re: [RFC 28/29] drm/xe/bo: Add attributes field to xe_bo
2025-03-14 8:02 ` [RFC 28/29] drm/xe/bo: Add attributes field to xe_bo Himal Prasad Ghimiray
@ 2025-05-14 19:35 ` Matthew Brost
0 siblings, 0 replies; 52+ messages in thread
From: Matthew Brost @ 2025-05-14 19:35 UTC (permalink / raw)
To: Himal Prasad Ghimiray; +Cc: intel-xe, thomas.hellstrom, oak.zeng
On Fri, Mar 14, 2025 at 01:32:25PM +0530, Himal Prasad Ghimiray wrote:
> A single BO can be linked to multiple VMAs, making VMA attributes
> insufficient for determining the placement and PTE update attributes
> of the BO. To address this, an attributes field has been added to the
> BO.
>
> Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> ---
> drivers/gpu/drm/xe/xe_bo_types.h | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h
> index 15a92e3d4898..bac21a4f6805 100644
> --- a/drivers/gpu/drm/xe/xe_bo_types.h
> +++ b/drivers/gpu/drm/xe/xe_bo_types.h
> @@ -58,6 +58,11 @@ struct xe_bo {
> */
> struct list_head client_link;
> #endif
> + /** @attr: User controlled attributes for bo */
> + struct {
> + /** @atomic_access: type of atomic access bo needs */
> + u32 atomic_access;
> + } attr;
> /**
> * @pxp_key_instance: PXP key instance this BO was created against. A
> * 0 in this variable indicates that the BO does not use PXP encryption.
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [RFC 29/29] drm/xe/bo : Update atomic_access attribute on madvise
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (27 preceding siblings ...)
2025-03-14 8:02 ` [RFC 28/29] drm/xe/bo: Add attributes field to xe_bo Himal Prasad Ghimiray
@ 2025-03-14 8:02 ` Himal Prasad Ghimiray
2025-03-14 15:00 ` ✗ CI.Patch_applied: failure for PREFETCH and MADVISE for SVM ranges (rev2) Patchwork
29 siblings, 0 replies; 52+ messages in thread
From: Himal Prasad Ghimiray @ 2025-03-14 8:02 UTC (permalink / raw)
To: intel-xe; +Cc: matthew.brost, thomas.hellstrom, oak.zeng, Himal Prasad Ghimiray
Update the bo_atomic_access based on user-provided input and determine
the migration to smem during a CPU fault.
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
---
drivers/gpu/drm/xe/xe_bo.c | 21 ++++++++++++++---
drivers/gpu/drm/xe/xe_vm.c | 11 +++++++--
drivers/gpu/drm/xe/xe_vm_madvise.c | 38 +++++++++++++++++++++++++++---
3 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 0c7a7f5e5596..0596348f7ff6 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -1329,6 +1329,12 @@ static void xe_gem_object_close(struct drm_gem_object *obj,
}
}
+static bool should_migrate_to_smem(struct xe_bo *bo)
+{
+ return bo->attr.atomic_access == DRM_XE_VMA_ATOMIC_GLOBAL ||
+ bo->attr.atomic_access == DRM_XE_VMA_ATOMIC_CPU;
+}
+
static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
{
struct ttm_buffer_object *tbo = vmf->vma->vm_private_data;
@@ -1337,7 +1343,7 @@ static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
struct xe_bo *bo = ttm_to_xe_bo(tbo);
bool needs_rpm = bo->flags & XE_BO_FLAG_VRAM_MASK;
vm_fault_t ret;
- int idx;
+ int idx, r = 0;
if (needs_rpm)
xe_pm_runtime_get(xe);
@@ -1349,8 +1355,17 @@ static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
if (drm_dev_enter(ddev, &idx)) {
trace_xe_bo_cpu_fault(bo);
- ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
- TTM_BO_VM_NUM_PREFAULT);
+ if (should_migrate_to_smem(bo)) {
+ r = xe_bo_migrate(bo, XE_PL_TT);
+ if (r == -EBUSY || r == -ERESTARTSYS || r == -EINTR)
+ ret = VM_FAULT_NOPAGE;
+ else if (r)
+ ret = VM_FAULT_SIGBUS;
+ }
+ if (!ret)
+ ret = ttm_bo_vm_fault_reserved(vmf,
+ vmf->vma->vm_page_prot,
+ TTM_BO_VM_NUM_PREFAULT);
drm_dev_exit(idx);
} else {
ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 349481b13546..5e174b7d57e0 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3069,9 +3069,16 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
err = vma_lock_and_validate(exec,
gpuva_to_vma(op->base.prefetch.va),
false);
- if (!err && !xe_vma_has_no_bo(vma))
- err = xe_bo_migrate(xe_vma_bo(vma),
+ if (!err && !xe_vma_has_no_bo(vma)) {
+ struct xe_bo *bo = xe_vma_bo(vma);
+
+ if (region == 0 && !vm->xe->info.has_device_atomics_on_smem &&
+ bo->attr.atomic_access == DRM_XE_VMA_ATOMIC_DEVICE)
+ region = 1;
+
+ err = xe_bo_migrate(bo,
region_to_mem_type[region]);
+ }
break;
}
default:
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index f4e0545937b0..bbae2faee603 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -87,16 +87,48 @@ static int madvise_atomic(struct xe_device *xe, struct xe_vm *vm,
struct xe_vma **vmas, int num_vmas,
struct drm_xe_madvise_ops ops)
{
- int i;
+ struct xe_bo *bo;
+ int err, i;
xe_assert(vm->xe, ops.type == DRM_XE_VMA_ATTR_ATOMIC);
xe_assert(vm->xe, ops.atomic.val > DRM_XE_VMA_ATOMIC_UNDEFINED &&
ops.atomic.val <= DRM_XE_VMA_ATOMIC_CPU);
vm_dbg(&xe->drm, "attr_value = %d", ops.atomic.val);
- for (i = 0; i < num_vmas; i++)
+ for (i = 0; i < num_vmas; i++) {
vmas[i]->attr.atomic_access = ops.atomic.val;
- /*TODO: handle bo backed vmas */
+
+ bo = xe_vma_bo(vmas[i]);
+ if (!bo)
+ continue;
+
+ if (XE_IOCTL_DBG(xe, ops.atomic.val == DRM_XE_VMA_ATOMIC_CPU &&
+ !(bo->flags & XE_BO_FLAG_SYSTEM)))
+ return -EINVAL;
+
+ if (XE_IOCTL_DBG(xe, ops.atomic.val == DRM_XE_VMA_ATOMIC_DEVICE &&
+ !(bo->flags & XE_BO_FLAG_VRAM0) &&
+ !(bo->flags & XE_BO_FLAG_VRAM1)))
+ return -EINVAL;
+
+ if (XE_IOCTL_DBG(xe, ops.atomic.val == DRM_XE_VMA_ATOMIC_GLOBAL &&
+ (!(bo->flags & XE_BO_FLAG_SYSTEM) ||
+ (!(bo->flags & XE_BO_FLAG_VRAM0) &&
+ !(bo->flags & XE_BO_FLAG_VRAM1)))))
+ return -EINVAL;
+
+ err = xe_bo_lock(bo, true);
+ if (err)
+ return err;
+ bo->attr.atomic_access = ops.atomic.val;
+
+ /* Invalidate cpu page table, so bo can migrate to smem in next access */
+ if (bo->attr.atomic_access == DRM_XE_VMA_ATOMIC_CPU ||
+ bo->attr.atomic_access == DRM_XE_VMA_ATOMIC_GLOBAL)
+ ttm_bo_unmap_virtual(&bo->ttm);
+
+ xe_bo_unlock(bo);
+ }
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 52+ messages in thread* ✗ CI.Patch_applied: failure for PREFETCH and MADVISE for SVM ranges (rev2)
2025-03-14 8:01 [RFC 00/29] PREFETCH and MADVISE for SVM ranges Himal Prasad Ghimiray
` (28 preceding siblings ...)
2025-03-14 8:02 ` [RFC 29/29] drm/xe/bo : Update atomic_access attribute on madvise Himal Prasad Ghimiray
@ 2025-03-14 15:00 ` Patchwork
29 siblings, 0 replies; 52+ messages in thread
From: Patchwork @ 2025-03-14 15:00 UTC (permalink / raw)
To: Ghimiray, Himal Prasad; +Cc: intel-xe
== Series Details ==
Series: PREFETCH and MADVISE for SVM ranges (rev2)
URL : https://patchwork.freedesktop.org/series/146290/
State : failure
== Summary ==
=== Applying kernel patches on branch 'drm-tip' with base: ===
Base commit: 83417b23792d drm-tip: 2025y-03m-14d-13h-46m-49s UTC integration manifest
=== git am output follows ===
error: patch failed: drivers/gpu/drm/xe/xe_svm.c:714
error: drivers/gpu/drm/xe/xe_svm.c: patch does not apply
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Applying: drm/xe: Introduce xe_vma_op_prefetch_range struct for prefetch of ranges
Applying: drm/xe: Make xe_svm_alloc_vram public
Applying: drm/xe/svm: Helper to add tile masks to svm ranges
Applying: drm/xe/svm: Make to_xe_range a public function
Applying: drm/xe/svm: Make xe_svm_range_* end/start/size public
Applying: drm/xe/vm: Update xe_vma_ops_incr_pt_update_ops to take an increment value
Applying: drm/xe/vm: Add an identifier in xe_vma_ops for svm prefetch
Applying: drm/xe: Rename lookup_vma function to xe_find_vma_by_addr
Applying: drm/xe/svm: Allow unaligned addresses and ranges for prefetch
Applying: drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm
Patch failed at 0010 drm/xe/svm: Refactor usage of drm_gpusvm* function in xe_svm
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
^ permalink raw reply [flat|nested] 52+ messages in thread