Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/xe: Allow CPU address mirror VMA unbind with gpu bindings for madvise

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.

v2 (Matthew Brost)
- Use vops flag to call unmapping of ranges in vm_bind_ioctl_ops_parse
- Rename the function

v3
- Fix doc

v4
- check if range is already in garbage collector (Matthew Brost)

Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://lore.kernel.org/r/20250821173104.3030148-7-himal.prasad.ghimiray@intel.com
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>

+48 -2
+35
drivers/gpu/drm/xe/xe_svm.c
··· 933 933 } 934 934 935 935 /** 936 + * xe_svm_unmap_address_range - UNMAP SVM mappings and ranges 937 + * @vm: The VM 938 + * @start: start addr 939 + * @end: end addr 940 + * 941 + * This function UNMAPS svm ranges if start or end address are inside them. 942 + */ 943 + void xe_svm_unmap_address_range(struct xe_vm *vm, u64 start, u64 end) 944 + { 945 + struct drm_gpusvm_notifier *notifier, *next; 946 + 947 + lockdep_assert_held_write(&vm->lock); 948 + 949 + drm_gpusvm_for_each_notifier_safe(notifier, next, &vm->svm.gpusvm, start, end) { 950 + struct drm_gpusvm_range *range, *__next; 951 + 952 + drm_gpusvm_for_each_range_safe(range, __next, notifier, start, end) { 953 + if (start > drm_gpusvm_range_start(range) || 954 + end < drm_gpusvm_range_end(range)) { 955 + if (IS_DGFX(vm->xe) && xe_svm_range_in_vram(to_xe_range(range))) 956 + drm_gpusvm_range_evict(&vm->svm.gpusvm, range); 957 + drm_gpusvm_range_get(range); 958 + __xe_svm_garbage_collector(vm, to_xe_range(range)); 959 + if (!list_empty(&to_xe_range(range)->garbage_collector_link)) { 960 + spin_lock(&vm->svm.garbage_collector.lock); 961 + list_del(&to_xe_range(range)->garbage_collector_link); 962 + spin_unlock(&vm->svm.garbage_collector.lock); 963 + } 964 + drm_gpusvm_range_put(range); 965 + } 966 + } 967 + } 968 + } 969 + 970 + /** 936 971 * xe_svm_bo_evict() - SVM evict BO to system memory 937 972 * @bo: BO to evict 938 973 *
+7
drivers/gpu/drm/xe/xe_svm.h
··· 90 90 91 91 u64 xe_svm_find_vma_start(struct xe_vm *vm, u64 addr, u64 end, struct xe_vma *vma); 92 92 93 + void xe_svm_unmap_address_range(struct xe_vm *vm, u64 start, u64 end); 94 + 93 95 /** 94 96 * xe_svm_range_has_dma_mapping() - SVM range has DMA mapping 95 97 * @range: SVM range ··· 303 301 u64 xe_svm_find_vma_start(struct xe_vm *vm, u64 addr, u64 end, struct xe_vma *vma) 304 302 { 305 303 return ULONG_MAX; 304 + } 305 + 306 + static inline 307 + void xe_svm_unmap_address_range(struct xe_vm *vm, u64 start, u64 end) 308 + { 306 309 } 307 310 308 311 #define xe_svm_assert_in_notifier(...) do {} while (0)
+6 -2
drivers/gpu/drm/xe/xe_vm.c
··· 2694 2694 end = op->base.remap.next->va.addr; 2695 2695 2696 2696 if (xe_vma_is_cpu_addr_mirror(old) && 2697 - xe_svm_has_mapping(vm, start, end)) 2698 - return -EBUSY; 2697 + xe_svm_has_mapping(vm, start, end)) { 2698 + if (vops->flags & XE_VMA_OPS_FLAG_MADVISE) 2699 + xe_svm_unmap_address_range(vm, start, end); 2700 + else 2701 + return -EBUSY; 2702 + } 2699 2703 2700 2704 op->remap.start = xe_vma_start(old); 2701 2705 op->remap.range = xe_vma_size(old);