mm/page_owner.c
Source file repositories/reference/linux-study-clean/mm/page_owner.c
File Facts
- System
- Linux kernel
- Corpus path
mm/page_owner.c- Extension
.c- Size
- 26064 bytes
- Lines
- 1002
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/debugfs.hlinux/mm.hlinux/slab.hlinux/uaccess.hlinux/memblock.hlinux/stacktrace.hlinux/page_owner.hlinux/jump_label.hlinux/migrate.hlinux/stackdepot.hlinux/seq_file.hlinux/memcontrol.hlinux/sched/clock.hinternal.h
Detected Declarations
struct page_ownerstruct stackstruct stack_print_ctxfunction set_current_in_page_ownerfunction unset_current_in_page_ownerfunction early_page_owner_paramfunction need_page_ownerfunction create_dummy_stackfunction register_dummy_stackfunction register_failure_stackfunction register_early_stackfunction init_page_ownerfunction save_stackfunction add_stack_record_to_listfunction inc_stack_record_countfunction dec_stack_record_countfunction __update_page_owner_handlefunction __update_page_owner_free_handlefunction __reset_page_ownerfunction __set_page_ownerfunction __folio_set_owner_migrate_reasonfunction __split_page_ownerfunction __folio_copy_ownerfunction pagetypeinfo_showmixedcount_printfunction print_page_owner_memcgfunction print_page_ownerfunction __dump_page_ownerfunction read_page_ownerfunction lseek_page_ownerfunction init_pages_in_zonefunction init_early_allocated_pagesfunction stack_printfunction stack_stopfunction page_owner_stack_openfunction page_owner_threshold_getfunction page_owner_threshold_setfunction pageowner_init
Annotated Snippet
static const struct file_operations page_owner_fops = {
.read = read_page_owner,
.llseek = lseek_page_owner,
};
static void *stack_start(struct seq_file *m, loff_t *ppos)
{
struct stack *stack;
struct stack_print_ctx *ctx = m->private;
if (*ppos == -1UL)
return NULL;
if (!*ppos) {
/*
* This pairs with smp_store_release() from function
* add_stack_record_to_list(), so we get a consistent
* value of stack_list.
*/
stack = smp_load_acquire(&stack_list);
ctx->stack = stack;
} else {
stack = ctx->stack;
}
return stack;
}
static void *stack_next(struct seq_file *m, void *v, loff_t *ppos)
{
struct stack *stack = v;
struct stack_print_ctx *ctx = m->private;
stack = stack->next;
*ppos = stack ? *ppos + 1 : -1UL;
ctx->stack = stack;
return stack;
}
static unsigned long page_owner_pages_threshold;
static int stack_print(struct seq_file *m, void *v)
{
int i, nr_base_pages;
struct stack *stack = v;
unsigned long *entries;
unsigned long nr_entries;
struct stack_record *stack_record = stack->stack_record;
struct stack_print_ctx *ctx = m->private;
if (!stack->stack_record)
return 0;
nr_base_pages = refcount_read(&stack_record->count) - 1;
if (ctx->flags & STACK_PRINT_FLAG_PAGES &&
(nr_base_pages < 1 || nr_base_pages < page_owner_pages_threshold))
return 0;
if (ctx->flags & STACK_PRINT_FLAG_STACK) {
nr_entries = stack_record->size;
entries = stack_record->entries;
for (i = 0; i < nr_entries; i++)
seq_printf(m, " %pS\n", (void *)entries[i]);
}
if (ctx->flags & STACK_PRINT_FLAG_HANDLE)
seq_printf(m, "handle: %d\n", stack_record->handle.handle);
if (ctx->flags & STACK_PRINT_FLAG_PAGES)
seq_printf(m, "nr_base_pages: %d\n", nr_base_pages);
seq_putc(m, '\n');
return 0;
}
static void stack_stop(struct seq_file *m, void *v)
{
}
static const struct seq_operations page_owner_stack_op = {
.start = stack_start,
.next = stack_next,
.stop = stack_stop,
.show = stack_print
};
static int page_owner_stack_open(struct inode *inode, struct file *file)
{
int ret = seq_open_private(file, &page_owner_stack_op,
sizeof(struct stack_print_ctx));
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/mm.h`, `linux/slab.h`, `linux/uaccess.h`, `linux/memblock.h`, `linux/stacktrace.h`, `linux/page_owner.h`, `linux/jump_label.h`.
- Detected declarations: `struct page_owner`, `struct stack`, `struct stack_print_ctx`, `function set_current_in_page_owner`, `function unset_current_in_page_owner`, `function early_page_owner_param`, `function need_page_owner`, `function create_dummy_stack`, `function register_dummy_stack`, `function register_failure_stack`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.