drivers/gpu/drm/xe/xe_vm_madvise.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_vm_madvise.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/xe/xe_vm_madvise.c- Extension
.c- Size
- 19789 bytes
- Lines
- 735
- 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_madvise.hlinux/nospec.hdrm/xe_drm.hxe_bo.hxe_pat.hxe_pt.hxe_svm.hxe_tlb_inval.hxe_vm.h
Detected Declarations
struct xe_vmas_in_madvise_rangestruct xe_madvise_detailsfunction get_vmasfunction drm_gpuvm_for_each_va_rangefunction madvise_preferred_mem_locfunction madvise_atomicfunction madvise_pat_indexfunction madvise_purgeablefunction xe_zap_ptes_in_madvise_rangefunction drm_gpuvm_for_each_va_rangefunction for_each_tilefunction xe_vm_invalidate_madvise_rangefunction madvise_args_are_sanefunction xe_madvise_details_initfunction xe_madvise_details_finifunction xe_madvise_purgeable_retained_to_userfunction check_pat_args_are_sanefunction check_bo_args_are_sanefunction xe_vm_madvise_ioctlfunction drm_exec_until_all_locked
Annotated Snippet
struct xe_vmas_in_madvise_range {
u64 addr;
u64 range;
struct xe_vma **vmas;
int num_vmas;
bool has_bo_vmas;
bool has_svm_userptr_vmas;
};
/**
* struct xe_madvise_details - Argument to madvise_funcs
* @dpagemap: Reference-counted pointer to a struct drm_pagemap.
* @has_purged_bo: Track if any BO was purged (for purgeable state)
* @retained_ptr: User pointer for retained value (for purgeable state)
*
* The madvise IOCTL handler may, in addition to the user-space
* args, have additional info to pass into the madvise_func that
* handles the madvise type. Use a struct_xe_madvise_details
* for that and extend the struct as necessary.
*/
struct xe_madvise_details {
struct drm_pagemap *dpagemap;
bool has_purged_bo;
u64 retained_ptr;
};
static int get_vmas(struct xe_vm *vm, struct xe_vmas_in_madvise_range *madvise_range)
{
u64 addr = madvise_range->addr;
u64 range = madvise_range->range;
struct xe_vma **__vmas;
struct drm_gpuva *gpuva;
int max_vmas = 8;
lockdep_assert_held(&vm->lock);
madvise_range->num_vmas = 0;
madvise_range->vmas = kmalloc_objs(*madvise_range->vmas, max_vmas);
if (!madvise_range->vmas)
return -ENOMEM;
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 (xe_vma_bo(vma))
madvise_range->has_bo_vmas = true;
else if (xe_vma_is_cpu_addr_mirror(vma) || xe_vma_is_userptr(vma))
madvise_range->has_svm_userptr_vmas = true;
if (madvise_range->num_vmas == max_vmas) {
max_vmas <<= 1;
__vmas = krealloc(madvise_range->vmas,
max_vmas * sizeof(*madvise_range->vmas),
GFP_KERNEL);
if (!__vmas) {
kfree(madvise_range->vmas);
return -ENOMEM;
}
madvise_range->vmas = __vmas;
}
madvise_range->vmas[madvise_range->num_vmas] = vma;
(madvise_range->num_vmas)++;
}
if (!madvise_range->num_vmas)
kfree(madvise_range->vmas);
vm_dbg(&vm->xe->drm, "madvise_range-num_vmas = %d\n", madvise_range->num_vmas);
return 0;
}
static void madvise_preferred_mem_loc(struct xe_device *xe, struct xe_vm *vm,
struct xe_vma **vmas, int num_vmas,
struct drm_xe_madvise *op,
struct xe_madvise_details *details)
{
int i;
xe_assert(vm->xe, op->type == DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC);
for (i = 0; i < num_vmas; i++) {
struct xe_vma *vma = vmas[i];
struct xe_vma_preferred_loc *loc = &vma->attr.preferred_loc;
/*TODO: Extend attributes to bo based vmas */
Annotation
- Immediate include surface: `xe_vm_madvise.h`, `linux/nospec.h`, `drm/xe_drm.h`, `xe_bo.h`, `xe_pat.h`, `xe_pt.h`, `xe_svm.h`, `xe_tlb_inval.h`.
- Detected declarations: `struct xe_vmas_in_madvise_range`, `struct xe_madvise_details`, `function get_vmas`, `function drm_gpuvm_for_each_va_range`, `function madvise_preferred_mem_loc`, `function madvise_atomic`, `function madvise_pat_index`, `function madvise_purgeable`, `function xe_zap_ptes_in_madvise_range`, `function drm_gpuvm_for_each_va_range`.
- 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.