drivers/gpu/drm/amd/amdkfd/kfd_svm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/amdkfd/kfd_svm.c- Extension
.c- Size
- 123114 bytes
- Lines
- 4352
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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
linux/types.hlinux/sched/task.hlinux/dynamic_debug.hdrm/ttm/ttm_tt.hdrm/drm_exec.hamdgpu_sync.hamdgpu_object.hamdgpu_vm.hamdgpu_hmm.hamdgpu.hamdgpu_xgmi.hamdgpu_reset.hkfd_priv.hkfd_svm.hkfd_migrate.hkfd_smi_events.h
Detected Declarations
struct criu_svm_metadatastruct svm_validate_contextfunction svm_range_unlinkfunction svm_range_add_notifier_lockedfunction svm_range_add_to_svmsfunction svm_range_remove_notifierfunction svm_is_valid_dma_mapping_addrfunction svm_range_dma_map_devfunction svm_range_dma_mapfunction for_each_set_bitfunction svm_range_dma_unmap_devfunction svm_range_dma_unmapfunction svm_range_freefunction svm_range_set_default_attributesfunction amdgpu_amdkfd_reserve_mem_limitfunction svm_bo_ref_unless_zerofunction svm_range_bo_releasefunction svm_range_bo_wq_releasefunction svm_range_bo_release_asyncfunction svm_range_bo_unref_asyncfunction svm_range_bo_unreffunction svm_range_validate_svm_bofunction svm_range_vram_node_newfunction svm_range_vram_node_freefunction svm_range_get_node_by_idfunction svm_range_get_pdd_by_nodefunction svm_range_bo_validatefunction svm_range_check_attrfunction svm_range_apply_attrsfunction svm_range_is_same_attrsfunction svm_range_debug_dumpfunction list_for_each_entryfunction svm_range_copy_arrayfunction svm_range_copy_dma_addrsfunction svm_range_split_arrayfunction svm_range_split_pagesfunction svm_range_split_nodesfunction svm_range_split_adjustfunction svm_range_splitfunction svm_range_split_tailfunction svm_range_split_headfunction svm_range_add_childfunction svm_nodes_in_same_hivefunction svm_range_get_pte_flagsfunction IP_VERSIONfunction svm_range_unmap_from_gpufunction svm_range_unmap_from_gpusfunction for_each_or_bit
Annotated Snippet
struct criu_svm_metadata {
struct list_head list;
struct kfd_criu_svm_range_priv_data data;
};
static void svm_range_evict_svm_bo_worker(struct work_struct *work);
static bool
svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
const struct mmu_notifier_range *range,
unsigned long cur_seq);
static int
svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last,
uint64_t *bo_s, uint64_t *bo_l);
static const struct mmu_interval_notifier_ops svm_range_mn_ops = {
.invalidate = svm_range_cpu_invalidate_pagetables,
};
/**
* svm_range_unlink - unlink svm_range from lists and interval tree
* @prange: svm range structure to be removed
*
* Remove the svm_range from the svms and svm_bo lists and the svms
* interval tree.
*
* Context: The caller must hold svms->lock
*/
static void svm_range_unlink(struct svm_range *prange)
{
pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms,
prange, prange->start, prange->last);
if (prange->svm_bo) {
spin_lock(&prange->svm_bo->list_lock);
list_del(&prange->svm_bo_list);
spin_unlock(&prange->svm_bo->list_lock);
}
list_del(&prange->list);
if (prange->it_node.start != 0 && prange->it_node.last != 0)
interval_tree_remove(&prange->it_node, &prange->svms->objects);
}
static void
svm_range_add_notifier_locked(struct mm_struct *mm, struct svm_range *prange)
{
pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms,
prange, prange->start, prange->last);
mmu_interval_notifier_insert_locked(&prange->notifier, mm,
prange->start << PAGE_SHIFT,
prange->npages << PAGE_SHIFT,
&svm_range_mn_ops);
}
/**
* svm_range_add_to_svms - add svm range to svms
* @prange: svm range structure to be added
*
* Add the svm range to svms interval tree and link list
*
* Context: The caller must hold svms->lock
*/
static void svm_range_add_to_svms(struct svm_range *prange)
{
pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms,
prange, prange->start, prange->last);
list_move_tail(&prange->list, &prange->svms->list);
prange->it_node.start = prange->start;
prange->it_node.last = prange->last;
interval_tree_insert(&prange->it_node, &prange->svms->objects);
}
static void svm_range_remove_notifier(struct svm_range *prange)
{
pr_debug("remove notifier svms 0x%p prange 0x%p [0x%lx 0x%lx]\n",
prange->svms, prange,
prange->notifier.interval_tree.start >> PAGE_SHIFT,
prange->notifier.interval_tree.last >> PAGE_SHIFT);
if (prange->notifier.interval_tree.start != 0 &&
prange->notifier.interval_tree.last != 0)
mmu_interval_notifier_remove(&prange->notifier);
}
static bool
svm_is_valid_dma_mapping_addr(struct device *dev, dma_addr_t dma_addr)
{
return dma_addr && !dma_mapping_error(dev, dma_addr) &&
!(dma_addr & SVM_RANGE_VRAM_DOMAIN);
Annotation
- Immediate include surface: `linux/types.h`, `linux/sched/task.h`, `linux/dynamic_debug.h`, `drm/ttm/ttm_tt.h`, `drm/drm_exec.h`, `amdgpu_sync.h`, `amdgpu_object.h`, `amdgpu_vm.h`.
- Detected declarations: `struct criu_svm_metadata`, `struct svm_validate_context`, `function svm_range_unlink`, `function svm_range_add_notifier_locked`, `function svm_range_add_to_svms`, `function svm_range_remove_notifier`, `function svm_is_valid_dma_mapping_addr`, `function svm_range_dma_map_dev`, `function svm_range_dma_map`, `function for_each_set_bit`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.