drivers/gpu/drm/xe/xe_userptr.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_userptr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/xe/xe_userptr.c- Extension
.c- Size
- 13017 bytes
- Lines
- 434
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
xe_svm.hxe_userptr.hlinux/mm.hxe_tlb_inval.hxe_trace_bo.h
Detected Declarations
function xe_userptr_assert_in_notifierfunction xe_vma_userptr_check_repinfunction __xe_vm_userptr_needs_repinfunction xe_vma_userptr_pin_pagesfunction xe_vma_userptr_do_invalfunction xe_vma_userptr_complete_tlb_invalfunction xe_vma_userptr_invalidate_pass1function xe_vma_userptr_invalidate_startfunction xe_vma_userptr_invalidate_finishfunction xe_vma_userptr_force_invalidatefunction xe_vm_userptr_pinfunction list_for_each_entry_safefunction xe_vm_userptr_check_repinfunction xe_userptr_setupfunction xe_userptr_removefunction xe_userptr_destroy
Annotated Snippet
if (!userptr->finish_inuse) {
/*
* Defer the TLB wait to an extra pass so the caller
* can pipeline TLB flushes across GPUs before waiting
* on any of them.
*/
xe_assert(vm->xe, !userptr->tlb_inval_submitted);
userptr->finish_inuse = true;
userptr->tlb_inval_submitted = true;
err = xe_vm_invalidate_vma_submit(vma, &userptr->inval_batch);
XE_WARN_ON(err);
return &userptr->finish;
}
err = xe_vm_invalidate_vma(vma);
XE_WARN_ON(err);
}
if (is_deferred)
userptr->finish_inuse = false;
drm_gpusvm_unmap_pages(&vm->svm.gpusvm, &uvma->userptr.pages,
xe_vma_size(vma) >> PAGE_SHIFT, &ctx);
return NULL;
}
static void
xe_vma_userptr_complete_tlb_inval(struct xe_vm *vm, struct xe_userptr_vma *uvma)
{
struct xe_userptr *userptr = &uvma->userptr;
struct xe_vma *vma = &uvma->vma;
struct drm_gpusvm_ctx ctx = {
.in_notifier = true,
.read_only = xe_vma_read_only(vma),
};
xe_userptr_assert_in_notifier(vm);
xe_assert(vm->xe, userptr->finish_inuse);
xe_assert(vm->xe, userptr->tlb_inval_submitted);
xe_tlb_inval_batch_wait(&userptr->inval_batch);
userptr->tlb_inval_submitted = false;
userptr->finish_inuse = false;
drm_gpusvm_unmap_pages(&vm->svm.gpusvm, &uvma->userptr.pages,
xe_vma_size(vma) >> PAGE_SHIFT, &ctx);
}
static struct mmu_interval_notifier_finish *
xe_vma_userptr_invalidate_pass1(struct xe_vm *vm, struct xe_userptr_vma *uvma)
{
struct xe_userptr *userptr = &uvma->userptr;
struct xe_vma *vma = &uvma->vma;
struct dma_resv_iter cursor;
struct dma_fence *fence;
bool signaled = true;
xe_userptr_assert_in_notifier(vm);
/*
* Tell exec and rebind worker they need to repin and rebind this
* userptr.
*/
if (!xe_vm_in_fault_mode(vm) &&
!(vma->gpuva.flags & XE_VMA_DESTROYED)) {
spin_lock(&vm->userptr.invalidated_lock);
list_move_tail(&userptr->invalidate_link,
&vm->userptr.invalidated);
spin_unlock(&vm->userptr.invalidated_lock);
}
/*
* Preempt fences turn into schedule disables, pipeline these.
* Note that even in fault mode, we need to wait for binds and
* unbinds to complete, and those are attached as BOOKMARK fences
* to the vm.
*/
dma_resv_iter_begin(&cursor, xe_vm_resv(vm),
DMA_RESV_USAGE_BOOKKEEP);
dma_resv_for_each_fence_unlocked(&cursor, fence) {
dma_fence_enable_sw_signaling(fence);
if (signaled && !dma_fence_is_signaled(fence))
signaled = false;
}
dma_resv_iter_end(&cursor);
/*
* Only one caller at a time can use the multi-pass state.
* If it's already in use, or all fences are already signaled,
* proceed directly to invalidation without deferring.
*/
if (signaled || userptr->finish_inuse)
return xe_vma_userptr_do_inval(vm, uvma, false);
Annotation
- Immediate include surface: `xe_svm.h`, `xe_userptr.h`, `linux/mm.h`, `xe_tlb_inval.h`, `xe_trace_bo.h`.
- Detected declarations: `function xe_userptr_assert_in_notifier`, `function xe_vma_userptr_check_repin`, `function __xe_vm_userptr_needs_repin`, `function xe_vma_userptr_pin_pages`, `function xe_vma_userptr_do_inval`, `function xe_vma_userptr_complete_tlb_inval`, `function xe_vma_userptr_invalidate_pass1`, `function xe_vma_userptr_invalidate_start`, `function xe_vma_userptr_invalidate_finish`, `function xe_vma_userptr_force_invalidate`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- 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.