drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c- Extension
.c- Size
- 52010 bytes
- Lines
- 2005
- 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.
- 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
vmm.hsubdev/fb.h
Detected Declarations
struct nvkm_vmm_iterfunction filesfunction nvkm_vmm_pt_newfunction nvkm_vmm_desc_typefunction nvkm_vmm_tracefunction nvkm_vmm_flush_markfunction nvkm_vmm_flushfunction nvkm_vmm_unref_pdesfunction nvkm_vmm_unref_sptesfunction nvkm_vmm_unref_ptesfunction nvkm_vmm_ref_sptesfunction nvkm_vmm_ref_ptesfunction nvkm_vmm_sparse_ptesfunction nvkm_vmm_sparse_unref_ptesfunction nvkm_vmm_sparse_ref_ptesfunction nvkm_vmm_ref_hwptfunction nvkm_vmm_ref_swptfunction nvkm_vmm_iterfunction nvkm_vmm_ptes_sparse_putfunction nvkm_vmm_ptes_sparse_getfunction nvkm_vmm_ptes_sparsefunction nvkm_vmm_ptes_unmapfunction nvkm_vmm_ptes_mapfunction nvkm_vmm_ptes_put_lockedfunction nvkm_vmm_ptes_putfunction nvkm_vmm_ptes_getfunction __nvkm_vmm_ptes_unmap_putfunction nvkm_vmm_ptes_unmap_putfunction __nvkm_vmm_ptes_get_mapfunction nvkm_vmm_ptes_get_mapfunction nvkm_vma_newfunction nvkm_vma_tailfunction nvkm_vmm_free_removefunction nvkm_vmm_free_deletefunction nvkm_vmm_free_insertfunction nvkm_vmm_node_removefunction nvkm_vmm_node_deletefunction nvkm_vmm_node_insertfunction nvkm_vmm_node_searchfunction nvkm_vmm_node_mergefunction nvkm_vmm_node_splitfunction nvkm_vma_dumpfunction nvkm_vmm_dumpfunction nvkm_vmm_dtorfunction nvkm_vmm_ctor_managedfunction nvkm_vmm_ctorfunction nvkm_vmm_new_function nvkm_vmm_pfn_split_merge
Annotated Snippet
struct nvkm_vmm_iter {
const struct nvkm_vmm_page *page;
const struct nvkm_vmm_desc *desc;
struct nvkm_vmm *vmm;
u64 cnt;
u16 max, lvl;
u32 pte[NVKM_VMM_LEVELS_MAX];
struct nvkm_vmm_pt *pt[NVKM_VMM_LEVELS_MAX];
int flush;
};
#ifdef CONFIG_NOUVEAU_DEBUG_MMU
static const char *
nvkm_vmm_desc_type(const struct nvkm_vmm_desc *desc)
{
switch (desc->type) {
case PGD: return "PGD";
case PGT: return "PGT";
case SPT: return "SPT";
case LPT: return "LPT";
default:
return "UNKNOWN";
}
}
static void
nvkm_vmm_trace(struct nvkm_vmm_iter *it, char *buf)
{
int lvl;
for (lvl = it->max; lvl >= 0; lvl--) {
if (lvl >= it->lvl)
buf += sprintf(buf, "%05x:", it->pte[lvl]);
else
buf += sprintf(buf, "xxxxx:");
}
}
#define TRA(i,f,a...) do { \
char _buf[NVKM_VMM_LEVELS_MAX * 7]; \
struct nvkm_vmm_iter *_it = (i); \
nvkm_vmm_trace(_it, _buf); \
VMM_TRACE(_it->vmm, "%s "f, _buf, ##a); \
} while(0)
#else
#define TRA(i,f,a...)
#endif
static inline void
nvkm_vmm_flush_mark(struct nvkm_vmm_iter *it)
{
it->flush = min(it->flush, it->max - it->lvl);
}
static inline void
nvkm_vmm_flush(struct nvkm_vmm_iter *it)
{
if (it->flush != NVKM_VMM_LEVELS_MAX) {
if (it->vmm->func->flush) {
TRA(it, "flush: %d", it->flush);
it->vmm->func->flush(it->vmm, it->flush);
}
it->flush = NVKM_VMM_LEVELS_MAX;
}
}
static void
nvkm_vmm_unref_pdes(struct nvkm_vmm_iter *it)
{
const struct nvkm_vmm_desc *desc = it->desc;
const int type = desc[it->lvl].type == SPT;
struct nvkm_vmm_pt *pgd = it->pt[it->lvl + 1];
struct nvkm_vmm_pt *pgt = it->pt[it->lvl];
struct nvkm_mmu_pt *pt = pgt->pt[type];
struct nvkm_vmm *vmm = it->vmm;
u32 pdei = it->pte[it->lvl + 1];
/* Recurse up the tree, unreferencing/destroying unneeded PDs. */
it->lvl++;
if (--pgd->refs[0]) {
const struct nvkm_vmm_desc_func *func = desc[it->lvl].func;
/* PD has other valid PDEs, so we need a proper update. */
TRA(it, "PDE unmap %s", nvkm_vmm_desc_type(&desc[it->lvl - 1]));
pgt->pt[type] = NULL;
if (!pgt->refs[!type]) {
/* PDE no longer required. */
if (pgd->pt[0]) {
if (pgt->sparse) {
func->sparse(vmm, pgd->pt[0], pdei, 1);
pgd->pde[pdei] = NVKM_VMM_PDE_SPARSE;
} else {
Annotation
- Immediate include surface: `vmm.h`, `subdev/fb.h`.
- Detected declarations: `struct nvkm_vmm_iter`, `function files`, `function nvkm_vmm_pt_new`, `function nvkm_vmm_desc_type`, `function nvkm_vmm_trace`, `function nvkm_vmm_flush_mark`, `function nvkm_vmm_flush`, `function nvkm_vmm_unref_pdes`, `function nvkm_vmm_unref_sptes`, `function nvkm_vmm_unref_ptes`.
- 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.