mm/mmu_gather.c
Source file repositories/reference/linux-study-clean/mm/mmu_gather.c
File Facts
- System
- Linux kernel
- Corpus path
mm/mmu_gather.c- Extension
.c- Size
- 15176 bytes
- Lines
- 556
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- 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/gfp.hlinux/highmem.hlinux/kernel.hlinux/mmdebug.hlinux/mm_types.hlinux/mm_inline.hlinux/pagemap.hlinux/rcupdate.hlinux/smp.hlinux/swap.hlinux/rmap.hlinux/pgalloc.hlinux/hugetlb.hasm/tlb.h
Detected Declarations
function tlb_next_batchfunction tlb_flush_rmap_batchfunction tlb_next_batchfunction __tlb_batch_free_encoded_pagesfunction tlb_batch_pages_flushfunction tlb_batch_list_freefunction __tlb_remove_folio_pages_sizefunction __tlb_remove_folio_pagesfunction __tlb_remove_page_sizefunction __tlb_remove_table_freefunction gup_fastfunction tlb_remove_table_rcufunction tlb_remove_table_freefunction tlb_remove_table_sync_onefunction tlb_remove_table_freefunction tlb_remove_tablefunction __tlb_remove_table_one_rcufunction __tlb_remove_table_onefunction __tlb_remove_table_onefunction tlb_remove_table_onefunction tlb_table_flushfunction tlb_remove_tablefunction tlb_table_initfunction tlb_table_flushfunction tlb_flush_mmufunction __tlb_gather_mmufunction anfunction spacefunction anfunction tlb_finish_mmu
Annotated Snippet
if (encoded_page_flags(enc) & ENCODED_PAGE_BIT_DELAY_RMAP) {
struct page *page = encoded_page_ptr(enc);
unsigned int nr_pages = 1;
if (unlikely(encoded_page_flags(enc) &
ENCODED_PAGE_BIT_NR_PAGES_NEXT))
nr_pages = encoded_nr_pages(pages[++i]);
folio_remove_rmap_ptes(page_folio(page), page, nr_pages,
vma);
}
}
}
/**
* tlb_flush_rmaps - do pending rmap removals after we have flushed the TLB
* @tlb: the current mmu_gather
* @vma: The memory area from which the pages are being removed.
*
* Note that because of how tlb_next_batch() above works, we will
* never start multiple new batches with pending delayed rmaps, so
* we only need to walk through the current active batch and the
* original local one.
*/
void tlb_flush_rmaps(struct mmu_gather *tlb, struct vm_area_struct *vma)
{
if (!tlb->delayed_rmap)
return;
tlb_flush_rmap_batch(&tlb->local, vma);
if (tlb->active != &tlb->local)
tlb_flush_rmap_batch(tlb->active, vma);
tlb->delayed_rmap = 0;
}
#endif
/*
* We might end up freeing a lot of pages. Reschedule on a regular
* basis to avoid soft lockups in configurations without full
* preemption enabled. The magic number of 512 folios seems to work.
*/
#define MAX_NR_FOLIOS_PER_FREE 512
static void __tlb_batch_free_encoded_pages(struct mmu_gather_batch *batch)
{
struct encoded_page **pages = batch->encoded_pages;
unsigned int nr, nr_pages;
while (batch->nr) {
if (!page_poisoning_enabled_static() && !want_init_on_free()) {
nr = min(MAX_NR_FOLIOS_PER_FREE, batch->nr);
/*
* Make sure we cover page + nr_pages, and don't leave
* nr_pages behind when capping the number of entries.
*/
if (unlikely(encoded_page_flags(pages[nr - 1]) &
ENCODED_PAGE_BIT_NR_PAGES_NEXT))
nr++;
} else {
/*
* With page poisoning and init_on_free, the time it
* takes to free memory grows proportionally with the
* actual memory size. Therefore, limit based on the
* actual memory size and not the number of involved
* folios.
*/
for (nr = 0, nr_pages = 0;
nr < batch->nr && nr_pages < MAX_NR_FOLIOS_PER_FREE;
nr++) {
if (unlikely(encoded_page_flags(pages[nr]) &
ENCODED_PAGE_BIT_NR_PAGES_NEXT))
nr_pages += encoded_nr_pages(pages[++nr]);
else
nr_pages++;
}
}
free_pages_and_swap_cache(pages, nr);
pages += nr;
batch->nr -= nr;
cond_resched();
}
}
static void tlb_batch_pages_flush(struct mmu_gather *tlb)
{
struct mmu_gather_batch *batch;
Annotation
- Immediate include surface: `linux/gfp.h`, `linux/highmem.h`, `linux/kernel.h`, `linux/mmdebug.h`, `linux/mm_types.h`, `linux/mm_inline.h`, `linux/pagemap.h`, `linux/rcupdate.h`.
- Detected declarations: `function tlb_next_batch`, `function tlb_flush_rmap_batch`, `function tlb_next_batch`, `function __tlb_batch_free_encoded_pages`, `function tlb_batch_pages_flush`, `function tlb_batch_list_free`, `function __tlb_remove_folio_pages_size`, `function __tlb_remove_folio_pages`, `function __tlb_remove_page_size`, `function __tlb_remove_table_free`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: source implementation candidate.
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.