drivers/gpu/drm/xe/xe_vm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_vm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/xe/xe_vm.c- Extension
.c- Size
- 125142 bytes
- Lines
- 4964
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
xe_vm.hlinux/dma-fence-array.hlinux/nospec.hdrm/drm_drv.hdrm/drm_exec.hdrm/drm_print.hdrm/ttm/ttm_tt.huapi/drm/xe_drm.hlinux/ascii85.hlinux/delay.hlinux/kthread.hlinux/mm.hlinux/swap.hgenerated/xe_wa_oob.hregs/xe_gtt_defs.hxe_assert.hxe_bo.hxe_device.hxe_drm_client.hxe_exec_queue.hxe_gt.hxe_migrate.hxe_pat.hxe_pm.hxe_preempt_fence.hxe_pt.hxe_pxp.hxe_sriov_vf.hxe_svm.hxe_sync.hxe_tile.hxe_tlb_inval.h
Detected Declarations
struct xe_vma_lock_and_validate_flagsstruct xe_vm_snapshotfunction xe_vm_drm_exec_lockfunction preempt_fences_waitingfunction list_for_each_entryfunction free_preempt_fencesfunction alloc_preempt_fencesfunction wait_for_existing_preempt_fencesfunction list_for_each_entryfunction xe_vm_is_idlefunction arm_preempt_fencesfunction list_for_each_entryfunction add_preempt_fencesfunction list_for_each_entryfunction resume_and_reinstall_preempt_fencesfunction list_for_each_entryfunction xe_vm_add_compute_exec_queuefunction xe_vm_remove_compute_exec_queuefunction xe_vm_killfunction xe_gpuvm_validatefunction xe_vm_validate_rebindfunction drm_exec_for_each_locked_objectfunction xe_preempt_work_beginfunction vm_suspend_rebind_workerfunction xe_vm_resume_rebind_workerfunction preempt_rebind_work_funcfunction drm_exec_until_all_lockedfunction xe_vm_add_fault_entry_pffunction xe_vm_clear_fault_entriesfunction xe_vma_ops_allocfunction xe_vma_svm_prefetch_op_finifunction xe_vma_svm_prefetch_ops_finifunction xe_vma_ops_finifunction xe_vma_ops_incr_pt_update_opsfunction xe_vm_populate_rebindfunction xe_vm_ops_add_rebindfunction xe_vm_rebindfunction xe_vm_populate_range_rebindfunction xe_vm_ops_add_range_rebindfunction xe_vm_range_rebindfunction xe_vm_populate_range_unbindfunction xe_vm_ops_add_range_unbindfunction xe_vm_range_unbindfunction xe_vma_mem_attr_finifunction xe_vma_freefunction xe_vma_mem_attr_copyfunction xe_vma_is_userptrfunction ioctls
Annotated Snippet
struct xe_vma_lock_and_validate_flags {
u32 res_evict : 1;
u32 validate : 1;
u32 request_decompress : 1;
u32 check_purged : 1;
};
static int vma_lock_and_validate(struct drm_exec *exec, struct xe_vma *vma,
struct xe_vma_lock_and_validate_flags flags)
{
struct xe_bo *bo = xe_vma_bo(vma);
struct xe_vm *vm = xe_vma_vm(vma);
bool validate_bo = flags.validate;
int err = 0;
if (bo) {
if (!bo->vm)
err = drm_exec_lock_obj(exec, &bo->ttm.base);
/* Reject new mappings to DONTNEED/purged BOs; allow cleanup operations */
if (!err && flags.check_purged) {
if (xe_bo_madv_is_dontneed(bo))
err = -EBUSY; /* BO marked purgeable */
else if (xe_bo_is_purged(bo))
err = -EINVAL; /* BO already purged */
}
/* Don't validate the BO for DONTNEED/PURGED remap remnants. */
if (vma->attr.purgeable_state != XE_MADV_PURGEABLE_WILLNEED)
validate_bo = false;
if (!err && validate_bo)
err = xe_bo_validate(bo, vm,
xe_vm_allow_vm_eviction(vm) &&
flags.res_evict, exec);
if (err)
return err;
if (flags.request_decompress)
err = xe_bo_decompress(bo);
}
return err;
}
static int check_ufence(struct xe_vma *vma)
{
if (vma->ufence) {
struct xe_user_fence * const f = vma->ufence;
if (!xe_sync_ufence_get_status(f))
return -EBUSY;
vma->ufence = NULL;
xe_sync_ufence_put(f);
}
return 0;
}
static int prefetch_ranges(struct xe_vm *vm, struct xe_vma_op *op)
{
bool devmem_possible = IS_DGFX(vm->xe) && IS_ENABLED(CONFIG_DRM_XE_PAGEMAP);
struct xe_vma *vma = gpuva_to_vma(op->base.prefetch.va);
struct drm_pagemap *dpagemap = op->prefetch_range.dpagemap;
int err = 0;
struct xe_svm_range *svm_range;
struct drm_gpusvm_ctx ctx = {};
unsigned long i;
if (!xe_vma_is_cpu_addr_mirror(vma))
return 0;
ctx.read_only = xe_vma_read_only(vma);
ctx.devmem_possible = devmem_possible;
ctx.check_pages_threshold = devmem_possible ? SZ_64K : 0;
ctx.device_private_page_owner = xe_svm_private_page_owner(vm, !dpagemap);
/* TODO: Threading the migration */
xa_for_each(&op->prefetch_range.range, i, svm_range) {
if (!dpagemap)
xe_svm_range_migrate_to_smem(vm, svm_range);
if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_VM)) {
drm_dbg(&vm->xe->drm,
"Prefetch pagemap is %s start 0x%016lx end 0x%016lx\n",
dpagemap ? dpagemap->drm->unique : "system",
xe_svm_range_start(svm_range), xe_svm_range_end(svm_range));
Annotation
- Immediate include surface: `xe_vm.h`, `linux/dma-fence-array.h`, `linux/nospec.h`, `drm/drm_drv.h`, `drm/drm_exec.h`, `drm/drm_print.h`, `drm/ttm/ttm_tt.h`, `uapi/drm/xe_drm.h`.
- Detected declarations: `struct xe_vma_lock_and_validate_flags`, `struct xe_vm_snapshot`, `function xe_vm_drm_exec_lock`, `function preempt_fences_waiting`, `function list_for_each_entry`, `function free_preempt_fences`, `function alloc_preempt_fences`, `function wait_for_existing_preempt_fences`, `function list_for_each_entry`, `function xe_vm_is_idle`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.