drivers/gpu/drm/drm_gpusvm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/drm_gpusvm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/drm_gpusvm.c- Extension
.c- Size
- 54102 bytes
- Lines
- 1806
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/dma-mapping.hlinux/export.hlinux/hmm.hlinux/hugetlb_inline.hlinux/memremap.hlinux/mm_types.hlinux/slab.hdrm/drm_device.hdrm/drm_gpusvm.hdrm/drm_pagemap.hdrm/drm_print.h
Detected Declarations
function drm_gpusvm_for_each_rangefunction npages_in_rangefunction drm_gpusvm_notifier_findfunction drm_gpusvm_range_findfunction drm_gpusvm_notifier_invalidatefunction drm_gpusvm_initfunction to_drm_gpusvm_notifierfunction drm_gpusvm_notifier_insertfunction drm_gpusvm_notifier_removefunction drm_gpusvm_finifunction drm_gpusvm_for_each_notifier_safefunction drm_gpusvm_notifier_allocfunction drm_gpusvm_notifier_freefunction to_drm_gpusvm_rangefunction drm_gpusvm_range_insertfunction __drm_gpusvm_range_removefunction drm_gpusvm_range_allocfunction drm_gpusvm_hmm_pfn_to_orderfunction drm_gpusvm_check_pagesfunction drm_gpusvm_scan_mmfunction drm_gpusvm_range_chunk_sizefunction drm_gpusvm_driver_lock_heldfunction drm_gpusvm_driver_lock_heldfunction drm_gpusvm_range_find_or_insertfunction __drm_gpusvm_unmap_pagesfunction __drm_gpusvm_free_pagesfunction drm_gpusvm_free_pagesfunction drm_gpusvm_range_removefunction drm_gpusvm_range_getfunction drm_gpusvm_range_destroyfunction drm_gpusvm_range_putfunction drm_gpusvm_pages_validfunction drm_gpusvm_range_pages_validfunction drm_gpusvm_pages_valid_unlockedfunction drm_gpusvm_get_pagesfunction drm_gpusvm_range_get_pagesfunction invalidatefunction drm_gpusvm_range_unmap_pagesfunction drm_gpusvm_range_evictfunction drm_gpusvm_has_mappingfunction drm_gpusvm_for_each_notifierfunction drm_gpusvm_range_set_unmappedexport drm_gpusvm_notifier_findexport drm_gpusvm_range_findexport drm_gpusvm_initexport drm_gpusvm_finiexport drm_gpusvm_scan_mmexport drm_gpusvm_find_vma_start
Annotated Snippet
* if (IS_ERR(range)) {
* err = PTR_ERR(range);
* goto unlock;
* }
*
* if (driver_migration_policy(range)) {
* err = drm_pagemap_populate_mm(driver_choose_drm_pagemap(),
* gpuva_start, gpuva_end, gpusvm->mm,
* ctx->timeslice_ms);
* if (err) // CPU mappings may have changed
* goto retry;
* }
*
* err = drm_gpusvm_range_get_pages(gpusvm, range, &ctx);
* if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) { // CPU mappings changed
* if (err == -EOPNOTSUPP)
* drm_gpusvm_range_evict(gpusvm, range);
* goto retry;
* } else if (err) {
* goto unlock;
* }
*
* err = driver_bind_range(gpusvm, range);
* if (err == -EAGAIN) // CPU mappings changed
* goto retry
*
* unlock:
* driver_svm_unlock();
* return err;
* }
*
* 2) Garbage Collector
*
* .. code-block:: c
*
* void __driver_garbage_collector(struct drm_gpusvm *gpusvm,
* struct drm_gpusvm_range *range)
* {
* assert_driver_svm_locked(gpusvm);
*
* // Partial unmap, migrate any remaining device memory pages back to RAM
* if (range->flags.partial_unmap)
* drm_gpusvm_range_evict(gpusvm, range);
*
* driver_unbind_range(range);
* drm_gpusvm_range_remove(gpusvm, range);
* }
*
* void driver_garbage_collector(struct drm_gpusvm *gpusvm)
* {
* assert_driver_svm_locked(gpusvm);
*
* for_each_range_in_garbage_collector(gpusvm, range)
* __driver_garbage_collector(gpusvm, range);
* }
*
* 3) Notifier callback
*
* .. code-block:: c
*
* void driver_invalidation(struct drm_gpusvm *gpusvm,
* struct drm_gpusvm_notifier *notifier,
* const struct mmu_notifier_range *mmu_range)
* {
* struct drm_gpusvm_ctx ctx = { .in_notifier = true, };
* struct drm_gpusvm_range *range = NULL;
*
* driver_invalidate_device_pages(gpusvm, mmu_range->start, mmu_range->end);
*
* drm_gpusvm_for_each_range(range, notifier, mmu_range->start,
* mmu_range->end) {
* drm_gpusvm_range_unmap_pages(gpusvm, range, &ctx);
*
* if (mmu_range->event != MMU_NOTIFY_UNMAP)
* continue;
*
* drm_gpusvm_range_set_unmapped(range, mmu_range);
* driver_garbage_collector_add(gpusvm, range);
* }
* }
*/
/**
* npages_in_range() - Calculate the number of pages in a given range
* @start: The start address of the range
* @end: The end address of the range
*
* This macro calculates the number of pages in a given memory range,
* specified by the start and end addresses. It divides the difference
* between the end and start addresses by the page size (PAGE_SIZE) to
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/export.h`, `linux/hmm.h`, `linux/hugetlb_inline.h`, `linux/memremap.h`, `linux/mm_types.h`, `linux/slab.h`, `drm/drm_device.h`.
- Detected declarations: `function drm_gpusvm_for_each_range`, `function npages_in_range`, `function drm_gpusvm_notifier_find`, `function drm_gpusvm_range_find`, `function drm_gpusvm_notifier_invalidate`, `function drm_gpusvm_init`, `function to_drm_gpusvm_notifier`, `function drm_gpusvm_notifier_insert`, `function drm_gpusvm_notifier_remove`, `function drm_gpusvm_fini`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: integration implementation candidate.
- 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.