mm/kmemleak.c

Source file repositories/reference/linux-study-clean/mm/kmemleak.c

File Facts

System
Linux kernel
Corpus path
mm/kmemleak.c
Extension
.c
Size
71605 bytes
Lines
2477
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 kmemleak_fops = {
	.owner		= THIS_MODULE,
	.open		= kmemleak_open,
	.read		= seq_read,
	.write		= kmemleak_write,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static void __kmemleak_do_cleanup(void)
{
	struct kmemleak_object *object, *tmp;
	unsigned int cnt = 0;

	/*
	 * Kmemleak has already been disabled, no need for RCU list traversal
	 * or kmemleak_lock held.
	 */
	list_for_each_entry_safe(object, tmp, &object_list, object_list) {
		__remove_object(object);
		__delete_object(object);

		/* Call cond_resched() once per 64 iterations to avoid soft lockup */
		if (!(++cnt & 0x3f))
			cond_resched();
	}
}

/*
 * Stop the memory scanning thread and free the kmemleak internal objects if
 * no previous scan thread (otherwise, kmemleak may still have some useful
 * information on memory leaks).
 */
static void kmemleak_do_cleanup(struct work_struct *work)
{
	stop_scan_thread();

	mutex_lock(&scan_mutex);
	/*
	 * Once it is made sure that kmemleak_scan has stopped, it is safe to no
	 * longer track object freeing. Ordering of the scan thread stopping and
	 * the memory accesses below is guaranteed by the kthread_stop()
	 * function.
	 */
	kmemleak_free_enabled = 0;
	mutex_unlock(&scan_mutex);

	if (!kmemleak_found_leaks)
		__kmemleak_do_cleanup();
	else
		pr_info("Kmemleak disabled without freeing internal data. Reclaim the memory with \"echo clear > /sys/kernel/debug/kmemleak\".\n");
}

static DECLARE_WORK(cleanup_work, kmemleak_do_cleanup);

/*
 * Disable kmemleak. No memory allocation/freeing will be traced once this
 * function is called. Disabling kmemleak is an irreversible operation.
 */
static void kmemleak_disable(void)
{
	/* atomically check whether it was already invoked */
	if (cmpxchg(&kmemleak_error, 0, 1))
		return;

	/* stop any memory operation tracing */
	kmemleak_enabled = 0;

	/* check whether it is too early for a kernel thread */
	if (kmemleak_late_initialized)
		schedule_work(&cleanup_work);
	else
		kmemleak_free_enabled = 0;

	pr_info("Kernel memory leak detector disabled\n");
}

/*
 * Allow boot-time kmemleak disabling (enabled by default).
 */
static int __init kmemleak_boot_config(char *str)
{
	if (!str)
		return -EINVAL;
	if (strcmp(str, "off") == 0)
		kmemleak_disable();
	else if (strcmp(str, "on") == 0) {
		kmemleak_skip_disable = 1;
		stack_depot_request_early_init();
	}

Annotation

Implementation Notes