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/svm: Consult madvise preferred location in prefetch

When prefetch region is DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, prefetch svm
ranges to preferred location provided by madvise.

v2 (Matthew Brost)
- Fix region, devmem_fd usages
- consult madvise is applicable for other vma's too.

v3
- Fix atomic handling

v4
- Fix xe_svm_range_validate to check for
DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC too.

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

+35 -19
+30 -17
drivers/gpu/drm/xe/xe_vm.c
··· 38 38 #include "xe_res_cursor.h" 39 39 #include "xe_svm.h" 40 40 #include "xe_sync.h" 41 + #include "xe_tile.h" 41 42 #include "xe_trace_bo.h" 42 43 #include "xe_wa.h" 43 44 #include "xe_hmm.h" ··· 2401 2400 __xe_vm_needs_clear_scratch_pages(vm, flags); 2402 2401 } else if (__op->op == DRM_GPUVA_OP_PREFETCH) { 2403 2402 struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va); 2403 + struct xe_tile *tile; 2404 2404 struct xe_svm_range *svm_range; 2405 2405 struct drm_gpusvm_ctx ctx = {}; 2406 - struct xe_tile *tile; 2406 + struct drm_pagemap *dpagemap; 2407 2407 u8 id, tile_mask = 0; 2408 2408 u32 i; 2409 2409 ··· 2421 2419 tile_mask |= 0x1 << id; 2422 2420 2423 2421 xa_init_flags(&op->prefetch_range.range, XA_FLAGS_ALLOC); 2424 - op->prefetch_range.region = prefetch_region; 2425 2422 op->prefetch_range.ranges_count = 0; 2423 + tile = NULL; 2424 + 2425 + if (prefetch_region == DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC) { 2426 + dpagemap = xe_vma_resolve_pagemap(vma, 2427 + xe_device_get_root_tile(vm->xe)); 2428 + /* 2429 + * TODO: Once multigpu support is enabled will need 2430 + * something to dereference tile from dpagemap. 2431 + */ 2432 + if (dpagemap) 2433 + tile = xe_device_get_root_tile(vm->xe); 2434 + } else if (prefetch_region) { 2435 + tile = &vm->xe->tiles[region_to_mem_type[prefetch_region] - 2436 + XE_PL_VRAM0]; 2437 + } 2438 + 2439 + op->prefetch_range.tile = tile; 2426 2440 alloc_next_range: 2427 2441 svm_range = xe_svm_range_find_or_insert(vm, addr, vma, &ctx); 2428 2442 ··· 2457 2439 goto unwind_prefetch_ops; 2458 2440 } 2459 2441 2460 - if (xe_svm_range_validate(vm, svm_range, tile_mask, !!prefetch_region)) { 2442 + if (xe_svm_range_validate(vm, svm_range, tile_mask, !!tile)) { 2461 2443 xe_svm_range_debug(svm_range, "PREFETCH - RANGE IS VALID"); 2462 2444 goto check_next_range; 2463 2445 } ··· 2953 2935 { 2954 2936 bool devmem_possible = IS_DGFX(vm->xe) && IS_ENABLED(CONFIG_DRM_XE_PAGEMAP); 2955 2937 struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va); 2938 + struct xe_tile *tile = op->prefetch_range.tile; 2956 2939 int err = 0; 2957 2940 2958 2941 struct xe_svm_range *svm_range; 2959 2942 struct drm_gpusvm_ctx ctx = {}; 2960 - struct xe_tile *tile; 2961 2943 unsigned long i; 2962 - u32 region; 2963 2944 2964 2945 if (!xe_vma_is_cpu_addr_mirror(vma)) 2965 2946 return 0; 2966 - 2967 - region = op->prefetch_range.region; 2968 2947 2969 2948 ctx.read_only = xe_vma_read_only(vma); 2970 2949 ctx.devmem_possible = devmem_possible; ··· 2969 2954 2970 2955 /* TODO: Threading the migration */ 2971 2956 xa_for_each(&op->prefetch_range.range, i, svm_range) { 2972 - if (!region) 2957 + if (!tile) 2973 2958 xe_svm_range_migrate_to_smem(vm, svm_range); 2974 2959 2975 - if (xe_svm_range_needs_migrate_to_vram(svm_range, vma, region)) { 2976 - tile = &vm->xe->tiles[region_to_mem_type[region] - XE_PL_VRAM0]; 2960 + if (xe_svm_range_needs_migrate_to_vram(svm_range, vma, !!tile)) { 2977 2961 err = xe_svm_alloc_vram(tile, svm_range, &ctx); 2978 2962 if (err) { 2979 2963 drm_dbg(&vm->xe->drm, "VRAM allocation failed, retry from userspace, asid=%u, gpusvm=%p, errno=%pe\n", ··· 3035 3021 struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va); 3036 3022 u32 region; 3037 3023 3038 - if (xe_vma_is_cpu_addr_mirror(vma)) 3039 - region = op->prefetch_range.region; 3040 - else 3024 + if (!xe_vma_is_cpu_addr_mirror(vma)) { 3041 3025 region = op->prefetch.region; 3042 - 3043 - xe_assert(vm->xe, region <= ARRAY_SIZE(region_to_mem_type)); 3026 + xe_assert(vm->xe, region == DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC || 3027 + region <= ARRAY_SIZE(region_to_mem_type)); 3028 + } 3044 3029 3045 3030 err = vma_lock_and_validate(exec, 3046 3031 gpuva_to_vma(op->base.prefetch.va), ··· 3457 3444 op == DRM_XE_VM_BIND_OP_PREFETCH) || 3458 3445 XE_IOCTL_DBG(xe, prefetch_region && 3459 3446 op != DRM_XE_VM_BIND_OP_PREFETCH) || 3460 - XE_IOCTL_DBG(xe, !(BIT(prefetch_region) & 3461 - xe->info.mem_region_mask)) || 3447 + XE_IOCTL_DBG(xe, (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC && 3448 + !(BIT(prefetch_region) & xe->info.mem_region_mask))) || 3462 3449 XE_IOCTL_DBG(xe, obj && 3463 3450 op == DRM_XE_VM_BIND_OP_UNMAP)) { 3464 3451 err = -EINVAL;
+5 -2
drivers/gpu/drm/xe/xe_vm_types.h
··· 428 428 struct xarray range; 429 429 /** @ranges_count: number of svm ranges to map */ 430 430 u32 ranges_count; 431 - /** @region: memory region to prefetch to */ 432 - u32 region; 431 + /** 432 + * @tile: Pointer to the tile structure containing memory to prefetch. 433 + * NULL if prefetch requested region is smem 434 + */ 435 + struct xe_tile *tile; 433 436 }; 434 437 435 438 /** enum xe_vma_op_flags - flags for VMA operation */