xref: /linux/samples/kmemleak/kmemleak-test.c (revision 36ec807b627b4c0a0a382f0ae48eac7187d14b2b)
11abbef4fSHui Su // SPDX-License-Identifier: GPL-2.0-only
21abbef4fSHui Su /*
31abbef4fSHui Su  * samples/kmemleak/kmemleak-test.c
41abbef4fSHui Su  *
51abbef4fSHui Su  * Copyright (C) 2008 ARM Limited
61abbef4fSHui Su  * Written by Catalin Marinas <catalin.marinas@arm.com>
71abbef4fSHui Su  */
81abbef4fSHui Su 
91abbef4fSHui Su #define pr_fmt(fmt) "kmemleak: " fmt
101abbef4fSHui Su 
111abbef4fSHui Su #include <linux/init.h>
121abbef4fSHui Su #include <linux/kernel.h>
131abbef4fSHui Su #include <linux/module.h>
141abbef4fSHui Su #include <linux/slab.h>
151abbef4fSHui Su #include <linux/vmalloc.h>
161abbef4fSHui Su #include <linux/list.h>
171abbef4fSHui Su #include <linux/percpu.h>
181abbef4fSHui Su #include <linux/fdtable.h>
191abbef4fSHui Su 
201abbef4fSHui Su #include <linux/kmemleak.h>
211abbef4fSHui Su 
221abbef4fSHui Su struct test_node {
231abbef4fSHui Su 	long header[25];
241abbef4fSHui Su 	struct list_head list;
251abbef4fSHui Su 	long footer[25];
261abbef4fSHui Su };
271abbef4fSHui Su 
281abbef4fSHui Su static LIST_HEAD(test_list);
291abbef4fSHui Su static DEFINE_PER_CPU(void *, kmemleak_test_pointer);
301abbef4fSHui Su 
311abbef4fSHui Su /*
321abbef4fSHui Su  * Some very simple testing. This function needs to be extended for
331abbef4fSHui Su  * proper testing.
341abbef4fSHui Su  */
35dcb8cbb5SJim Cromie static int kmemleak_test_init(void)
361abbef4fSHui Su {
371abbef4fSHui Su 	struct test_node *elem;
381abbef4fSHui Su 	int i;
391abbef4fSHui Su 
401abbef4fSHui Su 	pr_info("Kmemleak testing\n");
411abbef4fSHui Su 
421abbef4fSHui Su 	/* make some orphan objects */
431abbef4fSHui Su 	pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
441abbef4fSHui Su 	pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
451abbef4fSHui Su 	pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
461abbef4fSHui Su 	pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
471abbef4fSHui Su 	pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
481abbef4fSHui Su 	pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
491abbef4fSHui Su 	pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
501abbef4fSHui Su 	pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
511abbef4fSHui Su #ifndef CONFIG_MODULES
521abbef4fSHui Su 	pr_info("kmem_cache_alloc(files_cachep) = %p\n",
531abbef4fSHui Su 		kmem_cache_alloc(files_cachep, GFP_KERNEL));
541abbef4fSHui Su 	pr_info("kmem_cache_alloc(files_cachep) = %p\n",
551abbef4fSHui Su 		kmem_cache_alloc(files_cachep, GFP_KERNEL));
561abbef4fSHui Su #endif
571abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
581abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
591abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
601abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
611abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
621abbef4fSHui Su 
631abbef4fSHui Su 	/*
641abbef4fSHui Su 	 * Add elements to a list. They should only appear as orphan
651abbef4fSHui Su 	 * after the module is removed.
661abbef4fSHui Su 	 */
671abbef4fSHui Su 	for (i = 0; i < 10; i++) {
681abbef4fSHui Su 		elem = kzalloc(sizeof(*elem), GFP_KERNEL);
691abbef4fSHui Su 		pr_info("kzalloc(sizeof(*elem)) = %p\n", elem);
701abbef4fSHui Su 		if (!elem)
711abbef4fSHui Su 			return -ENOMEM;
721abbef4fSHui Su 		INIT_LIST_HEAD(&elem->list);
731abbef4fSHui Su 		list_add_tail(&elem->list, &test_list);
741abbef4fSHui Su 	}
751abbef4fSHui Su 
761abbef4fSHui Su 	for_each_possible_cpu(i) {
771abbef4fSHui Su 		per_cpu(kmemleak_test_pointer, i) = kmalloc(129, GFP_KERNEL);
781abbef4fSHui Su 		pr_info("kmalloc(129) = %p\n",
791abbef4fSHui Su 			per_cpu(kmemleak_test_pointer, i));
801abbef4fSHui Su 	}
811abbef4fSHui Su 
821abbef4fSHui Su 	return 0;
831abbef4fSHui Su }
841abbef4fSHui Su module_init(kmemleak_test_init);
851abbef4fSHui Su 
861abbef4fSHui Su static void __exit kmemleak_test_exit(void)
871abbef4fSHui Su {
881abbef4fSHui Su 	struct test_node *elem, *tmp;
891abbef4fSHui Su 
901abbef4fSHui Su 	/*
911abbef4fSHui Su 	 * Remove the list elements without actually freeing the
921abbef4fSHui Su 	 * memory.
931abbef4fSHui Su 	 */
941abbef4fSHui Su 	list_for_each_entry_safe(elem, tmp, &test_list, list)
951abbef4fSHui Su 		list_del(&elem->list);
961abbef4fSHui Su }
971abbef4fSHui Su module_exit(kmemleak_test_exit);
981abbef4fSHui Su 
99*656fe3eeSJeff Johnson MODULE_DESCRIPTION("Sample module to leak memory for kmemleak testing");
1001abbef4fSHui Su MODULE_LICENSE("GPL");
101