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.

Dependency Surface

Detected Declarations

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

Implementation Notes