xref: /linux/samples/kmemleak/kmemleak-test.c (revision 1abbef4f51724fb11f09adf0e75275f7cb422a8a)
1*1abbef4fSHui Su // SPDX-License-Identifier: GPL-2.0-only
2*1abbef4fSHui Su /*
3*1abbef4fSHui Su  * samples/kmemleak/kmemleak-test.c
4*1abbef4fSHui Su  *
5*1abbef4fSHui Su  * Copyright (C) 2008 ARM Limited
6*1abbef4fSHui Su  * Written by Catalin Marinas <catalin.marinas@arm.com>
7*1abbef4fSHui Su  */
8*1abbef4fSHui Su 
9*1abbef4fSHui Su #define pr_fmt(fmt) "kmemleak: " fmt
10*1abbef4fSHui Su 
11*1abbef4fSHui Su #include <linux/init.h>
12*1abbef4fSHui Su #include <linux/kernel.h>
13*1abbef4fSHui Su #include <linux/module.h>
14*1abbef4fSHui Su #include <linux/slab.h>
15*1abbef4fSHui Su #include <linux/vmalloc.h>
16*1abbef4fSHui Su #include <linux/list.h>
17*1abbef4fSHui Su #include <linux/percpu.h>
18*1abbef4fSHui Su #include <linux/fdtable.h>
19*1abbef4fSHui Su 
20*1abbef4fSHui Su #include <linux/kmemleak.h>
21*1abbef4fSHui Su 
22*1abbef4fSHui Su struct test_node {
23*1abbef4fSHui Su 	long header[25];
24*1abbef4fSHui Su 	struct list_head list;
25*1abbef4fSHui Su 	long footer[25];
26*1abbef4fSHui Su };
27*1abbef4fSHui Su 
28*1abbef4fSHui Su static LIST_HEAD(test_list);
29*1abbef4fSHui Su static DEFINE_PER_CPU(void *, kmemleak_test_pointer);
30*1abbef4fSHui Su 
31*1abbef4fSHui Su /*
32*1abbef4fSHui Su  * Some very simple testing. This function needs to be extended for
33*1abbef4fSHui Su  * proper testing.
34*1abbef4fSHui Su  */
35*1abbef4fSHui Su static int __init kmemleak_test_init(void)
36*1abbef4fSHui Su {
37*1abbef4fSHui Su 	struct test_node *elem;
38*1abbef4fSHui Su 	int i;
39*1abbef4fSHui Su 
40*1abbef4fSHui Su 	pr_info("Kmemleak testing\n");
41*1abbef4fSHui Su 
42*1abbef4fSHui Su 	/* make some orphan objects */
43*1abbef4fSHui Su 	pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
44*1abbef4fSHui Su 	pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
45*1abbef4fSHui Su 	pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
46*1abbef4fSHui Su 	pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
47*1abbef4fSHui Su 	pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
48*1abbef4fSHui Su 	pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
49*1abbef4fSHui Su 	pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
50*1abbef4fSHui Su 	pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
51*1abbef4fSHui Su #ifndef CONFIG_MODULES
52*1abbef4fSHui Su 	pr_info("kmem_cache_alloc(files_cachep) = %p\n",
53*1abbef4fSHui Su 		kmem_cache_alloc(files_cachep, GFP_KERNEL));
54*1abbef4fSHui Su 	pr_info("kmem_cache_alloc(files_cachep) = %p\n",
55*1abbef4fSHui Su 		kmem_cache_alloc(files_cachep, GFP_KERNEL));
56*1abbef4fSHui Su #endif
57*1abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
58*1abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
59*1abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
60*1abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
61*1abbef4fSHui Su 	pr_info("vmalloc(64) = %p\n", vmalloc(64));
62*1abbef4fSHui Su 
63*1abbef4fSHui Su 	/*
64*1abbef4fSHui Su 	 * Add elements to a list. They should only appear as orphan
65*1abbef4fSHui Su 	 * after the module is removed.
66*1abbef4fSHui Su 	 */
67*1abbef4fSHui Su 	for (i = 0; i < 10; i++) {
68*1abbef4fSHui Su 		elem = kzalloc(sizeof(*elem), GFP_KERNEL);
69*1abbef4fSHui Su 		pr_info("kzalloc(sizeof(*elem)) = %p\n", elem);
70*1abbef4fSHui Su 		if (!elem)
71*1abbef4fSHui Su 			return -ENOMEM;
72*1abbef4fSHui Su 		INIT_LIST_HEAD(&elem->list);
73*1abbef4fSHui Su 		list_add_tail(&elem->list, &test_list);
74*1abbef4fSHui Su 	}
75*1abbef4fSHui Su 
76*1abbef4fSHui Su 	for_each_possible_cpu(i) {
77*1abbef4fSHui Su 		per_cpu(kmemleak_test_pointer, i) = kmalloc(129, GFP_KERNEL);
78*1abbef4fSHui Su 		pr_info("kmalloc(129) = %p\n",
79*1abbef4fSHui Su 			per_cpu(kmemleak_test_pointer, i));
80*1abbef4fSHui Su 	}
81*1abbef4fSHui Su 
82*1abbef4fSHui Su 	return 0;
83*1abbef4fSHui Su }
84*1abbef4fSHui Su module_init(kmemleak_test_init);
85*1abbef4fSHui Su 
86*1abbef4fSHui Su static void __exit kmemleak_test_exit(void)
87*1abbef4fSHui Su {
88*1abbef4fSHui Su 	struct test_node *elem, *tmp;
89*1abbef4fSHui Su 
90*1abbef4fSHui Su 	/*
91*1abbef4fSHui Su 	 * Remove the list elements without actually freeing the
92*1abbef4fSHui Su 	 * memory.
93*1abbef4fSHui Su 	 */
94*1abbef4fSHui Su 	list_for_each_entry_safe(elem, tmp, &test_list, list)
95*1abbef4fSHui Su 		list_del(&elem->list);
96*1abbef4fSHui Su }
97*1abbef4fSHui Su module_exit(kmemleak_test_exit);
98*1abbef4fSHui Su 
99*1abbef4fSHui Su MODULE_LICENSE("GPL");
100