mm/page_ext.c
Source file repositories/reference/linux-study-clean/mm/page_ext.c
File Facts
- System
- Linux kernel
- Corpus path
mm/page_ext.c- Extension
.c- Size
- 15482 bytes
- Lines
- 581
- 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.
- 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
linux/mm.hlinux/mmzone.hlinux/memblock.hlinux/page_ext.hlinux/memory.hlinux/vmalloc.hlinux/kmemleak.hlinux/page_owner.hlinux/page_idle.hlinux/page_table_check.hlinux/rcupdate.hlinux/pgalloc_tag.hlinux/iommu-debug-pagealloc.h
Detected Declarations
function need_page_idlefunction setup_early_page_extfunction invoke_need_callbacksfunction invoke_init_callbacksfunction page_ext_init_flatmem_latefunction pgdat_page_ext_initfunction alloc_node_page_extfunction page_ext_init_flatmemfunction for_each_online_nodefunction page_ext_invalidfunction alloc_page_extfunction init_section_page_extfunction free_page_extfunction __free_page_extfunction __invalidate_page_extfunction online_page_extfunction offline_page_extfunction page_ext_callbackfunction page_ext_initfunction for_each_node_statefunction pgdat_page_ext_initfunction page_ext_getfunction page_ext_from_physfunction page_ext_put
Annotated Snippet
if (page_ext_ops[i]->need()) {
if (page_ext_ops[i]->need_shared_flags) {
page_ext_size = sizeof(struct page_ext);
break;
}
}
}
for (i = 0; i < entries; i++) {
if (page_ext_ops[i]->need()) {
page_ext_ops[i]->offset = page_ext_size;
page_ext_size += page_ext_ops[i]->size;
need = true;
}
}
return need;
}
static void __init invoke_init_callbacks(void)
{
int i;
int entries = ARRAY_SIZE(page_ext_ops);
for (i = 0; i < entries; i++) {
if (page_ext_ops[i]->init)
page_ext_ops[i]->init();
}
}
static inline struct page_ext *get_entry(void *base, unsigned long index)
{
return base + page_ext_size * index;
}
#ifndef CONFIG_SPARSEMEM
void __init page_ext_init_flatmem_late(void)
{
invoke_init_callbacks();
}
void __meminit pgdat_page_ext_init(struct pglist_data *pgdat)
{
pgdat->node_page_ext = NULL;
}
static struct page_ext *lookup_page_ext(const struct page *page)
{
unsigned long pfn = page_to_pfn(page);
unsigned long index;
struct page_ext *base;
WARN_ON_ONCE(!rcu_read_lock_held());
base = NODE_DATA(page_to_nid(page))->node_page_ext;
/*
* The sanity checks the page allocator does upon freeing a
* page can reach here before the page_ext arrays are
* allocated when feeding a range of pages to the allocator
* for the first time during bootup or memory hotplug.
*/
if (unlikely(!base))
return NULL;
index = pfn - round_down(node_start_pfn(page_to_nid(page)),
MAX_ORDER_NR_PAGES);
return get_entry(base, index);
}
static int __init alloc_node_page_ext(int nid)
{
struct page_ext *base;
unsigned long table_size;
unsigned long nr_pages;
nr_pages = NODE_DATA(nid)->node_spanned_pages;
if (!nr_pages)
return 0;
/*
* Need extra space if node range is not aligned with
* MAX_ORDER_NR_PAGES. When page allocator's buddy algorithm
* checks buddy's status, range could be out of exact node range.
*/
if (!IS_ALIGNED(node_start_pfn(nid), MAX_ORDER_NR_PAGES) ||
!IS_ALIGNED(node_end_pfn(nid), MAX_ORDER_NR_PAGES))
nr_pages += MAX_ORDER_NR_PAGES;
table_size = page_ext_size * nr_pages;
base = memblock_alloc_try_nid(
table_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
Annotation
- Immediate include surface: `linux/mm.h`, `linux/mmzone.h`, `linux/memblock.h`, `linux/page_ext.h`, `linux/memory.h`, `linux/vmalloc.h`, `linux/kmemleak.h`, `linux/page_owner.h`.
- Detected declarations: `function need_page_idle`, `function setup_early_page_ext`, `function invoke_need_callbacks`, `function invoke_init_callbacks`, `function page_ext_init_flatmem_late`, `function pgdat_page_ext_init`, `function alloc_node_page_ext`, `function page_ext_init_flatmem`, `function for_each_online_node`, `function page_ext_invalid`.
- Atlas domain: Core OS / Memory Management.
- 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.