[CI 40/43] drm/xe/svm: Migration from sram to vram for system allocator
Oak Zeng
oak.zeng at intel.com
Wed Jun 12 02:26:02 UTC 2024
If applicable, migrate a range of hmmptr from sram to vram for
system allocator. Traditional userptr is not migrated. Only userptr
created during fault (aka userptr splitted from system allocator vma,
aka fault userptr in codes) can be migrated.
Instead of the whole userptr, only a sub-range of userptr is populated
and bind to GPU page table. Right now the range granularity is 2MiB,
which will be overwritten by memory attribute API.
FIXME: The migration should be conditional on user memory attributes
setting. Add this logic when memory attributes are supported
Cc: Thomas Hellström <thomas.hellstrom at linux.intel.com>
Cc: Matthew Brost <matthew.brost at intel.com>
Cc: Brian Welty <brian.welty at intel.com>
Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray at intel.com>
Signed-off-by: Oak Zeng <oak.zeng at intel.com>
---
drivers/gpu/drm/xe/xe_gt_pagefault.c | 41 ++++++++++++++++++++++++++--
drivers/gpu/drm/xe/xe_vm.c | 17 +++++++-----
drivers/gpu/drm/xe/xe_vm.h | 2 +-
3 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c
index 9e47e0c97a1b..004cd4d8e1a0 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -128,6 +128,12 @@ static int handle_vma_pagefault(struct xe_tile *tile, struct pagefault *pf,
ktime_t end = 0;
int err;
bool atomic;
+ /**FIXME: use migration granularity from memory attributes*/
+ u64 migrate_granularity = SZ_2M;
+ u64 fault_addr = pf->page_addr;
+ u64 fault_offset, fault_cpu_addr;
+ u64 aligned_cpu_fault_start, aligned_cpu_fault_end;
+ u64 cpu_va_start, cpu_va_end, gpu_va_start, gpu_va_end;
trace_xe_vma_pagefault(vma);
atomic = access_is_atomic(pf->access_type);
@@ -144,13 +150,42 @@ static int handle_vma_pagefault(struct xe_tile *tile, struct pagefault *pf,
}
}
+ fault_offset = fault_addr - xe_vma_start(vma);
+ fault_cpu_addr = xe_vma_userptr(vma) + fault_offset;
+ aligned_cpu_fault_start = ALIGN_DOWN(fault_cpu_addr, migrate_granularity);
+ aligned_cpu_fault_end = aligned_cpu_fault_start + migrate_granularity;
+
+ if (xe_vma_is_userptr(vma)) {
+ cpu_va_start = max_t(u64, xe_vma_userptr(vma), aligned_cpu_fault_start);
+ cpu_va_end = min_t(u64, xe_vma_userptr_end(vma), aligned_cpu_fault_end);
+ gpu_va_start = xe_vma_start(vma) + (cpu_va_start - xe_vma_userptr(vma));
+ gpu_va_end = xe_vma_end(vma) - (xe_vma_userptr_end(vma) - cpu_va_end);
+ } else {
+ gpu_va_start = xe_vma_start(vma);
+ gpu_va_end = xe_vma_end(vma);
+ }
+
retry_userptr:
xe_vm_userptr_garbage_collector(vm);
if (xe_vma_is_userptr(vma) &&
xe_vma_userptr_check_repin(to_userptr_vma(vma))) {
struct xe_userptr_vma *uvma = to_userptr_vma(vma);
+ struct xe_userptr *userptr = &uvma->userptr;
+ struct drm_hmmptr *hmmptr = &userptr->hmmptr;
+
+ mmap_read_lock(hmmptr->notifier.mm);
+ if (xe_vma_is_fault_userptr(vma)) {
+ /**FIXME: add migration policy here*/
+ err = drm_svm_migrate_hmmptr_to_vram(&vm->gpuvm, &tile->mem.vram.drm_mr,
+ hmmptr, cpu_va_start, cpu_va_end);
+ if (err) {
+ mmap_read_unlock(hmmptr->notifier.mm);
+ return err;
+ }
- err = xe_vma_userptr_pin_pages(uvma);
+ }
+ err = xe_vma_userptr_pin_pages(uvma, cpu_va_start, cpu_va_end, true);
+ mmap_read_unlock(hmmptr->notifier.mm);
if (err)
return err;
}
@@ -167,8 +202,8 @@ static int handle_vma_pagefault(struct xe_tile *tile, struct pagefault *pf,
/* Bind VMA only to the GT that has faulted */
trace_xe_vma_pf_bind(vma);
- fence = xe_vma_rebind(vm, vma, xe_vma_start(vma),
- xe_vma_end(vma), BIT(tile->id));
+ fence = xe_vma_rebind(vm, vma, gpu_va_start,
+ gpu_va_end, BIT(tile->id));
if (IS_ERR(fence)) {
err = PTR_ERR(fence);
if (xe_vm_validate_should_retry(&exec, err, &end))
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 4de4817f041b..a5f732db9e1c 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -63,7 +63,7 @@ int xe_vma_userptr_check_repin(struct xe_userptr_vma *uvma)
-EAGAIN : 0;
}
-int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma)
+int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma, u64 start, u64 end, bool mmap_locked)
{
struct drm_hmmptr *hmmptr = &uvma->userptr.hmmptr;
struct xe_vma *vma = &uvma->vma;
@@ -73,14 +73,15 @@ int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma)
lockdep_assert_held(&vm->lock);
xe_assert(xe, xe_vma_is_userptr(vma));
+ xe_assert(xe, start >= xe_vma_userptr(vma));
+ xe_assert(xe, end <= xe_vma_userptr_end(vma));
- ret = drm_svm_hmmptr_populate(hmmptr, NULL, xe_vma_userptr(vma),
- xe_vma_userptr(vma) + xe_vma_size(vma),
- !xe_vma_read_only(vma), false);
+ ret = drm_svm_hmmptr_populate(hmmptr, NULL, start, end,
+ !xe_vma_read_only(vma), mmap_locked);
if (ret)
return ret;
- xe_vma_userptr_dma_map_pages(uvma, xe_vma_userptr(vma), xe_vma_userptr_end(vma));
+ xe_vma_userptr_dma_map_pages(uvma, start, end);
return 0;
}
@@ -736,7 +737,8 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
/* Pin and move to temporary list */
list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
userptr.repin_link) {
- err = xe_vma_userptr_pin_pages(uvma);
+ err = xe_vma_userptr_pin_pages(uvma, xe_vma_userptr(&uvma->vma),
+ xe_vma_userptr_end(&uvma->vma), false);
if (err == -EFAULT) {
list_del_init(&uvma->userptr.repin_link);
@@ -2116,7 +2118,8 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
drm_exec_fini(&exec);
if (xe_vma_is_userptr(vma) && !xe_vma_is_fault_userptr(vma)) {
- err = xe_vma_userptr_pin_pages(to_userptr_vma(vma));
+ err = xe_vma_userptr_pin_pages(to_userptr_vma(vma), xe_vma_userptr(vma),
+ xe_vma_userptr_end(vma), false);
if (err) {
prep_vma_destroy(vm, vma, false);
xe_vma_destroy_unlocked(vma);
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 4c75438e7504..ec4201b042ec 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -253,7 +253,7 @@ static inline void xe_vm_reactivate_rebind(struct xe_vm *vm)
}
}
-int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma);
+int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma, u64 start, u64 end, bool mmap_locked);
void xe_vma_userptr_dma_map_pages(struct xe_userptr_vma *uvma,
u64 start, u64 end);
--
2.26.3
More information about the Intel-xe
mailing list