drivers/gpu/drm/nouveau/nouveau_dmem.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nouveau_dmem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/nouveau_dmem.c- Extension
.c- Size
- 24025 bytes
- Lines
- 894
- 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.
- 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
nouveau_dmem.hnouveau_drv.hnouveau_chan.hnouveau_dma.hnouveau_mem.hnouveau_bo.hnouveau_svm.hnvif/class.hnvif/object.hnvif/push906f.hnvif/if000c.hnvif/if500b.hnvif/if900b.hnvhw/class/cla0b5.hlinux/sched/mm.hlinux/hmm.hlinux/memremap.hlinux/migrate.h
Detected Declarations
struct nouveau_dmem_chunkstruct nouveau_dmem_migratestruct nouveau_dmemstruct nouveau_dmem_dma_infoenum nouveau_aperfunction nouveau_dmem_page_addrfunction nouveau_dmem_folio_freefunction nouveau_dmem_fence_donefunction nouveau_dmem_copy_foliofunction nouveau_dmem_migrate_to_ramfunction nouveau_dmem_folio_splitfunction nouveau_dmem_chunk_allocfunction nouveau_dmem_page_alloc_lockedfunction nouveau_dmem_page_free_lockedfunction nouveau_dmem_resumefunction nouveau_dmem_suspendfunction nouveau_dmem_evict_chunkfunction nouveau_dmem_finifunction list_for_each_entry_safefunction nvc0b5_migrate_copyfunction nvc0b5_migrate_clearfunction nouveau_dmem_migrate_initfunction nouveau_dmem_initfunction nouveau_dmem_migrate_copy_onefunction nouveau_dmem_migrate_chunkfunction nouveau_dmem_migrate_vma
Annotated Snippet
struct nouveau_dmem_chunk {
struct list_head list;
struct nouveau_bo *bo;
struct nouveau_drm *drm;
unsigned long callocated;
struct dev_pagemap pagemap;
};
struct nouveau_dmem_migrate {
nouveau_migrate_copy_t copy_func;
nouveau_clear_page_t clear_func;
struct nouveau_channel *chan;
};
struct nouveau_dmem {
struct nouveau_drm *drm;
struct nouveau_dmem_migrate migrate;
struct list_head chunks;
struct mutex mutex;
struct page *free_pages;
struct folio *free_folios;
spinlock_t lock;
};
struct nouveau_dmem_dma_info {
dma_addr_t dma_addr;
size_t size;
};
static struct nouveau_dmem_chunk *nouveau_page_to_chunk(struct page *page)
{
return container_of(page_pgmap(page), struct nouveau_dmem_chunk,
pagemap);
}
static struct nouveau_drm *page_to_drm(struct page *page)
{
struct nouveau_dmem_chunk *chunk = nouveau_page_to_chunk(page);
return chunk->drm;
}
unsigned long nouveau_dmem_page_addr(struct page *page)
{
struct nouveau_dmem_chunk *chunk = nouveau_page_to_chunk(page);
unsigned long off = (page_to_pfn(page) << PAGE_SHIFT) -
chunk->pagemap.range.start;
return chunk->bo->offset + off;
}
static void nouveau_dmem_folio_free(struct folio *folio)
{
struct page *page = &folio->page;
struct nouveau_dmem_chunk *chunk = nouveau_page_to_chunk(page);
struct nouveau_dmem *dmem = chunk->drm->dmem;
spin_lock(&dmem->lock);
if (folio_order(folio)) {
page->zone_device_data = dmem->free_folios;
dmem->free_folios = folio;
} else {
page->zone_device_data = dmem->free_pages;
dmem->free_pages = page;
}
WARN_ON(!chunk->callocated);
chunk->callocated--;
/*
* FIXME when chunk->callocated reach 0 we should add the chunk to
* a reclaim list so that it can be freed in case of memory pressure.
*/
spin_unlock(&dmem->lock);
}
static void nouveau_dmem_fence_done(struct nouveau_fence **fence)
{
if (fence) {
nouveau_fence_wait(*fence, true, false);
nouveau_fence_unref(fence);
} else {
/*
* FIXME wait for channel to be IDLE before calling finalizing
* the hmem object.
*/
}
}
static int nouveau_dmem_copy_folio(struct nouveau_drm *drm,
struct folio *sfolio, struct folio *dfolio,
Annotation
- Immediate include surface: `nouveau_dmem.h`, `nouveau_drv.h`, `nouveau_chan.h`, `nouveau_dma.h`, `nouveau_mem.h`, `nouveau_bo.h`, `nouveau_svm.h`, `nvif/class.h`.
- Detected declarations: `struct nouveau_dmem_chunk`, `struct nouveau_dmem_migrate`, `struct nouveau_dmem`, `struct nouveau_dmem_dma_info`, `enum nouveau_aper`, `function nouveau_dmem_page_addr`, `function nouveau_dmem_folio_free`, `function nouveau_dmem_fence_done`, `function nouveau_dmem_copy_folio`, `function nouveau_dmem_migrate_to_ram`.
- 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.
- 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.