Blame view

mm/kmemleak.c 59.5 KB
450515395   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2
3
4
5
6
7
  /*
   * mm/kmemleak.c
   *
   * Copyright (C) 2008 ARM Limited
   * Written by Catalin Marinas <catalin.marinas@arm.com>
   *
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
8
   * For more information on the algorithm and kmemleak usage, please see
22901c6c9   Andreas Platschek   kmemleak: fix ref...
9
   * Documentation/dev-tools/kmemleak.rst.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
10
11
12
13
14
15
16
17
18
   *
   * Notes on locking
   * ----------------
   *
   * The following locks and mutexes are used by kmemleak:
   *
   * - kmemleak_lock (rwlock): protects the object_list modifications and
   *   accesses to the object_tree_root. The object_list is the main list
   *   holding the metadata (struct kmemleak_object) for the allocated memory
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
19
   *   blocks. The object_tree_root is a red black tree used to look-up
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
   *   metadata based on a pointer to the corresponding memory block.  The
   *   kmemleak_object structures are added to the object_list and
   *   object_tree_root in the create_object() function called from the
   *   kmemleak_alloc() callback and removed in delete_object() called from the
   *   kmemleak_free() callback
   * - kmemleak_object.lock (spinlock): protects a kmemleak_object. Accesses to
   *   the metadata (e.g. count) are protected by this lock. Note that some
   *   members of this structure may be protected by other means (atomic or
   *   kmemleak_lock). This lock is also held when scanning the corresponding
   *   memory block to avoid the kernel freeing it via the kmemleak_free()
   *   callback. This is less heavyweight than holding a global lock like
   *   kmemleak_lock during scanning
   * - scan_mutex (mutex): ensures that only one thread may scan the memory for
   *   unreferenced objects at a time. The gray_list contains the objects which
   *   are already referenced or marked as false positives and need to be
   *   scanned. This list is only modified during a scanning episode when the
   *   scan_mutex is held. At the end of a scan, the gray_list is always empty.
   *   Note that the kmemleak_object.use_count is incremented when an object is
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
38
39
40
41
   *   added to the gray_list and therefore cannot be freed. This mutex also
   *   prevents multiple users of the "kmemleak" debugfs file together with
   *   modifications to the memory scanning parameters including the scan_thread
   *   pointer
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
42
   *
93ada579b   Catalin Marinas   mm: kmemleak: opt...
43
   * Locks and mutexes are acquired/nested in the following order:
9d5a4c730   Catalin Marinas   mm: kmemleak: avo...
44
   *
93ada579b   Catalin Marinas   mm: kmemleak: opt...
45
46
47
48
   *   scan_mutex [-> object->lock] -> kmemleak_lock -> other_object->lock (SINGLE_DEPTH_NESTING)
   *
   * No kmemleak_lock and object->lock nesting is allowed outside scan_mutex
   * regions.
9d5a4c730   Catalin Marinas   mm: kmemleak: avo...
49
   *
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
50
51
52
53
54
55
56
   * The kmemleak_object structures have a use_count incremented or decremented
   * using the get_object()/put_object() functions. When the use_count becomes
   * 0, this count can no longer be incremented and put_object() schedules the
   * kmemleak_object freeing via an RCU callback. All calls to the get_object()
   * function must be protected by rcu_read_lock() to avoid accessing a freed
   * structure.
   */
ae281064b   Joe Perches   kmemleak: use pr_fmt
57
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
58
59
60
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/list.h>
3f07c0144   Ingo Molnar   sched/headers: Pr...
61
  #include <linux/sched/signal.h>
299300258   Ingo Molnar   sched/headers: Pr...
62
  #include <linux/sched/task.h>
68db0cf10   Ingo Molnar   sched/headers: Pr...
63
  #include <linux/sched/task_stack.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
64
65
  #include <linux/jiffies.h>
  #include <linux/delay.h>
b95f1b31b   Paul Gortmaker   mm: Map most file...
66
  #include <linux/export.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
67
  #include <linux/kthread.h>
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
68
  #include <linux/rbtree.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
69
70
71
72
73
  #include <linux/fs.h>
  #include <linux/debugfs.h>
  #include <linux/seq_file.h>
  #include <linux/cpumask.h>
  #include <linux/spinlock.h>
154221c3e   Vincent Whitchurch   kmemleak: add mod...
74
  #include <linux/module.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
75
76
77
78
79
  #include <linux/mutex.h>
  #include <linux/rcupdate.h>
  #include <linux/stacktrace.h>
  #include <linux/cache.h>
  #include <linux/percpu.h>
57c8a661d   Mike Rapoport   mm: remove includ...
80
  #include <linux/memblock.h>
9099daed9   Catalin Marinas   mm: kmemleak: avo...
81
  #include <linux/pfn.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
82
83
84
85
86
87
88
89
  #include <linux/mmzone.h>
  #include <linux/slab.h>
  #include <linux/thread_info.h>
  #include <linux/err.h>
  #include <linux/uaccess.h>
  #include <linux/string.h>
  #include <linux/nodemask.h>
  #include <linux/mm.h>
179a8100e   Catalin Marinas   kmemleak: Do no c...
90
  #include <linux/workqueue.h>
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
91
  #include <linux/crc32.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
92
93
94
  
  #include <asm/sections.h>
  #include <asm/processor.h>
60063497a   Arun Sharma   atomic: use <linu...
95
  #include <linux/atomic.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
96

e79ed2f13   Andrey Ryabinin   kmemleak: disable...
97
  #include <linux/kasan.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
98
  #include <linux/kmemleak.h>
029aeff5d   Laura Abbott   kmemleak: Add sup...
99
  #include <linux/memory_hotplug.h>
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
100
101
102
103
104
  
  /*
   * Kmemleak configuration and common defines.
   */
  #define MAX_TRACE		16	/* stack trace length */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
105
  #define MSECS_MIN_AGE		5000	/* minimum object age for reporting */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
106
107
  #define SECS_FIRST_SCAN		60	/* delay before the first scan */
  #define SECS_SCAN_WAIT		600	/* subsequent auto scanning delay */
af98603da   Catalin Marinas   kmemleak: Allow r...
108
  #define MAX_SCAN_SIZE		4096	/* maximum size of a scanned block */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
109
110
  
  #define BYTES_PER_POINTER	sizeof(void *)
216c04b0d   Catalin Marinas   kmemleak: Only us...
111
  /* GFP bitmask for kmemleak internal allocations */
20b5c3039   Vladimir Davydov   Revert "gfp: add ...
112
  #define gfp_kmemleak_mask(gfp)	(((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \
6ae4bd1f0   Catalin Marinas   kmemleak: Allow k...
113
  				 __GFP_NORETRY | __GFP_NOMEMALLOC | \
df9576def   Yang Shi   Revert "kmemleak:...
114
  				 __GFP_NOWARN)
216c04b0d   Catalin Marinas   kmemleak: Only us...
115

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
116
117
118
  /* scanning area inside a memory block */
  struct kmemleak_scan_area {
  	struct hlist_node node;
c017b4be3   Catalin Marinas   kmemleak: Simplif...
119
120
  	unsigned long start;
  	size_t size;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
121
  };
a1084c877   Luis R. Rodriguez   kmemleak: move co...
122
123
  #define KMEMLEAK_GREY	0
  #define KMEMLEAK_BLACK	-1
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
124
125
126
127
  /*
   * Structure holding the metadata for each allocated memory block.
   * Modifications to such objects should be made while holding the
   * object->lock. Insertions or deletions from object_list, gray_list or
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
128
   * rb_node are already protected by the corresponding locks or mutex (see
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
129
130
131
132
133
   * the notes on locking above). These objects are reference-counted
   * (use_count) and freed using the RCU mechanism.
   */
  struct kmemleak_object {
  	spinlock_t lock;
f66abf09e   Catalin Marinas   mm: kmemleak: sli...
134
  	unsigned int flags;		/* object status flags */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
135
136
  	struct list_head object_list;
  	struct list_head gray_list;
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
137
  	struct rb_node rb_node;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
138
139
140
141
142
  	struct rcu_head rcu;		/* object_list lockless traversal */
  	/* object usage count; object freed when use_count == 0 */
  	atomic_t use_count;
  	unsigned long pointer;
  	size_t size;
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
143
144
  	/* pass surplus references to this pointer */
  	unsigned long excess_ref;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
145
146
147
148
  	/* minimum number of a pointers found before it is considered leak */
  	int min_count;
  	/* the total number of pointers found pointing to this object */
  	int count;
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
149
150
  	/* checksum for detecting modified objects */
  	u32 checksum;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  	/* memory ranges to be scanned inside an object (empty for all) */
  	struct hlist_head area_list;
  	unsigned long trace[MAX_TRACE];
  	unsigned int trace_len;
  	unsigned long jiffies;		/* creation timestamp */
  	pid_t pid;			/* pid of the current task */
  	char comm[TASK_COMM_LEN];	/* executable name */
  };
  
  /* flag representing the memory block allocation status */
  #define OBJECT_ALLOCATED	(1 << 0)
  /* flag set after the first reporting of an unreference object */
  #define OBJECT_REPORTED		(1 << 1)
  /* flag set to not scan the object */
  #define OBJECT_NO_SCAN		(1 << 2)
154221c3e   Vincent Whitchurch   kmemleak: add mod...
166
  #define HEX_PREFIX		"    "
0494e0828   Sergey Senozhatsky   kmemleak: Printin...
167
168
169
170
171
172
173
174
  /* number of bytes to print per line; must be 16 or 32 */
  #define HEX_ROW_SIZE		16
  /* number of bytes to print at a time (1, 2, 4, 8) */
  #define HEX_GROUP_SIZE		1
  /* include ASCII after the hex output */
  #define HEX_ASCII		1
  /* max number of lines to be printed */
  #define HEX_MAX_LINES		2
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
175
176
177
178
  /* the list of all allocated objects */
  static LIST_HEAD(object_list);
  /* the list of gray-colored objects (see color_gray comment below) */
  static LIST_HEAD(gray_list);
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
179
180
181
  /* search tree for object boundaries */
  static struct rb_root object_tree_root = RB_ROOT;
  /* rw_lock protecting the access to object_list and object_tree_root */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
182
183
184
185
186
187
188
  static DEFINE_RWLOCK(kmemleak_lock);
  
  /* allocation caches for kmemleak internal data */
  static struct kmem_cache *object_cache;
  static struct kmem_cache *scan_area_cache;
  
  /* set if tracing memory operations is enabled */
8910ae896   Li Zefan   kmemleak: change ...
189
  static int kmemleak_enabled;
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
190
191
  /* same as above but only for the kmemleak_free() callback */
  static int kmemleak_free_enabled;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
192
  /* set in the late_initcall if there were no errors */
8910ae896   Li Zefan   kmemleak: change ...
193
  static int kmemleak_initialized;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
194
  /* enables or disables early logging of the memory operations */
8910ae896   Li Zefan   kmemleak: change ...
195
  static int kmemleak_early_log = 1;
5f79020cb   Catalin Marinas   kmemleak: Show wh...
196
  /* set if a kmemleak warning was issued */
8910ae896   Li Zefan   kmemleak: change ...
197
  static int kmemleak_warning;
5f79020cb   Catalin Marinas   kmemleak: Show wh...
198
  /* set if a fatal kmemleak error has occurred */
8910ae896   Li Zefan   kmemleak: change ...
199
  static int kmemleak_error;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
200
201
202
203
  
  /* minimum and maximum address that may be valid pointers */
  static unsigned long min_addr = ULONG_MAX;
  static unsigned long max_addr;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
204
  static struct task_struct *scan_thread;
acf4968ec   Catalin Marinas   kmemleak: Slightl...
205
  /* used to avoid reporting of recently allocated objects */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
206
  static unsigned long jiffies_min_age;
acf4968ec   Catalin Marinas   kmemleak: Slightl...
207
  static unsigned long jiffies_last_scan;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
208
209
210
  /* delay between automatic memory scannings */
  static signed long jiffies_scan_wait;
  /* enables or disables the task stacks scanning */
e0a2a1601   Catalin Marinas   kmemleak: Enable ...
211
  static int kmemleak_stack_scan = 1;
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
212
  /* protects the memory scanning, parameters and debug/kmemleak file access */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
213
  static DEFINE_MUTEX(scan_mutex);
ab0155a22   Jason Baron   kmemleak: Introdu...
214
215
  /* setting kmemleak=on, will set this var, skipping the disable */
  static int kmemleak_skip_disable;
dc9b3f424   Li Zefan   kmemleak: free in...
216
217
  /* If there are leaks that can be reported */
  static bool kmemleak_found_leaks;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
218

154221c3e   Vincent Whitchurch   kmemleak: add mod...
219
220
  static bool kmemleak_verbose;
  module_param_named(verbose, kmemleak_verbose, bool, 0600);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
221
  /*
2030117d2   Catalin Marinas   kmemleak: Fix som...
222
   * Early object allocation/freeing logging. Kmemleak is initialized after the
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
223
   * kernel allocator. However, both the kernel allocator and kmemleak may
2030117d2   Catalin Marinas   kmemleak: Fix som...
224
   * allocate memory blocks which need to be tracked. Kmemleak defines an
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
225
226
227
228
229
230
231
   * arbitrary buffer to hold the allocation/freeing information before it is
   * fully initialized.
   */
  
  /* kmemleak operation type for early logging */
  enum {
  	KMEMLEAK_ALLOC,
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
232
  	KMEMLEAK_ALLOC_PERCPU,
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
233
  	KMEMLEAK_FREE,
53238a60d   Catalin Marinas   kmemleak: Allow p...
234
  	KMEMLEAK_FREE_PART,
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
235
  	KMEMLEAK_FREE_PERCPU,
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
236
237
238
  	KMEMLEAK_NOT_LEAK,
  	KMEMLEAK_IGNORE,
  	KMEMLEAK_SCAN_AREA,
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
239
240
  	KMEMLEAK_NO_SCAN,
  	KMEMLEAK_SET_EXCESS_REF
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
241
242
243
244
245
246
247
248
  };
  
  /*
   * Structure holding the information passed to kmemleak callbacks during the
   * early logging.
   */
  struct early_log {
  	int op_type;			/* kmemleak operation type */
f66abf09e   Catalin Marinas   mm: kmemleak: sli...
249
  	int min_count;			/* minimum reference count */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
250
  	const void *ptr;		/* allocated/freed memory block */
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
251
252
253
254
  	union {
  		size_t size;		/* memory block size */
  		unsigned long excess_ref; /* surplus reference passing */
  	};
fd6789675   Catalin Marinas   kmemleak: Save th...
255
256
  	unsigned long trace[MAX_TRACE];	/* stack trace */
  	unsigned int trace_len;		/* stack trace length */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
257
258
259
  };
  
  /* early logging buffer and current position */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
260
261
262
  static struct early_log
  	early_log[CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE] __initdata;
  static int crt_early_log __initdata;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
263
264
265
266
267
268
  
  static void kmemleak_disable(void);
  
  /*
   * Print a warning and dump the stack trace.
   */
5f79020cb   Catalin Marinas   kmemleak: Show wh...
269
  #define kmemleak_warn(x...)	do {		\
598d80914   Joe Perches   mm: convert pr_wa...
270
  	pr_warn(x);				\
5f79020cb   Catalin Marinas   kmemleak: Show wh...
271
  	dump_stack();				\
8910ae896   Li Zefan   kmemleak: change ...
272
  	kmemleak_warning = 1;			\
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
273
274
275
  } while (0)
  
  /*
25985edce   Lucas De Marchi   Fix common misspe...
276
   * Macro invoked when a serious kmemleak condition occurred and cannot be
2030117d2   Catalin Marinas   kmemleak: Fix som...
277
   * recovered from. Kmemleak will be disabled and further allocation/freeing
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
278
279
   * tracing no longer available.
   */
000814f44   Catalin Marinas   kmemleak: Rename ...
280
  #define kmemleak_stop(x...)	do {	\
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
281
282
283
  	kmemleak_warn(x);		\
  	kmemleak_disable();		\
  } while (0)
154221c3e   Vincent Whitchurch   kmemleak: add mod...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  #define warn_or_seq_printf(seq, fmt, ...)	do {	\
  	if (seq)					\
  		seq_printf(seq, fmt, ##__VA_ARGS__);	\
  	else						\
  		pr_warn(fmt, ##__VA_ARGS__);		\
  } while (0)
  
  static void warn_or_seq_hex_dump(struct seq_file *seq, int prefix_type,
  				 int rowsize, int groupsize, const void *buf,
  				 size_t len, bool ascii)
  {
  	if (seq)
  		seq_hex_dump(seq, HEX_PREFIX, prefix_type, rowsize, groupsize,
  			     buf, len, ascii);
  	else
  		print_hex_dump(KERN_WARNING, pr_fmt(HEX_PREFIX), prefix_type,
  			       rowsize, groupsize, buf, len, ascii);
  }
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
302
  /*
0494e0828   Sergey Senozhatsky   kmemleak: Printin...
303
304
305
306
307
308
309
310
311
   * Printing of the objects hex dump to the seq file. The number of lines to be
   * printed is limited to HEX_MAX_LINES to prevent seq file spamming. The
   * actual number of printed bytes depends on HEX_ROW_SIZE. It must be called
   * with the object->lock held.
   */
  static void hex_dump_object(struct seq_file *seq,
  			    struct kmemleak_object *object)
  {
  	const u8 *ptr = (const u8 *)object->pointer;
6fc37c490   Andy Shevchenko   kmemleak: use seq...
312
  	size_t len;
0494e0828   Sergey Senozhatsky   kmemleak: Printin...
313
314
  
  	/* limit the number of lines to HEX_MAX_LINES */
6fc37c490   Andy Shevchenko   kmemleak: use seq...
315
  	len = min_t(size_t, object->size, HEX_MAX_LINES * HEX_ROW_SIZE);
0494e0828   Sergey Senozhatsky   kmemleak: Printin...
316

154221c3e   Vincent Whitchurch   kmemleak: add mod...
317
318
  	warn_or_seq_printf(seq, "  hex dump (first %zu bytes):
  ", len);
5c335fe02   Dmitry Vyukov   mm: prevent KASAN...
319
  	kasan_disable_current();
154221c3e   Vincent Whitchurch   kmemleak: add mod...
320
321
  	warn_or_seq_hex_dump(seq, DUMP_PREFIX_NONE, HEX_ROW_SIZE,
  			     HEX_GROUP_SIZE, ptr, len, HEX_ASCII);
5c335fe02   Dmitry Vyukov   mm: prevent KASAN...
322
  	kasan_enable_current();
0494e0828   Sergey Senozhatsky   kmemleak: Printin...
323
324
325
  }
  
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
326
327
328
329
330
331
332
333
334
   * Object colors, encoded with count and min_count:
   * - white - orphan object, not enough references to it (count < min_count)
   * - gray  - not orphan, not marked as false positive (min_count == 0) or
   *		sufficient references to it (count >= min_count)
   * - black - ignore, it doesn't contain references (e.g. text section)
   *		(min_count == -1). No function defined for this color.
   * Newly created objects don't have any color assigned (object->count == -1)
   * before the next memory scan when they become white.
   */
4a558dd6f   Luis R. Rodriguez   kmemleak: use boo...
335
  static bool color_white(const struct kmemleak_object *object)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
336
  {
a1084c877   Luis R. Rodriguez   kmemleak: move co...
337
338
  	return object->count != KMEMLEAK_BLACK &&
  		object->count < object->min_count;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
339
  }
4a558dd6f   Luis R. Rodriguez   kmemleak: use boo...
340
  static bool color_gray(const struct kmemleak_object *object)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
341
  {
a1084c877   Luis R. Rodriguez   kmemleak: move co...
342
343
  	return object->min_count != KMEMLEAK_BLACK &&
  		object->count >= object->min_count;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
344
345
346
  }
  
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
347
348
349
350
   * Objects are considered unreferenced only if their color is white, they have
   * not be deleted and have a minimum age to avoid false positives caused by
   * pointers temporarily stored in CPU registers.
   */
4a558dd6f   Luis R. Rodriguez   kmemleak: use boo...
351
  static bool unreferenced_object(struct kmemleak_object *object)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
352
  {
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
353
  	return (color_white(object) && object->flags & OBJECT_ALLOCATED) &&
acf4968ec   Catalin Marinas   kmemleak: Slightl...
354
355
  		time_before_eq(object->jiffies + jiffies_min_age,
  			       jiffies_last_scan);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
356
357
358
  }
  
  /*
bab4a34af   Catalin Marinas   kmemleak: Simplif...
359
360
   * Printing of the unreferenced objects information to the seq file. The
   * print_unreferenced function must be called with the object->lock held.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
361
   */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
362
363
364
365
  static void print_unreferenced(struct seq_file *seq,
  			       struct kmemleak_object *object)
  {
  	int i;
fefdd336b   Catalin Marinas   kmemleak: Show th...
366
  	unsigned int msecs_age = jiffies_to_msecs(jiffies - object->jiffies);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
367

154221c3e   Vincent Whitchurch   kmemleak: add mod...
368
369
  	warn_or_seq_printf(seq, "unreferenced object 0x%08lx (size %zu):
  ",
bab4a34af   Catalin Marinas   kmemleak: Simplif...
370
  		   object->pointer, object->size);
154221c3e   Vincent Whitchurch   kmemleak: add mod...
371
372
  	warn_or_seq_printf(seq, "  comm \"%s\", pid %d, jiffies %lu (age %d.%03ds)
  ",
fefdd336b   Catalin Marinas   kmemleak: Show th...
373
374
  		   object->comm, object->pid, object->jiffies,
  		   msecs_age / 1000, msecs_age % 1000);
0494e0828   Sergey Senozhatsky   kmemleak: Printin...
375
  	hex_dump_object(seq, object);
154221c3e   Vincent Whitchurch   kmemleak: add mod...
376
377
  	warn_or_seq_printf(seq, "  backtrace:
  ");
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
378
379
380
  
  	for (i = 0; i < object->trace_len; i++) {
  		void *ptr = (void *)object->trace[i];
154221c3e   Vincent Whitchurch   kmemleak: add mod...
381
382
  		warn_or_seq_printf(seq, "    [<%p>] %pS
  ", ptr, ptr);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
383
384
385
386
387
388
389
390
391
392
  	}
  }
  
  /*
   * Print the kmemleak_object information. This function is used mainly for
   * debugging special cases when kmemleak operations. It must be called with
   * the object->lock held.
   */
  static void dump_object_info(struct kmemleak_object *object)
  {
ae281064b   Joe Perches   kmemleak: use pr_fmt
393
394
  	pr_notice("Object 0x%08lx (size %zu):
  ",
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
395
  		  object->pointer, object->size);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
396
397
398
399
400
401
402
  	pr_notice("  comm \"%s\", pid %d, jiffies %lu
  ",
  		  object->comm, object->pid, object->jiffies);
  	pr_notice("  min_count = %d
  ", object->min_count);
  	pr_notice("  count = %d
  ", object->count);
f66abf09e   Catalin Marinas   mm: kmemleak: sli...
403
404
  	pr_notice("  flags = 0x%x
  ", object->flags);
aae0ad7ae   Jianpeng Ma   mm/kmemleak.c: us...
405
406
  	pr_notice("  checksum = %u
  ", object->checksum);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
407
408
  	pr_notice("  backtrace:
  ");
07984aad1   Thomas Gleixner   mm/kmemleak: Simp...
409
  	stack_trace_print(object->trace, object->trace_len, 4);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
410
411
412
  }
  
  /*
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
413
   * Look-up a memory block metadata (kmemleak_object) in the object search
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
414
415
416
417
418
419
   * tree based on a pointer value. If alias is 0, only values pointing to the
   * beginning of the memory block are allowed. The kmemleak_lock must be held
   * when calling this function.
   */
  static struct kmemleak_object *lookup_object(unsigned long ptr, int alias)
  {
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
420
421
422
423
424
425
426
427
428
429
430
431
  	struct rb_node *rb = object_tree_root.rb_node;
  
  	while (rb) {
  		struct kmemleak_object *object =
  			rb_entry(rb, struct kmemleak_object, rb_node);
  		if (ptr < object->pointer)
  			rb = object->rb_node.rb_left;
  		else if (object->pointer + object->size <= ptr)
  			rb = object->rb_node.rb_right;
  		else if (object->pointer == ptr || alias)
  			return object;
  		else {
5f79020cb   Catalin Marinas   kmemleak: Show wh...
432
433
434
  			kmemleak_warn("Found object by alias at 0x%08lx
  ",
  				      ptr);
a7686a45c   Catalin Marinas   kmemleak: Show mo...
435
  			dump_object_info(object);
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
436
  			break;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
437
  		}
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
438
439
  	}
  	return NULL;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
  }
  
  /*
   * Increment the object use_count. Return 1 if successful or 0 otherwise. Note
   * that once an object's use_count reached 0, the RCU freeing was already
   * registered and the object should no longer be used. This function must be
   * called under the protection of rcu_read_lock().
   */
  static int get_object(struct kmemleak_object *object)
  {
  	return atomic_inc_not_zero(&object->use_count);
  }
  
  /*
   * RCU callback to free a kmemleak_object.
   */
  static void free_object_rcu(struct rcu_head *rcu)
  {
b67bfe0d4   Sasha Levin   hlist: drop the n...
458
  	struct hlist_node *tmp;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
459
460
461
462
463
464
465
466
  	struct kmemleak_scan_area *area;
  	struct kmemleak_object *object =
  		container_of(rcu, struct kmemleak_object, rcu);
  
  	/*
  	 * Once use_count is 0 (guaranteed by put_object), there is no other
  	 * code accessing this object, hence no need for locking.
  	 */
b67bfe0d4   Sasha Levin   hlist: drop the n...
467
468
  	hlist_for_each_entry_safe(area, tmp, &object->area_list, node) {
  		hlist_del(&area->node);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  		kmem_cache_free(scan_area_cache, area);
  	}
  	kmem_cache_free(object_cache, object);
  }
  
  /*
   * Decrement the object use_count. Once the count is 0, free the object using
   * an RCU callback. Since put_object() may be called via the kmemleak_free() ->
   * delete_object() path, the delayed RCU freeing ensures that there is no
   * recursive call to the kernel allocator. Lock-less RCU object_list traversal
   * is also possible.
   */
  static void put_object(struct kmemleak_object *object)
  {
  	if (!atomic_dec_and_test(&object->use_count))
  		return;
  
  	/* should only get here after delete_object was called */
  	WARN_ON(object->flags & OBJECT_ALLOCATED);
  
  	call_rcu(&object->rcu, free_object_rcu);
  }
  
  /*
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
493
   * Look up an object in the object search tree and increase its use_count.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
494
495
496
497
   */
  static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias)
  {
  	unsigned long flags;
9fbed2540   Alexey Klimov   mm/kmemleak.c: re...
498
  	struct kmemleak_object *object;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
499
500
501
  
  	rcu_read_lock();
  	read_lock_irqsave(&kmemleak_lock, flags);
93ada579b   Catalin Marinas   mm: kmemleak: opt...
502
  	object = lookup_object(ptr, alias);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
503
504
505
506
507
508
509
510
511
512
513
  	read_unlock_irqrestore(&kmemleak_lock, flags);
  
  	/* check whether the object is still available */
  	if (object && !get_object(object))
  		object = NULL;
  	rcu_read_unlock();
  
  	return object;
  }
  
  /*
e781a9ab4   Catalin Marinas   mm: kmemleak: fix...
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
   * Look up an object in the object search tree and remove it from both
   * object_tree_root and object_list. The returned object's use_count should be
   * at least 1, as initially set by create_object().
   */
  static struct kmemleak_object *find_and_remove_object(unsigned long ptr, int alias)
  {
  	unsigned long flags;
  	struct kmemleak_object *object;
  
  	write_lock_irqsave(&kmemleak_lock, flags);
  	object = lookup_object(ptr, alias);
  	if (object) {
  		rb_erase(&object->rb_node, &object_tree_root);
  		list_del_rcu(&object->object_list);
  	}
  	write_unlock_irqrestore(&kmemleak_lock, flags);
  
  	return object;
  }
  
  /*
fd6789675   Catalin Marinas   kmemleak: Save th...
535
536
537
538
   * Save stack trace to the given array of MAX_TRACE size.
   */
  static int __save_stack_trace(unsigned long *trace)
  {
07984aad1   Thomas Gleixner   mm/kmemleak: Simp...
539
  	return stack_trace_save(trace, MAX_TRACE, 2);
fd6789675   Catalin Marinas   kmemleak: Save th...
540
541
542
  }
  
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
543
544
545
   * Create the metadata (struct kmemleak_object) corresponding to an allocated
   * memory block and add it to the object_list and object_tree_root.
   */
fd6789675   Catalin Marinas   kmemleak: Save th...
546
547
  static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
  					     int min_count, gfp_t gfp)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
548
549
  {
  	unsigned long flags;
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
550
551
  	struct kmemleak_object *object, *parent;
  	struct rb_node **link, *rb_parent;
a2f775751   Andrey Konovalov   kmemleak: account...
552
  	unsigned long untagged_ptr;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
553

6ae4bd1f0   Catalin Marinas   kmemleak: Allow k...
554
  	object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
555
  	if (!object) {
598d80914   Joe Perches   mm: convert pr_wa...
556
557
  		pr_warn("Cannot allocate a kmemleak_object structure
  ");
6ae4bd1f0   Catalin Marinas   kmemleak: Allow k...
558
  		kmemleak_disable();
fd6789675   Catalin Marinas   kmemleak: Save th...
559
  		return NULL;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
560
561
562
563
564
565
566
  	}
  
  	INIT_LIST_HEAD(&object->object_list);
  	INIT_LIST_HEAD(&object->gray_list);
  	INIT_HLIST_HEAD(&object->area_list);
  	spin_lock_init(&object->lock);
  	atomic_set(&object->use_count, 1);
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
567
  	object->flags = OBJECT_ALLOCATED;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
568
569
  	object->pointer = ptr;
  	object->size = size;
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
570
  	object->excess_ref = 0;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
571
  	object->min_count = min_count;
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
572
  	object->count = 0;			/* white color initially */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
573
  	object->jiffies = jiffies;
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
574
  	object->checksum = 0;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
575
576
577
578
579
  
  	/* task information */
  	if (in_irq()) {
  		object->pid = 0;
  		strncpy(object->comm, "hardirq", sizeof(object->comm));
6ef905695   Dmitry Vyukov   mm/kmemleak.c: fi...
580
  	} else if (in_serving_softirq()) {
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  		object->pid = 0;
  		strncpy(object->comm, "softirq", sizeof(object->comm));
  	} else {
  		object->pid = current->pid;
  		/*
  		 * There is a small chance of a race with set_task_comm(),
  		 * however using get_task_comm() here may cause locking
  		 * dependency issues with current->alloc_lock. In the worst
  		 * case, the command line is not correct.
  		 */
  		strncpy(object->comm, current->comm, sizeof(object->comm));
  	}
  
  	/* kernel backtrace */
fd6789675   Catalin Marinas   kmemleak: Save th...
595
  	object->trace_len = __save_stack_trace(object->trace);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
596

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
597
  	write_lock_irqsave(&kmemleak_lock, flags);
0580a1819   Luis R. Rodriguez   kmemleak: fix spa...
598

a2f775751   Andrey Konovalov   kmemleak: account...
599
600
601
  	untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr);
  	min_addr = min(min_addr, untagged_ptr);
  	max_addr = max(max_addr, untagged_ptr + size);
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
602
603
604
605
606
607
608
609
610
611
  	link = &object_tree_root.rb_node;
  	rb_parent = NULL;
  	while (*link) {
  		rb_parent = *link;
  		parent = rb_entry(rb_parent, struct kmemleak_object, rb_node);
  		if (ptr + size <= parent->pointer)
  			link = &parent->rb_node.rb_left;
  		else if (parent->pointer + parent->size <= ptr)
  			link = &parent->rb_node.rb_right;
  		else {
756a025f0   Joe Perches   mm: coalesce spli...
612
613
  			kmemleak_stop("Cannot insert 0x%lx into the object search tree (overlaps existing)
  ",
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
614
  				      ptr);
9d5a4c730   Catalin Marinas   mm: kmemleak: avo...
615
616
617
618
619
  			/*
  			 * No need for parent->lock here since "parent" cannot
  			 * be freed while the kmemleak_lock is held.
  			 */
  			dump_object_info(parent);
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
620
  			kmem_cache_free(object_cache, object);
9d5a4c730   Catalin Marinas   mm: kmemleak: avo...
621
  			object = NULL;
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
622
623
  			goto out;
  		}
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
624
  	}
85d3a316c   Michel Lespinasse   kmemleak: use rbt...
625
626
  	rb_link_node(&object->rb_node, rb_parent, link);
  	rb_insert_color(&object->rb_node, &object_tree_root);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
627
628
629
  	list_add_tail_rcu(&object->object_list, &object_list);
  out:
  	write_unlock_irqrestore(&kmemleak_lock, flags);
fd6789675   Catalin Marinas   kmemleak: Save th...
630
  	return object;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
631
632
633
  }
  
  /*
e781a9ab4   Catalin Marinas   mm: kmemleak: fix...
634
   * Mark the object as not allocated and schedule RCU freeing via put_object().
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
635
   */
53238a60d   Catalin Marinas   kmemleak: Allow p...
636
  static void __delete_object(struct kmemleak_object *object)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
637
638
  {
  	unsigned long flags;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
639

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
640
  	WARN_ON(!(object->flags & OBJECT_ALLOCATED));
e781a9ab4   Catalin Marinas   mm: kmemleak: fix...
641
  	WARN_ON(atomic_read(&object->use_count) < 1);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
642
643
644
645
646
647
  
  	/*
  	 * Locking here also ensures that the corresponding memory block
  	 * cannot be freed when it is being scanned.
  	 */
  	spin_lock_irqsave(&object->lock, flags);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
648
649
650
651
652
653
  	object->flags &= ~OBJECT_ALLOCATED;
  	spin_unlock_irqrestore(&object->lock, flags);
  	put_object(object);
  }
  
  /*
53238a60d   Catalin Marinas   kmemleak: Allow p...
654
655
656
657
658
659
   * Look up the metadata (struct kmemleak_object) corresponding to ptr and
   * delete it.
   */
  static void delete_object_full(unsigned long ptr)
  {
  	struct kmemleak_object *object;
e781a9ab4   Catalin Marinas   mm: kmemleak: fix...
660
  	object = find_and_remove_object(ptr, 0);
53238a60d   Catalin Marinas   kmemleak: Allow p...
661
662
663
664
665
666
667
668
669
  	if (!object) {
  #ifdef DEBUG
  		kmemleak_warn("Freeing unknown object at 0x%08lx
  ",
  			      ptr);
  #endif
  		return;
  	}
  	__delete_object(object);
53238a60d   Catalin Marinas   kmemleak: Allow p...
670
671
672
673
674
675
676
677
678
679
680
  }
  
  /*
   * Look up the metadata (struct kmemleak_object) corresponding to ptr and
   * delete it. If the memory block is partially freed, the function may create
   * additional metadata for the remaining parts of the block.
   */
  static void delete_object_part(unsigned long ptr, size_t size)
  {
  	struct kmemleak_object *object;
  	unsigned long start, end;
e781a9ab4   Catalin Marinas   mm: kmemleak: fix...
681
  	object = find_and_remove_object(ptr, 1);
53238a60d   Catalin Marinas   kmemleak: Allow p...
682
683
  	if (!object) {
  #ifdef DEBUG
756a025f0   Joe Perches   mm: coalesce spli...
684
685
686
  		kmemleak_warn("Partially freeing unknown object at 0x%08lx (size %zu)
  ",
  			      ptr, size);
53238a60d   Catalin Marinas   kmemleak: Allow p...
687
688
689
  #endif
  		return;
  	}
53238a60d   Catalin Marinas   kmemleak: Allow p...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
  
  	/*
  	 * Create one or two objects that may result from the memory block
  	 * split. Note that partial freeing is only done by free_bootmem() and
  	 * this happens before kmemleak_init() is called. The path below is
  	 * only executed during early log recording in kmemleak_init(), so
  	 * GFP_KERNEL is enough.
  	 */
  	start = object->pointer;
  	end = object->pointer + object->size;
  	if (ptr > start)
  		create_object(start, ptr - start, object->min_count,
  			      GFP_KERNEL);
  	if (ptr + size < end)
  		create_object(ptr + size, end - ptr - size, object->min_count,
  			      GFP_KERNEL);
e781a9ab4   Catalin Marinas   mm: kmemleak: fix...
706
  	__delete_object(object);
53238a60d   Catalin Marinas   kmemleak: Allow p...
707
  }
a1084c877   Luis R. Rodriguez   kmemleak: move co...
708
709
710
711
712
713
714
715
716
  
  static void __paint_it(struct kmemleak_object *object, int color)
  {
  	object->min_count = color;
  	if (color == KMEMLEAK_BLACK)
  		object->flags |= OBJECT_NO_SCAN;
  }
  
  static void paint_it(struct kmemleak_object *object, int color)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
717
718
  {
  	unsigned long flags;
a1084c877   Luis R. Rodriguez   kmemleak: move co...
719
720
721
722
723
724
725
726
  
  	spin_lock_irqsave(&object->lock, flags);
  	__paint_it(object, color);
  	spin_unlock_irqrestore(&object->lock, flags);
  }
  
  static void paint_ptr(unsigned long ptr, int color)
  {
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
727
728
729
730
  	struct kmemleak_object *object;
  
  	object = find_and_get_object(ptr, 0);
  	if (!object) {
756a025f0   Joe Perches   mm: coalesce spli...
731
732
733
  		kmemleak_warn("Trying to color unknown object at 0x%08lx as %s
  ",
  			      ptr,
a1084c877   Luis R. Rodriguez   kmemleak: move co...
734
735
  			      (color == KMEMLEAK_GREY) ? "Grey" :
  			      (color == KMEMLEAK_BLACK) ? "Black" : "Unknown");
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
736
737
  		return;
  	}
a1084c877   Luis R. Rodriguez   kmemleak: move co...
738
  	paint_it(object, color);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
739
740
741
742
  	put_object(object);
  }
  
  /*
145b64b95   Holger Hans Peter Freyther   kmemleak: Fix typ...
743
   * Mark an object permanently as gray-colored so that it can no longer be
a1084c877   Luis R. Rodriguez   kmemleak: move co...
744
745
746
747
748
749
750
751
   * reported as a leak. This is used in general to mark a false positive.
   */
  static void make_gray_object(unsigned long ptr)
  {
  	paint_ptr(ptr, KMEMLEAK_GREY);
  }
  
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
752
753
754
755
756
   * Mark the object as black-colored so that it is ignored from scans and
   * reporting.
   */
  static void make_black_object(unsigned long ptr)
  {
a1084c877   Luis R. Rodriguez   kmemleak: move co...
757
  	paint_ptr(ptr, KMEMLEAK_BLACK);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
758
759
760
761
762
763
  }
  
  /*
   * Add a scanning area to the object. If at least one such area is added,
   * kmemleak will only scan these ranges rather than the whole memory block.
   */
c017b4be3   Catalin Marinas   kmemleak: Simplif...
764
  static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
765
766
767
768
  {
  	unsigned long flags;
  	struct kmemleak_object *object;
  	struct kmemleak_scan_area *area;
c017b4be3   Catalin Marinas   kmemleak: Simplif...
769
  	object = find_and_get_object(ptr, 1);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
770
  	if (!object) {
ae281064b   Joe Perches   kmemleak: use pr_fmt
771
772
773
  		kmemleak_warn("Adding scan area to unknown object at 0x%08lx
  ",
  			      ptr);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
774
775
  		return;
  	}
6ae4bd1f0   Catalin Marinas   kmemleak: Allow k...
776
  	area = kmem_cache_alloc(scan_area_cache, gfp_kmemleak_mask(gfp));
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
777
  	if (!area) {
598d80914   Joe Perches   mm: convert pr_wa...
778
779
  		pr_warn("Cannot allocate a scan area
  ");
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
780
781
782
783
  		goto out;
  	}
  
  	spin_lock_irqsave(&object->lock, flags);
7f88f88f8   Catalin Marinas   mm: kmemleak: avo...
784
785
786
  	if (size == SIZE_MAX) {
  		size = object->pointer + object->size - ptr;
  	} else if (ptr + size > object->pointer + object->size) {
ae281064b   Joe Perches   kmemleak: use pr_fmt
787
788
  		kmemleak_warn("Scan area larger than object 0x%08lx
  ", ptr);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
789
790
791
792
793
794
  		dump_object_info(object);
  		kmem_cache_free(scan_area_cache, area);
  		goto out_unlock;
  	}
  
  	INIT_HLIST_NODE(&area->node);
c017b4be3   Catalin Marinas   kmemleak: Simplif...
795
796
  	area->start = ptr;
  	area->size = size;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
797
798
799
800
801
802
803
804
805
  
  	hlist_add_head(&area->node, &object->area_list);
  out_unlock:
  	spin_unlock_irqrestore(&object->lock, flags);
  out:
  	put_object(object);
  }
  
  /*
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
   * Any surplus references (object already gray) to 'ptr' are passed to
   * 'excess_ref'. This is used in the vmalloc() case where a pointer to
   * vm_struct may be used as an alternative reference to the vmalloc'ed object
   * (see free_thread_stack()).
   */
  static void object_set_excess_ref(unsigned long ptr, unsigned long excess_ref)
  {
  	unsigned long flags;
  	struct kmemleak_object *object;
  
  	object = find_and_get_object(ptr, 0);
  	if (!object) {
  		kmemleak_warn("Setting excess_ref on unknown object at 0x%08lx
  ",
  			      ptr);
  		return;
  	}
  
  	spin_lock_irqsave(&object->lock, flags);
  	object->excess_ref = excess_ref;
  	spin_unlock_irqrestore(&object->lock, flags);
  	put_object(object);
  }
  
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
831
832
833
834
835
836
837
838
839
840
841
   * Set the OBJECT_NO_SCAN flag for the object corresponding to the give
   * pointer. Such object will not be scanned by kmemleak but references to it
   * are searched.
   */
  static void object_no_scan(unsigned long ptr)
  {
  	unsigned long flags;
  	struct kmemleak_object *object;
  
  	object = find_and_get_object(ptr, 0);
  	if (!object) {
ae281064b   Joe Perches   kmemleak: use pr_fmt
842
843
  		kmemleak_warn("Not scanning unknown object at 0x%08lx
  ", ptr);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
844
845
846
847
848
849
850
851
852
853
854
855
856
  		return;
  	}
  
  	spin_lock_irqsave(&object->lock, flags);
  	object->flags |= OBJECT_NO_SCAN;
  	spin_unlock_irqrestore(&object->lock, flags);
  	put_object(object);
  }
  
  /*
   * Log an early kmemleak_* call to the early_log buffer. These calls will be
   * processed later once kmemleak is fully initialized.
   */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
857
  static void __init log_early(int op_type, const void *ptr, size_t size,
c017b4be3   Catalin Marinas   kmemleak: Simplif...
858
  			     int min_count)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
859
860
861
  {
  	unsigned long flags;
  	struct early_log *log;
8910ae896   Li Zefan   kmemleak: change ...
862
  	if (kmemleak_error) {
b66930052   Catalin Marinas   kmemleak: When th...
863
864
865
866
  		/* kmemleak stopped recording, just count the requests */
  		crt_early_log++;
  		return;
  	}
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
867
  	if (crt_early_log >= ARRAY_SIZE(early_log)) {
21cd3a604   Wang Kai   kmemleak: record ...
868
  		crt_early_log++;
a9d9058ab   Catalin Marinas   kmemleak: Allow t...
869
  		kmemleak_disable();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
870
871
872
873
874
875
876
877
878
879
880
881
882
  		return;
  	}
  
  	/*
  	 * There is no need for locking since the kernel is still in UP mode
  	 * at this stage. Disabling the IRQs is enough.
  	 */
  	local_irq_save(flags);
  	log = &early_log[crt_early_log];
  	log->op_type = op_type;
  	log->ptr = ptr;
  	log->size = size;
  	log->min_count = min_count;
5f79020cb   Catalin Marinas   kmemleak: Show wh...
883
  	log->trace_len = __save_stack_trace(log->trace);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
884
885
886
887
888
  	crt_early_log++;
  	local_irq_restore(flags);
  }
  
  /*
fd6789675   Catalin Marinas   kmemleak: Save th...
889
890
891
892
893
894
895
   * Log an early allocated block and populate the stack trace.
   */
  static void early_alloc(struct early_log *log)
  {
  	struct kmemleak_object *object;
  	unsigned long flags;
  	int i;
8910ae896   Li Zefan   kmemleak: change ...
896
  	if (!kmemleak_enabled || !log->ptr || IS_ERR(log->ptr))
fd6789675   Catalin Marinas   kmemleak: Save th...
897
898
899
900
901
902
903
  		return;
  
  	/*
  	 * RCU locking needed to ensure object is not freed via put_object().
  	 */
  	rcu_read_lock();
  	object = create_object((unsigned long)log->ptr, log->size,
c1bcd6b32   Tetsuo Handa   kmemleak: Use GFP...
904
  			       log->min_count, GFP_ATOMIC);
0d5d1aadc   Catalin Marinas   kmemleak: Check f...
905
906
  	if (!object)
  		goto out;
fd6789675   Catalin Marinas   kmemleak: Save th...
907
908
909
910
911
  	spin_lock_irqsave(&object->lock, flags);
  	for (i = 0; i < log->trace_len; i++)
  		object->trace[i] = log->trace[i];
  	object->trace_len = log->trace_len;
  	spin_unlock_irqrestore(&object->lock, flags);
0d5d1aadc   Catalin Marinas   kmemleak: Check f...
912
  out:
fd6789675   Catalin Marinas   kmemleak: Save th...
913
914
  	rcu_read_unlock();
  }
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
915
916
917
918
919
920
921
922
923
924
925
926
927
  /*
   * Log an early allocated block and populate the stack trace.
   */
  static void early_alloc_percpu(struct early_log *log)
  {
  	unsigned int cpu;
  	const void __percpu *ptr = log->ptr;
  
  	for_each_possible_cpu(cpu) {
  		log->ptr = per_cpu_ptr(ptr, cpu);
  		early_alloc(log);
  	}
  }
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
928
929
930
931
932
933
934
935
936
937
938
939
  /**
   * kmemleak_alloc - register a newly allocated object
   * @ptr:	pointer to beginning of the object
   * @size:	size of the object
   * @min_count:	minimum number of references to this object. If during memory
   *		scanning a number of references less than @min_count is found,
   *		the object is reported as a memory leak. If @min_count is 0,
   *		the object is never reported as a leak. If @min_count is -1,
   *		the object is ignored (not scanned and not reported as a leak)
   * @gfp:	kmalloc() flags used for kmemleak internal memory allocations
   *
   * This function is called from the kernel allocators when a new object
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
940
   * (memory block) is allocated (kmem_cache_alloc, kmalloc etc.).
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
941
   */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
942
943
  void __ref kmemleak_alloc(const void *ptr, size_t size, int min_count,
  			  gfp_t gfp)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
944
945
946
  {
  	pr_debug("%s(0x%p, %zu, %d)
  ", __func__, ptr, size, min_count);
8910ae896   Li Zefan   kmemleak: change ...
947
  	if (kmemleak_enabled && ptr && !IS_ERR(ptr))
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
948
  		create_object((unsigned long)ptr, size, min_count, gfp);
8910ae896   Li Zefan   kmemleak: change ...
949
  	else if (kmemleak_early_log)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
950
  		log_early(KMEMLEAK_ALLOC, ptr, size, min_count);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
951
952
  }
  EXPORT_SYMBOL_GPL(kmemleak_alloc);
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
953
  /**
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
954
955
956
   * kmemleak_alloc_percpu - register a newly allocated __percpu object
   * @ptr:	__percpu pointer to beginning of the object
   * @size:	size of the object
8a8c35fad   Larry Finger   mm: kmemleak_allo...
957
   * @gfp:	flags used for kmemleak internal memory allocations
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
958
959
   *
   * This function is called from the kernel percpu allocator when a new object
8a8c35fad   Larry Finger   mm: kmemleak_allo...
960
   * (memory block) is allocated (alloc_percpu).
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
961
   */
8a8c35fad   Larry Finger   mm: kmemleak_allo...
962
963
  void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size,
  				 gfp_t gfp)
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
964
965
966
967
968
969
970
971
972
973
  {
  	unsigned int cpu;
  
  	pr_debug("%s(0x%p, %zu)
  ", __func__, ptr, size);
  
  	/*
  	 * Percpu allocations are only scanned and not reported as leaks
  	 * (min_count is set to 0).
  	 */
8910ae896   Li Zefan   kmemleak: change ...
974
  	if (kmemleak_enabled && ptr && !IS_ERR(ptr))
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
975
976
  		for_each_possible_cpu(cpu)
  			create_object((unsigned long)per_cpu_ptr(ptr, cpu),
8a8c35fad   Larry Finger   mm: kmemleak_allo...
977
  				      size, 0, gfp);
8910ae896   Li Zefan   kmemleak: change ...
978
  	else if (kmemleak_early_log)
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
979
980
981
982
983
  		log_early(KMEMLEAK_ALLOC_PERCPU, ptr, size, 0);
  }
  EXPORT_SYMBOL_GPL(kmemleak_alloc_percpu);
  
  /**
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
   * kmemleak_vmalloc - register a newly vmalloc'ed object
   * @area:	pointer to vm_struct
   * @size:	size of the object
   * @gfp:	__vmalloc() flags used for kmemleak internal memory allocations
   *
   * This function is called from the vmalloc() kernel allocator when a new
   * object (memory block) is allocated.
   */
  void __ref kmemleak_vmalloc(const struct vm_struct *area, size_t size, gfp_t gfp)
  {
  	pr_debug("%s(0x%p, %zu)
  ", __func__, area, size);
  
  	/*
  	 * A min_count = 2 is needed because vm_struct contains a reference to
  	 * the virtual address of the vmalloc'ed block.
  	 */
  	if (kmemleak_enabled) {
  		create_object((unsigned long)area->addr, size, 2, gfp);
  		object_set_excess_ref((unsigned long)area,
  				      (unsigned long)area->addr);
  	} else if (kmemleak_early_log) {
  		log_early(KMEMLEAK_ALLOC, area->addr, size, 2);
  		/* reusing early_log.size for storing area->addr */
  		log_early(KMEMLEAK_SET_EXCESS_REF,
  			  area, (unsigned long)area->addr, 0);
  	}
  }
  EXPORT_SYMBOL_GPL(kmemleak_vmalloc);
  
  /**
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
1015
1016
1017
1018
1019
   * kmemleak_free - unregister a previously registered object
   * @ptr:	pointer to beginning of the object
   *
   * This function is called from the kernel allocators when an object (memory
   * block) is freed (kmem_cache_free, kfree, vfree etc.).
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1020
   */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
1021
  void __ref kmemleak_free(const void *ptr)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1022
1023
1024
  {
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
1025
  	if (kmemleak_free_enabled && ptr && !IS_ERR(ptr))
53238a60d   Catalin Marinas   kmemleak: Allow p...
1026
  		delete_object_full((unsigned long)ptr);
8910ae896   Li Zefan   kmemleak: change ...
1027
  	else if (kmemleak_early_log)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1028
  		log_early(KMEMLEAK_FREE, ptr, 0, 0);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1029
1030
  }
  EXPORT_SYMBOL_GPL(kmemleak_free);
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
1031
1032
1033
1034
1035
1036
1037
1038
  /**
   * kmemleak_free_part - partially unregister a previously registered object
   * @ptr:	pointer to the beginning or inside the object. This also
   *		represents the start of the range to be freed
   * @size:	size to be unregistered
   *
   * This function is called when only a part of a memory block is freed
   * (usually from the bootmem allocator).
53238a60d   Catalin Marinas   kmemleak: Allow p...
1039
   */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
1040
  void __ref kmemleak_free_part(const void *ptr, size_t size)
53238a60d   Catalin Marinas   kmemleak: Allow p...
1041
1042
1043
  {
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
8910ae896   Li Zefan   kmemleak: change ...
1044
  	if (kmemleak_enabled && ptr && !IS_ERR(ptr))
53238a60d   Catalin Marinas   kmemleak: Allow p...
1045
  		delete_object_part((unsigned long)ptr, size);
8910ae896   Li Zefan   kmemleak: change ...
1046
  	else if (kmemleak_early_log)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1047
  		log_early(KMEMLEAK_FREE_PART, ptr, size, 0);
53238a60d   Catalin Marinas   kmemleak: Allow p...
1048
1049
  }
  EXPORT_SYMBOL_GPL(kmemleak_free_part);
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
1050
  /**
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
   * kmemleak_free_percpu - unregister a previously registered __percpu object
   * @ptr:	__percpu pointer to beginning of the object
   *
   * This function is called from the kernel percpu allocator when an object
   * (memory block) is freed (free_percpu).
   */
  void __ref kmemleak_free_percpu(const void __percpu *ptr)
  {
  	unsigned int cpu;
  
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
1063
  	if (kmemleak_free_enabled && ptr && !IS_ERR(ptr))
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
1064
1065
1066
  		for_each_possible_cpu(cpu)
  			delete_object_full((unsigned long)per_cpu_ptr(ptr,
  								      cpu));
8910ae896   Li Zefan   kmemleak: change ...
1067
  	else if (kmemleak_early_log)
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
1068
1069
1070
1071
1072
  		log_early(KMEMLEAK_FREE_PERCPU, ptr, 0, 0);
  }
  EXPORT_SYMBOL_GPL(kmemleak_free_percpu);
  
  /**
ffe2c748e   Catalin Marinas   mm: introduce kme...
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
   * kmemleak_update_trace - update object allocation stack trace
   * @ptr:	pointer to beginning of the object
   *
   * Override the object allocation stack trace for cases where the actual
   * allocation place is not always useful.
   */
  void __ref kmemleak_update_trace(const void *ptr)
  {
  	struct kmemleak_object *object;
  	unsigned long flags;
  
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
  
  	if (!kmemleak_enabled || IS_ERR_OR_NULL(ptr))
  		return;
  
  	object = find_and_get_object((unsigned long)ptr, 1);
  	if (!object) {
  #ifdef DEBUG
  		kmemleak_warn("Updating stack trace for unknown object at %p
  ",
  			      ptr);
  #endif
  		return;
  	}
  
  	spin_lock_irqsave(&object->lock, flags);
  	object->trace_len = __save_stack_trace(object->trace);
  	spin_unlock_irqrestore(&object->lock, flags);
  
  	put_object(object);
  }
  EXPORT_SYMBOL(kmemleak_update_trace);
  
  /**
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
1109
1110
1111
1112
1113
   * kmemleak_not_leak - mark an allocated object as false positive
   * @ptr:	pointer to beginning of the object
   *
   * Calling this function on an object will cause the memory block to no longer
   * be reported as leak and always be scanned.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1114
   */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
1115
  void __ref kmemleak_not_leak(const void *ptr)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1116
1117
1118
  {
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
8910ae896   Li Zefan   kmemleak: change ...
1119
  	if (kmemleak_enabled && ptr && !IS_ERR(ptr))
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1120
  		make_gray_object((unsigned long)ptr);
8910ae896   Li Zefan   kmemleak: change ...
1121
  	else if (kmemleak_early_log)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1122
  		log_early(KMEMLEAK_NOT_LEAK, ptr, 0, 0);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1123
1124
  }
  EXPORT_SYMBOL(kmemleak_not_leak);
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
1125
1126
1127
1128
1129
1130
1131
1132
  /**
   * kmemleak_ignore - ignore an allocated object
   * @ptr:	pointer to beginning of the object
   *
   * Calling this function on an object will cause the memory block to be
   * ignored (not scanned and not reported as a leak). This is usually done when
   * it is known that the corresponding block is not a leak and does not contain
   * any references to other allocated memory blocks.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1133
   */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
1134
  void __ref kmemleak_ignore(const void *ptr)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1135
1136
1137
  {
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
8910ae896   Li Zefan   kmemleak: change ...
1138
  	if (kmemleak_enabled && ptr && !IS_ERR(ptr))
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1139
  		make_black_object((unsigned long)ptr);
8910ae896   Li Zefan   kmemleak: change ...
1140
  	else if (kmemleak_early_log)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1141
  		log_early(KMEMLEAK_IGNORE, ptr, 0, 0);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1142
1143
  }
  EXPORT_SYMBOL(kmemleak_ignore);
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
  /**
   * kmemleak_scan_area - limit the range to be scanned in an allocated object
   * @ptr:	pointer to beginning or inside the object. This also
   *		represents the start of the scan area
   * @size:	size of the scan area
   * @gfp:	kmalloc() flags used for kmemleak internal memory allocations
   *
   * This function is used when it is known that only certain parts of an object
   * contain references to other objects. Kmemleak will only scan these areas
   * reducing the number false negatives.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1154
   */
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1155
  void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1156
1157
1158
  {
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
8910ae896   Li Zefan   kmemleak: change ...
1159
  	if (kmemleak_enabled && ptr && size && !IS_ERR(ptr))
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1160
  		add_scan_area((unsigned long)ptr, size, gfp);
8910ae896   Li Zefan   kmemleak: change ...
1161
  	else if (kmemleak_early_log)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1162
  		log_early(KMEMLEAK_SCAN_AREA, ptr, size, 0);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1163
1164
  }
  EXPORT_SYMBOL(kmemleak_scan_area);
a2b6bf63c   Catalin Marinas   kmemleak: Add Doc...
1165
1166
1167
1168
1169
1170
1171
1172
  /**
   * kmemleak_no_scan - do not scan an allocated object
   * @ptr:	pointer to beginning of the object
   *
   * This function notifies kmemleak not to scan the given memory block. Useful
   * in situations where it is known that the given object does not contain any
   * references to other objects. Kmemleak will not scan such objects reducing
   * the number of false negatives.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1173
   */
a6186d89c   Catalin Marinas   kmemleak: Mark th...
1174
  void __ref kmemleak_no_scan(const void *ptr)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1175
1176
1177
  {
  	pr_debug("%s(0x%p)
  ", __func__, ptr);
8910ae896   Li Zefan   kmemleak: change ...
1178
  	if (kmemleak_enabled && ptr && !IS_ERR(ptr))
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1179
  		object_no_scan((unsigned long)ptr);
8910ae896   Li Zefan   kmemleak: change ...
1180
  	else if (kmemleak_early_log)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1181
  		log_early(KMEMLEAK_NO_SCAN, ptr, 0, 0);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1182
1183
  }
  EXPORT_SYMBOL(kmemleak_no_scan);
9099daed9   Catalin Marinas   mm: kmemleak: avo...
1184
1185
1186
  /**
   * kmemleak_alloc_phys - similar to kmemleak_alloc but taking a physical
   *			 address argument
e8b098fc5   Mike Rapoport   mm: kernel-doc: a...
1187
1188
1189
1190
1191
   * @phys:	physical address of the object
   * @size:	size of the object
   * @min_count:	minimum number of references to this object.
   *              See kmemleak_alloc()
   * @gfp:	kmalloc() flags used for kmemleak internal memory allocations
9099daed9   Catalin Marinas   mm: kmemleak: avo...
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
   */
  void __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, int min_count,
  			       gfp_t gfp)
  {
  	if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
  		kmemleak_alloc(__va(phys), size, min_count, gfp);
  }
  EXPORT_SYMBOL(kmemleak_alloc_phys);
  
  /**
   * kmemleak_free_part_phys - similar to kmemleak_free_part but taking a
   *			     physical address argument
e8b098fc5   Mike Rapoport   mm: kernel-doc: a...
1204
1205
1206
   * @phys:	physical address if the beginning or inside an object. This
   *		also represents the start of the range to be freed
   * @size:	size to be unregistered
9099daed9   Catalin Marinas   mm: kmemleak: avo...
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
   */
  void __ref kmemleak_free_part_phys(phys_addr_t phys, size_t size)
  {
  	if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
  		kmemleak_free_part(__va(phys), size);
  }
  EXPORT_SYMBOL(kmemleak_free_part_phys);
  
  /**
   * kmemleak_not_leak_phys - similar to kmemleak_not_leak but taking a physical
   *			    address argument
e8b098fc5   Mike Rapoport   mm: kernel-doc: a...
1218
   * @phys:	physical address of the object
9099daed9   Catalin Marinas   mm: kmemleak: avo...
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
   */
  void __ref kmemleak_not_leak_phys(phys_addr_t phys)
  {
  	if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
  		kmemleak_not_leak(__va(phys));
  }
  EXPORT_SYMBOL(kmemleak_not_leak_phys);
  
  /**
   * kmemleak_ignore_phys - similar to kmemleak_ignore but taking a physical
   *			  address argument
e8b098fc5   Mike Rapoport   mm: kernel-doc: a...
1230
   * @phys:	physical address of the object
9099daed9   Catalin Marinas   mm: kmemleak: avo...
1231
1232
1233
1234
1235
1236
1237
   */
  void __ref kmemleak_ignore_phys(phys_addr_t phys)
  {
  	if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn)
  		kmemleak_ignore(__va(phys));
  }
  EXPORT_SYMBOL(kmemleak_ignore_phys);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1238
  /*
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1239
1240
1241
1242
1243
   * Update an object's checksum and return true if it was modified.
   */
  static bool update_checksum(struct kmemleak_object *object)
  {
  	u32 old_csum = object->checksum;
e79ed2f13   Andrey Ryabinin   kmemleak: disable...
1244
  	kasan_disable_current();
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1245
  	object->checksum = crc32(0, (void *)object->pointer, object->size);
e79ed2f13   Andrey Ryabinin   kmemleak: disable...
1246
  	kasan_enable_current();
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1247
1248
1249
1250
  	return object->checksum != old_csum;
  }
  
  /*
04f70d13c   Catalin Marinas   mm: kmemleak: fac...
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
   * Update an object's references. object->lock must be held by the caller.
   */
  static void update_refs(struct kmemleak_object *object)
  {
  	if (!color_white(object)) {
  		/* non-orphan, ignored or new */
  		return;
  	}
  
  	/*
  	 * Increase the object's reference count (number of pointers to the
  	 * memory block). If this count reaches the required minimum, the
  	 * object's color will become gray and it will be added to the
  	 * gray_list.
  	 */
  	object->count++;
  	if (color_gray(object)) {
  		/* put_object() called when removing from gray_list */
  		WARN_ON(!get_object(object));
  		list_add_tail(&object->gray_list, &gray_list);
  	}
  }
  
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1275
   * Memory scanning is a long process and it needs to be interruptable. This
25985edce   Lucas De Marchi   Fix common misspe...
1276
   * function checks whether such interrupt condition occurred.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1277
1278
1279
   */
  static int scan_should_stop(void)
  {
8910ae896   Li Zefan   kmemleak: change ...
1280
  	if (!kmemleak_enabled)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
  		return 1;
  
  	/*
  	 * This function may be called from either process or kthread context,
  	 * hence the need to check for both stop conditions.
  	 */
  	if (current->mm)
  		return signal_pending(current);
  	else
  		return kthread_should_stop();
  
  	return 0;
  }
  
  /*
   * Scan a memory block (exclusive range) for valid pointers and add those
   * found to the gray list.
   */
  static void scan_block(void *_start, void *_end,
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1300
  		       struct kmemleak_object *scanned)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1301
1302
1303
1304
  {
  	unsigned long *ptr;
  	unsigned long *start = PTR_ALIGN(_start, BYTES_PER_POINTER);
  	unsigned long *end = _end - (BYTES_PER_POINTER - 1);
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1305
  	unsigned long flags;
a2f775751   Andrey Konovalov   kmemleak: account...
1306
  	unsigned long untagged_ptr;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1307

93ada579b   Catalin Marinas   mm: kmemleak: opt...
1308
  	read_lock_irqsave(&kmemleak_lock, flags);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1309
  	for (ptr = start; ptr < end; ptr++) {
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1310
  		struct kmemleak_object *object;
8e019366b   Pekka Enberg   kmemleak: Don't s...
1311
  		unsigned long pointer;
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
1312
  		unsigned long excess_ref;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1313
1314
1315
  
  		if (scan_should_stop())
  			break;
e79ed2f13   Andrey Ryabinin   kmemleak: disable...
1316
  		kasan_disable_current();
8e019366b   Pekka Enberg   kmemleak: Don't s...
1317
  		pointer = *ptr;
e79ed2f13   Andrey Ryabinin   kmemleak: disable...
1318
  		kasan_enable_current();
8e019366b   Pekka Enberg   kmemleak: Don't s...
1319

a2f775751   Andrey Konovalov   kmemleak: account...
1320
1321
  		untagged_ptr = (unsigned long)kasan_reset_tag((void *)pointer);
  		if (untagged_ptr < min_addr || untagged_ptr >= max_addr)
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1322
1323
1324
1325
1326
1327
1328
1329
1330
  			continue;
  
  		/*
  		 * No need for get_object() here since we hold kmemleak_lock.
  		 * object->use_count cannot be dropped to 0 while the object
  		 * is still present in object_tree_root and object_list
  		 * (with updates protected by kmemleak_lock).
  		 */
  		object = lookup_object(pointer, 1);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1331
1332
  		if (!object)
  			continue;
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1333
  		if (object == scanned)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1334
  			/* self referenced, ignore */
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1335
  			continue;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1336
1337
1338
1339
1340
1341
  
  		/*
  		 * Avoid the lockdep recursive warning on object->lock being
  		 * previously acquired in scan_object(). These locks are
  		 * enclosed by scan_mutex.
  		 */
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1342
  		spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING);
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
1343
1344
1345
1346
1347
1348
1349
1350
  		/* only pass surplus references (object already gray) */
  		if (color_gray(object)) {
  			excess_ref = object->excess_ref;
  			/* no need for update_refs() if object already gray */
  		} else {
  			excess_ref = 0;
  			update_refs(object);
  		}
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1351
  		spin_unlock(&object->lock);
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
  
  		if (excess_ref) {
  			object = lookup_object(excess_ref, 0);
  			if (!object)
  				continue;
  			if (object == scanned)
  				/* circular reference, ignore */
  				continue;
  			spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING);
  			update_refs(object);
  			spin_unlock(&object->lock);
  		}
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1364
1365
1366
  	}
  	read_unlock_irqrestore(&kmemleak_lock, flags);
  }
0587da40b   Catalin Marinas   kmemleak: Release...
1367

93ada579b   Catalin Marinas   mm: kmemleak: opt...
1368
1369
1370
  /*
   * Scan a large memory block in MAX_SCAN_SIZE chunks to reduce the latency.
   */
dce5b0bde   Arnd Bergmann   mm/kmemleak.c: fi...
1371
  #ifdef CONFIG_SMP
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1372
1373
1374
1375
1376
1377
1378
1379
1380
  static void scan_large_block(void *start, void *end)
  {
  	void *next;
  
  	while (start < end) {
  		next = min(start + MAX_SCAN_SIZE, end);
  		scan_block(start, next, NULL);
  		start = next;
  		cond_resched();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1381
1382
  	}
  }
dce5b0bde   Arnd Bergmann   mm/kmemleak.c: fi...
1383
  #endif
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1384
1385
1386
1387
1388
1389
1390
1391
  
  /*
   * Scan a memory block corresponding to a kmemleak_object. A condition is
   * that object->use_count >= 1.
   */
  static void scan_object(struct kmemleak_object *object)
  {
  	struct kmemleak_scan_area *area;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1392
1393
1394
  	unsigned long flags;
  
  	/*
21ae2956c   Uwe Kleine-König   tree-wide: fix ty...
1395
1396
  	 * Once the object->lock is acquired, the corresponding memory block
  	 * cannot be freed (the same lock is acquired in delete_object).
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1397
1398
1399
1400
1401
1402
1403
  	 */
  	spin_lock_irqsave(&object->lock, flags);
  	if (object->flags & OBJECT_NO_SCAN)
  		goto out;
  	if (!(object->flags & OBJECT_ALLOCATED))
  		/* already freed object */
  		goto out;
af98603da   Catalin Marinas   kmemleak: Allow r...
1404
1405
1406
  	if (hlist_empty(&object->area_list)) {
  		void *start = (void *)object->pointer;
  		void *end = (void *)(object->pointer + object->size);
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1407
1408
1409
1410
1411
  		void *next;
  
  		do {
  			next = min(start + MAX_SCAN_SIZE, end);
  			scan_block(start, next, object);
af98603da   Catalin Marinas   kmemleak: Allow r...
1412

93ada579b   Catalin Marinas   mm: kmemleak: opt...
1413
1414
1415
  			start = next;
  			if (start >= end)
  				break;
af98603da   Catalin Marinas   kmemleak: Allow r...
1416
1417
1418
1419
  
  			spin_unlock_irqrestore(&object->lock, flags);
  			cond_resched();
  			spin_lock_irqsave(&object->lock, flags);
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1420
  		} while (object->flags & OBJECT_ALLOCATED);
af98603da   Catalin Marinas   kmemleak: Allow r...
1421
  	} else
b67bfe0d4   Sasha Levin   hlist: drop the n...
1422
  		hlist_for_each_entry(area, &object->area_list, node)
c017b4be3   Catalin Marinas   kmemleak: Simplif...
1423
1424
  			scan_block((void *)area->start,
  				   (void *)(area->start + area->size),
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1425
  				   object);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1426
1427
1428
1429
1430
  out:
  	spin_unlock_irqrestore(&object->lock, flags);
  }
  
  /*
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
   * Scan the objects already referenced (gray objects). More objects will be
   * referenced and, if there are no memory leaks, all the objects are scanned.
   */
  static void scan_gray_list(void)
  {
  	struct kmemleak_object *object, *tmp;
  
  	/*
  	 * The list traversal is safe for both tail additions and removals
  	 * from inside the loop. The kmemleak objects cannot be freed from
  	 * outside the loop because their use_count was incremented.
  	 */
  	object = list_entry(gray_list.next, typeof(*object), gray_list);
  	while (&object->gray_list != &gray_list) {
  		cond_resched();
  
  		/* may add new objects to the list */
  		if (!scan_should_stop())
  			scan_object(object);
  
  		tmp = list_entry(object->gray_list.next, typeof(*object),
  				 gray_list);
  
  		/* remove the object from the list and release it */
  		list_del(&object->gray_list);
  		put_object(object);
  
  		object = tmp;
  	}
  	WARN_ON(!list_empty(&gray_list));
  }
  
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1464
1465
1466
1467
1468
1469
1470
   * Scan data sections and all the referenced memory blocks allocated via the
   * kernel's standard allocators. This function must be called with the
   * scan_mutex held.
   */
  static void kmemleak_scan(void)
  {
  	unsigned long flags;
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1471
  	struct kmemleak_object *object;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1472
  	int i;
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1473
  	int new_leaks = 0;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1474

acf4968ec   Catalin Marinas   kmemleak: Slightl...
1475
  	jiffies_last_scan = jiffies;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
  	/* prepare the kmemleak_object's */
  	rcu_read_lock();
  	list_for_each_entry_rcu(object, &object_list, object_list) {
  		spin_lock_irqsave(&object->lock, flags);
  #ifdef DEBUG
  		/*
  		 * With a few exceptions there should be a maximum of
  		 * 1 reference to any object at this point.
  		 */
  		if (atomic_read(&object->use_count) > 1) {
ae281064b   Joe Perches   kmemleak: use pr_fmt
1486
1487
  			pr_debug("object->use_count = %d
  ",
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
  				 atomic_read(&object->use_count));
  			dump_object_info(object);
  		}
  #endif
  		/* reset the reference count (whiten the object) */
  		object->count = 0;
  		if (color_gray(object) && get_object(object))
  			list_add_tail(&object->gray_list, &gray_list);
  
  		spin_unlock_irqrestore(&object->lock, flags);
  	}
  	rcu_read_unlock();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1500
1501
1502
  #ifdef CONFIG_SMP
  	/* per-cpu sections scanning */
  	for_each_possible_cpu(i)
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1503
1504
  		scan_large_block(__per_cpu_start + per_cpu_offset(i),
  				 __per_cpu_end + per_cpu_offset(i));
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1505
1506
1507
  #endif
  
  	/*
029aeff5d   Laura Abbott   kmemleak: Add sup...
1508
  	 * Struct page scanning for each node.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1509
  	 */
bfc8c9013   Vladimir Davydov   mem-hotplug: impl...
1510
  	get_online_mems();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1511
  	for_each_online_node(i) {
108bcc96e   Cody P Schafer   mm: add & use zon...
1512
1513
  		unsigned long start_pfn = node_start_pfn(i);
  		unsigned long end_pfn = node_end_pfn(i);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1514
1515
1516
  		unsigned long pfn;
  
  		for (pfn = start_pfn; pfn < end_pfn; pfn++) {
9f1eb38e0   Oscar Salvador   mm, kmemleak: lit...
1517
  			struct page *page = pfn_to_online_page(pfn);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1518

9f1eb38e0   Oscar Salvador   mm, kmemleak: lit...
1519
1520
1521
1522
1523
  			if (!page)
  				continue;
  
  			/* only scan pages belonging to this node */
  			if (page_to_nid(page) != i)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1524
  				continue;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1525
1526
1527
  			/* only scan if page is in use */
  			if (page_count(page) == 0)
  				continue;
93ada579b   Catalin Marinas   mm: kmemleak: opt...
1528
  			scan_block(page, page + 1, NULL);
13ab183d1   Andrew Morton   mm/kmemleak.c: ma...
1529
  			if (!(pfn & 63))
bde5f6bc6   Yisheng Xie   kmemleak: add sch...
1530
  				cond_resched();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1531
1532
  		}
  	}
bfc8c9013   Vladimir Davydov   mem-hotplug: impl...
1533
  	put_online_mems();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1534
1535
  
  	/*
43ed5d6ee   Catalin Marinas   kmemleak: Scan al...
1536
  	 * Scanning the task stacks (may introduce false negatives).
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1537
1538
  	 */
  	if (kmemleak_stack_scan) {
43ed5d6ee   Catalin Marinas   kmemleak: Scan al...
1539
  		struct task_struct *p, *g;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1540
  		read_lock(&tasklist_lock);
43ed5d6ee   Catalin Marinas   kmemleak: Scan al...
1541
  		do_each_thread(g, p) {
37df49f43   Catalin Marinas   mm: kmemleak: ens...
1542
1543
1544
1545
1546
  			void *stack = try_get_task_stack(p);
  			if (stack) {
  				scan_block(stack, stack + THREAD_SIZE, NULL);
  				put_task_stack(p);
  			}
43ed5d6ee   Catalin Marinas   kmemleak: Scan al...
1547
  		} while_each_thread(g, p);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1548
1549
1550
1551
1552
  		read_unlock(&tasklist_lock);
  	}
  
  	/*
  	 * Scan the objects already referenced from the sections scanned
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1553
  	 * above.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1554
  	 */
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1555
  	scan_gray_list();
2587362ea   Catalin Marinas   kmemleak: Scan ob...
1556
1557
  
  	/*
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1558
1559
  	 * Check for new or unreferenced objects modified since the previous
  	 * scan and color them gray until the next scan.
2587362ea   Catalin Marinas   kmemleak: Scan ob...
1560
1561
1562
1563
  	 */
  	rcu_read_lock();
  	list_for_each_entry_rcu(object, &object_list, object_list) {
  		spin_lock_irqsave(&object->lock, flags);
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1564
1565
1566
1567
  		if (color_white(object) && (object->flags & OBJECT_ALLOCATED)
  		    && update_checksum(object) && get_object(object)) {
  			/* color it gray temporarily */
  			object->count = object->min_count;
2587362ea   Catalin Marinas   kmemleak: Scan ob...
1568
1569
1570
1571
1572
  			list_add_tail(&object->gray_list, &gray_list);
  		}
  		spin_unlock_irqrestore(&object->lock, flags);
  	}
  	rcu_read_unlock();
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1573
1574
1575
1576
  	/*
  	 * Re-scan the gray list for modified unreferenced objects.
  	 */
  	scan_gray_list();
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1577
1578
  
  	/*
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1579
  	 * If scanning was stopped do not report any new unreferenced objects.
17bb9e0d9   Catalin Marinas   kmemleak: Do not ...
1580
  	 */
04609ccc4   Catalin Marinas   kmemleak: Reduce ...
1581
  	if (scan_should_stop())
17bb9e0d9   Catalin Marinas   kmemleak: Do not ...
1582
1583
1584
  		return;
  
  	/*
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1585
1586
1587
1588
1589
1590
1591
1592
  	 * Scanning result reporting.
  	 */
  	rcu_read_lock();
  	list_for_each_entry_rcu(object, &object_list, object_list) {
  		spin_lock_irqsave(&object->lock, flags);
  		if (unreferenced_object(object) &&
  		    !(object->flags & OBJECT_REPORTED)) {
  			object->flags |= OBJECT_REPORTED;
154221c3e   Vincent Whitchurch   kmemleak: add mod...
1593
1594
1595
  
  			if (kmemleak_verbose)
  				print_unreferenced(NULL, object);
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1596
1597
1598
1599
1600
  			new_leaks++;
  		}
  		spin_unlock_irqrestore(&object->lock, flags);
  	}
  	rcu_read_unlock();
dc9b3f424   Li Zefan   kmemleak: free in...
1601
1602
  	if (new_leaks) {
  		kmemleak_found_leaks = true;
756a025f0   Joe Perches   mm: coalesce spli...
1603
1604
1605
  		pr_info("%d new suspected memory leaks (see /sys/kernel/debug/kmemleak)
  ",
  			new_leaks);
dc9b3f424   Li Zefan   kmemleak: free in...
1606
  	}
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1607

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1608
1609
1610
1611
1612
1613
1614
1615
  }
  
  /*
   * Thread function performing automatic memory scanning. Unreferenced objects
   * at the end of a memory scan are reported but only the first time.
   */
  static int kmemleak_scan_thread(void *arg)
  {
d53ce0422   Sri Krishna chowdary   kmemleak: add con...
1616
  	static int first_run = IS_ENABLED(CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1617

ae281064b   Joe Perches   kmemleak: use pr_fmt
1618
1619
  	pr_info("Automatic memory scanning thread started
  ");
bf2a76b31   Catalin Marinas   kmemleak: Renice ...
1620
  	set_user_nice(current, 10);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1621
1622
1623
1624
1625
  
  	/*
  	 * Wait before the first scan to allow the system to fully initialize.
  	 */
  	if (first_run) {
98c42d945   Vegard Nossum   kmemleak: don't h...
1626
  		signed long timeout = msecs_to_jiffies(SECS_FIRST_SCAN * 1000);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1627
  		first_run = 0;
98c42d945   Vegard Nossum   kmemleak: don't h...
1628
1629
  		while (timeout && !kthread_should_stop())
  			timeout = schedule_timeout_interruptible(timeout);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1630
1631
1632
  	}
  
  	while (!kthread_should_stop()) {
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1633
1634
1635
  		signed long timeout = jiffies_scan_wait;
  
  		mutex_lock(&scan_mutex);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1636
  		kmemleak_scan();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1637
  		mutex_unlock(&scan_mutex);
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1638

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1639
1640
1641
1642
  		/* wait before the next scan */
  		while (timeout && !kthread_should_stop())
  			timeout = schedule_timeout_interruptible(timeout);
  	}
ae281064b   Joe Perches   kmemleak: use pr_fmt
1643
1644
  	pr_info("Automatic memory scanning thread ended
  ");
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1645
1646
1647
1648
1649
1650
  
  	return 0;
  }
  
  /*
   * Start the automatic memory scanning thread. This function must be called
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1651
   * with the scan_mutex held.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1652
   */
7eb0d5e5b   Luis R. Rodriguez   kmemleak: fix spa...
1653
  static void start_scan_thread(void)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1654
1655
1656
1657
1658
  {
  	if (scan_thread)
  		return;
  	scan_thread = kthread_run(kmemleak_scan_thread, NULL, "kmemleak");
  	if (IS_ERR(scan_thread)) {
598d80914   Joe Perches   mm: convert pr_wa...
1659
1660
  		pr_warn("Failed to create the scan thread
  ");
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1661
1662
1663
1664
1665
  		scan_thread = NULL;
  	}
  }
  
  /*
914b6dfff   Vinayak Menon   mm/kmemleak.c: wa...
1666
   * Stop the automatic memory scanning thread.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1667
   */
7eb0d5e5b   Luis R. Rodriguez   kmemleak: fix spa...
1668
  static void stop_scan_thread(void)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
  {
  	if (scan_thread) {
  		kthread_stop(scan_thread);
  		scan_thread = NULL;
  	}
  }
  
  /*
   * Iterate over the object_list and return the first valid object at or after
   * the required position with its use_count incremented. The function triggers
   * a memory scanning when the pos argument points to the first position.
   */
  static void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos)
  {
  	struct kmemleak_object *object;
  	loff_t n = *pos;
b87324d08   Catalin Marinas   kmemleak: Do not ...
1685
1686
1687
1688
1689
  	int err;
  
  	err = mutex_lock_interruptible(&scan_mutex);
  	if (err < 0)
  		return ERR_PTR(err);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1690

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1691
1692
1693
1694
1695
1696
1697
1698
1699
  	rcu_read_lock();
  	list_for_each_entry_rcu(object, &object_list, object_list) {
  		if (n-- > 0)
  			continue;
  		if (get_object(object))
  			goto out;
  	}
  	object = NULL;
  out:
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
  	return object;
  }
  
  /*
   * Return the next object in the object_list. The function decrements the
   * use_count of the previous object and increases that of the next one.
   */
  static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  {
  	struct kmemleak_object *prev_obj = v;
  	struct kmemleak_object *next_obj = NULL;
58fac0956   Michael Wang   kmemleak: Replace...
1711
  	struct kmemleak_object *obj = prev_obj;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1712
1713
  
  	++(*pos);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1714

58fac0956   Michael Wang   kmemleak: Replace...
1715
  	list_for_each_entry_continue_rcu(obj, &object_list, object_list) {
52c3ce4ec   Catalin Marinas   kmemleak: Do not ...
1716
1717
  		if (get_object(obj)) {
  			next_obj = obj;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1718
  			break;
52c3ce4ec   Catalin Marinas   kmemleak: Do not ...
1719
  		}
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1720
  	}
288c857d6   Catalin Marinas   kmemleak: Remove ...
1721

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1722
1723
1724
1725
1726
1727
1728
1729
1730
  	put_object(prev_obj);
  	return next_obj;
  }
  
  /*
   * Decrement the use_count of the last object required, if any.
   */
  static void kmemleak_seq_stop(struct seq_file *seq, void *v)
  {
b87324d08   Catalin Marinas   kmemleak: Do not ...
1731
1732
1733
1734
1735
  	if (!IS_ERR(v)) {
  		/*
  		 * kmemleak_seq_start may return ERR_PTR if the scan_mutex
  		 * waiting was interrupted, so only release it if !IS_ERR.
  		 */
f5886c7f9   Catalin Marinas   kmemleak: Protect...
1736
  		rcu_read_unlock();
b87324d08   Catalin Marinas   kmemleak: Do not ...
1737
1738
1739
1740
  		mutex_unlock(&scan_mutex);
  		if (v)
  			put_object(v);
  	}
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
  }
  
  /*
   * Print the information for an unreferenced object to the seq file.
   */
  static int kmemleak_seq_show(struct seq_file *seq, void *v)
  {
  	struct kmemleak_object *object = v;
  	unsigned long flags;
  
  	spin_lock_irqsave(&object->lock, flags);
288c857d6   Catalin Marinas   kmemleak: Remove ...
1752
  	if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object))
17bb9e0d9   Catalin Marinas   kmemleak: Do not ...
1753
  		print_unreferenced(seq, object);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
  	spin_unlock_irqrestore(&object->lock, flags);
  	return 0;
  }
  
  static const struct seq_operations kmemleak_seq_ops = {
  	.start = kmemleak_seq_start,
  	.next  = kmemleak_seq_next,
  	.stop  = kmemleak_seq_stop,
  	.show  = kmemleak_seq_show,
  };
  
  static int kmemleak_open(struct inode *inode, struct file *file)
  {
b87324d08   Catalin Marinas   kmemleak: Do not ...
1767
  	return seq_open(file, &kmemleak_seq_ops);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1768
  }
189d84ed5   Catalin Marinas   kmemleak: Dump ob...
1769
1770
1771
1772
1773
  static int dump_str_object_info(const char *str)
  {
  	unsigned long flags;
  	struct kmemleak_object *object;
  	unsigned long addr;
dc053733e   Abhijit Pawar   mm/kmemleak.c: re...
1774
1775
  	if (kstrtoul(str, 0, &addr))
  		return -EINVAL;
189d84ed5   Catalin Marinas   kmemleak: Dump ob...
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
  	object = find_and_get_object(addr, 0);
  	if (!object) {
  		pr_info("Unknown object at 0x%08lx
  ", addr);
  		return -EINVAL;
  	}
  
  	spin_lock_irqsave(&object->lock, flags);
  	dump_object_info(object);
  	spin_unlock_irqrestore(&object->lock, flags);
  
  	put_object(object);
  	return 0;
  }
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1790
  /*
30b371010   Luis R. Rodriguez   kmemleak: add cle...
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
   * We use grey instead of black to ensure we can do future scans on the same
   * objects. If we did not do future scans these black objects could
   * potentially contain references to newly allocated objects in the future and
   * we'd end up with false positives.
   */
  static void kmemleak_clear(void)
  {
  	struct kmemleak_object *object;
  	unsigned long flags;
  
  	rcu_read_lock();
  	list_for_each_entry_rcu(object, &object_list, object_list) {
  		spin_lock_irqsave(&object->lock, flags);
  		if ((object->flags & OBJECT_REPORTED) &&
  		    unreferenced_object(object))
a1084c877   Luis R. Rodriguez   kmemleak: move co...
1806
  			__paint_it(object, KMEMLEAK_GREY);
30b371010   Luis R. Rodriguez   kmemleak: add cle...
1807
1808
1809
  		spin_unlock_irqrestore(&object->lock, flags);
  	}
  	rcu_read_unlock();
dc9b3f424   Li Zefan   kmemleak: free in...
1810
1811
  
  	kmemleak_found_leaks = false;
30b371010   Luis R. Rodriguez   kmemleak: add cle...
1812
  }
c89da70c7   Li Zefan   kmemleak: allow f...
1813
  static void __kmemleak_do_cleanup(void);
30b371010   Luis R. Rodriguez   kmemleak: add cle...
1814
  /*
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1815
1816
1817
1818
1819
1820
1821
1822
1823
   * File write operation to configure kmemleak at run-time. The following
   * commands can be written to the /sys/kernel/debug/kmemleak file:
   *   off	- disable kmemleak (irreversible)
   *   stack=on	- enable the task stacks scanning
   *   stack=off	- disable the tasks stacks scanning
   *   scan=on	- start the automatic memory scanning thread
   *   scan=off	- stop the automatic memory scanning thread
   *   scan=...	- set the automatic memory scanning period in seconds (0 to
   *		  disable it)
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1824
   *   scan	- trigger a memory scan
30b371010   Luis R. Rodriguez   kmemleak: add cle...
1825
   *   clear	- mark all current reported unreferenced kmemleak objects as
c89da70c7   Li Zefan   kmemleak: allow f...
1826
1827
   *		  grey to ignore printing them, or free all kmemleak objects
   *		  if kmemleak has been disabled.
189d84ed5   Catalin Marinas   kmemleak: Dump ob...
1828
   *   dump=...	- dump information about the object found at the given address
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1829
1830
1831
1832
1833
1834
   */
  static ssize_t kmemleak_write(struct file *file, const char __user *user_buf,
  			      size_t size, loff_t *ppos)
  {
  	char buf[64];
  	int buf_size;
b87324d08   Catalin Marinas   kmemleak: Do not ...
1835
  	int ret;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1836
1837
1838
1839
1840
  
  	buf_size = min(size, (sizeof(buf) - 1));
  	if (strncpy_from_user(buf, user_buf, buf_size) < 0)
  		return -EFAULT;
  	buf[buf_size] = 0;
b87324d08   Catalin Marinas   kmemleak: Do not ...
1841
1842
1843
  	ret = mutex_lock_interruptible(&scan_mutex);
  	if (ret < 0)
  		return ret;
c89da70c7   Li Zefan   kmemleak: allow f...
1844
  	if (strncmp(buf, "clear", 5) == 0) {
8910ae896   Li Zefan   kmemleak: change ...
1845
  		if (kmemleak_enabled)
c89da70c7   Li Zefan   kmemleak: allow f...
1846
1847
1848
1849
1850
  			kmemleak_clear();
  		else
  			__kmemleak_do_cleanup();
  		goto out;
  	}
8910ae896   Li Zefan   kmemleak: change ...
1851
  	if (!kmemleak_enabled) {
4e4dfce22   André Almeida   mm/kmemleak.c: ch...
1852
  		ret = -EPERM;
c89da70c7   Li Zefan   kmemleak: allow f...
1853
1854
  		goto out;
  	}
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
  	if (strncmp(buf, "off", 3) == 0)
  		kmemleak_disable();
  	else if (strncmp(buf, "stack=on", 8) == 0)
  		kmemleak_stack_scan = 1;
  	else if (strncmp(buf, "stack=off", 9) == 0)
  		kmemleak_stack_scan = 0;
  	else if (strncmp(buf, "scan=on", 7) == 0)
  		start_scan_thread();
  	else if (strncmp(buf, "scan=off", 8) == 0)
  		stop_scan_thread();
  	else if (strncmp(buf, "scan=", 5) == 0) {
  		unsigned long secs;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1867

3dbb95f78   Jingoo Han   mm: replace stric...
1868
  		ret = kstrtoul(buf + 5, 0, &secs);
b87324d08   Catalin Marinas   kmemleak: Do not ...
1869
1870
  		if (ret < 0)
  			goto out;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1871
1872
1873
1874
1875
  		stop_scan_thread();
  		if (secs) {
  			jiffies_scan_wait = msecs_to_jiffies(secs * 1000);
  			start_scan_thread();
  		}
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1876
1877
  	} else if (strncmp(buf, "scan", 4) == 0)
  		kmemleak_scan();
189d84ed5   Catalin Marinas   kmemleak: Dump ob...
1878
1879
  	else if (strncmp(buf, "dump=", 5) == 0)
  		ret = dump_str_object_info(buf + 5);
4698c1f2b   Catalin Marinas   kmemleak: Do not ...
1880
  	else
b87324d08   Catalin Marinas   kmemleak: Do not ...
1881
1882
1883
1884
1885
1886
  		ret = -EINVAL;
  
  out:
  	mutex_unlock(&scan_mutex);
  	if (ret < 0)
  		return ret;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
  
  	/* ignore the rest of the buffer, only one command at a time */
  	*ppos += size;
  	return size;
  }
  
  static const struct file_operations kmemleak_fops = {
  	.owner		= THIS_MODULE,
  	.open		= kmemleak_open,
  	.read		= seq_read,
  	.write		= kmemleak_write,
  	.llseek		= seq_lseek,
5f3bf19ae   Li Zefan   kmemleak: remove ...
1899
  	.release	= seq_release,
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1900
  };
c89da70c7   Li Zefan   kmemleak: allow f...
1901
1902
1903
1904
1905
1906
1907
1908
1909
  static void __kmemleak_do_cleanup(void)
  {
  	struct kmemleak_object *object;
  
  	rcu_read_lock();
  	list_for_each_entry_rcu(object, &object_list, object_list)
  		delete_object_full(object->pointer);
  	rcu_read_unlock();
  }
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1910
  /*
74341703e   Catalin Marinas   kmemleak: Report ...
1911
1912
1913
   * 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).
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1914
   */
179a8100e   Catalin Marinas   kmemleak: Do no c...
1915
  static void kmemleak_do_cleanup(struct work_struct *work)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1916
  {
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1917
  	stop_scan_thread();
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1918

914b6dfff   Vinayak Menon   mm/kmemleak.c: wa...
1919
  	mutex_lock(&scan_mutex);
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
1920
  	/*
914b6dfff   Vinayak Menon   mm/kmemleak.c: wa...
1921
1922
1923
1924
  	 * 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.
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
1925
1926
  	 */
  	kmemleak_free_enabled = 0;
914b6dfff   Vinayak Menon   mm/kmemleak.c: wa...
1927
  	mutex_unlock(&scan_mutex);
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
1928

c89da70c7   Li Zefan   kmemleak: allow f...
1929
1930
1931
  	if (!kmemleak_found_leaks)
  		__kmemleak_do_cleanup();
  	else
756a025f0   Joe Perches   mm: coalesce spli...
1932
1933
  		pr_info("Kmemleak disabled without freeing internal data. Reclaim the memory with \"echo clear > /sys/kernel/debug/kmemleak\".
  ");
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1934
  }
179a8100e   Catalin Marinas   kmemleak: Do no c...
1935
  static DECLARE_WORK(cleanup_work, kmemleak_do_cleanup);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1936
1937
1938
1939
1940
1941
1942
1943
  
  /*
   * 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 */
8910ae896   Li Zefan   kmemleak: change ...
1944
  	if (cmpxchg(&kmemleak_error, 0, 1))
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1945
1946
1947
  		return;
  
  	/* stop any memory operation tracing */
8910ae896   Li Zefan   kmemleak: change ...
1948
  	kmemleak_enabled = 0;
fcf3a5b62   Catalin Marinas   mm: kmemleak: dis...
1949
  	kmemleak_early_log = 0;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1950
1951
  
  	/* check whether it is too early for a kernel thread */
8910ae896   Li Zefan   kmemleak: change ...
1952
  	if (kmemleak_initialized)
179a8100e   Catalin Marinas   kmemleak: Do no c...
1953
  		schedule_work(&cleanup_work);
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
1954
1955
  	else
  		kmemleak_free_enabled = 0;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1956
1957
1958
1959
1960
1961
1962
1963
  
  	pr_info("Kernel memory leak detector disabled
  ");
  }
  
  /*
   * Allow boot-time kmemleak disabling (enabled by default).
   */
8bd30c109   Dou Liyang   mm/kmemleak.c: ma...
1964
  static int __init kmemleak_boot_config(char *str)
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1965
1966
1967
1968
1969
  {
  	if (!str)
  		return -EINVAL;
  	if (strcmp(str, "off") == 0)
  		kmemleak_disable();
ab0155a22   Jason Baron   kmemleak: Introdu...
1970
1971
1972
  	else if (strcmp(str, "on") == 0)
  		kmemleak_skip_disable = 1;
  	else
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1973
1974
1975
1976
  		return -EINVAL;
  	return 0;
  }
  early_param("kmemleak", kmemleak_boot_config);
5f79020cb   Catalin Marinas   kmemleak: Show wh...
1977
1978
  static void __init print_log_trace(struct early_log *log)
  {
5f79020cb   Catalin Marinas   kmemleak: Show wh...
1979
1980
  	pr_notice("Early log backtrace:
  ");
07984aad1   Thomas Gleixner   mm/kmemleak: Simp...
1981
  	stack_trace_print(log->trace, log->trace_len, 2);
5f79020cb   Catalin Marinas   kmemleak: Show wh...
1982
  }
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1983
  /*
2030117d2   Catalin Marinas   kmemleak: Fix som...
1984
   * Kmemleak initialization.
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1985
1986
1987
1988
1989
   */
  void __init kmemleak_init(void)
  {
  	int i;
  	unsigned long flags;
ab0155a22   Jason Baron   kmemleak: Introdu...
1990
1991
1992
1993
1994
1995
  #ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF
  	if (!kmemleak_skip_disable) {
  		kmemleak_disable();
  		return;
  	}
  #endif
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
1996
1997
1998
1999
2000
  	jiffies_min_age = msecs_to_jiffies(MSECS_MIN_AGE);
  	jiffies_scan_wait = msecs_to_jiffies(SECS_SCAN_WAIT * 1000);
  
  	object_cache = KMEM_CACHE(kmemleak_object, SLAB_NOLEAKTRACE);
  	scan_area_cache = KMEM_CACHE(kmemleak_scan_area, SLAB_NOLEAKTRACE);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2001

21cd3a604   Wang Kai   kmemleak: record ...
2002
  	if (crt_early_log > ARRAY_SIZE(early_log))
598d80914   Joe Perches   mm: convert pr_wa...
2003
2004
2005
  		pr_warn("Early log buffer exceeded (%d), please increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE
  ",
  			crt_early_log);
b66930052   Catalin Marinas   kmemleak: When th...
2006

3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2007
2008
  	/* the kernel is still in UP mode, so disabling the IRQs is enough */
  	local_irq_save(flags);
3551a9280   Catalin Marinas   mm: postpone the ...
2009
  	kmemleak_early_log = 0;
8910ae896   Li Zefan   kmemleak: change ...
2010
  	if (kmemleak_error) {
b66930052   Catalin Marinas   kmemleak: When th...
2011
2012
  		local_irq_restore(flags);
  		return;
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
2013
  	} else {
8910ae896   Li Zefan   kmemleak: change ...
2014
  		kmemleak_enabled = 1;
c5f3b1a51   Catalin Marinas   mm: kmemleak: all...
2015
2016
  		kmemleak_free_enabled = 1;
  	}
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2017
  	local_irq_restore(flags);
298a32b13   Catalin Marinas   kmemleak: powerpc...
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
  	/* register the data/bss sections */
  	create_object((unsigned long)_sdata, _edata - _sdata,
  		      KMEMLEAK_GREY, GFP_ATOMIC);
  	create_object((unsigned long)__bss_start, __bss_stop - __bss_start,
  		      KMEMLEAK_GREY, GFP_ATOMIC);
  	/* only register .data..ro_after_init if not within .data */
  	if (__start_ro_after_init < _sdata || __end_ro_after_init > _edata)
  		create_object((unsigned long)__start_ro_after_init,
  			      __end_ro_after_init - __start_ro_after_init,
  			      KMEMLEAK_GREY, GFP_ATOMIC);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
  	/*
  	 * This is the point where tracking allocations is safe. Automatic
  	 * scanning is started during the late initcall. Add the early logged
  	 * callbacks to the kmemleak infrastructure.
  	 */
  	for (i = 0; i < crt_early_log; i++) {
  		struct early_log *log = &early_log[i];
  
  		switch (log->op_type) {
  		case KMEMLEAK_ALLOC:
fd6789675   Catalin Marinas   kmemleak: Save th...
2038
  			early_alloc(log);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2039
  			break;
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
2040
2041
2042
  		case KMEMLEAK_ALLOC_PERCPU:
  			early_alloc_percpu(log);
  			break;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2043
2044
2045
  		case KMEMLEAK_FREE:
  			kmemleak_free(log->ptr);
  			break;
53238a60d   Catalin Marinas   kmemleak: Allow p...
2046
2047
2048
  		case KMEMLEAK_FREE_PART:
  			kmemleak_free_part(log->ptr, log->size);
  			break;
f528f0b8e   Catalin Marinas   kmemleak: Handle ...
2049
2050
2051
  		case KMEMLEAK_FREE_PERCPU:
  			kmemleak_free_percpu(log->ptr);
  			break;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2052
2053
2054
2055
2056
2057
2058
  		case KMEMLEAK_NOT_LEAK:
  			kmemleak_not_leak(log->ptr);
  			break;
  		case KMEMLEAK_IGNORE:
  			kmemleak_ignore(log->ptr);
  			break;
  		case KMEMLEAK_SCAN_AREA:
c017b4be3   Catalin Marinas   kmemleak: Simplif...
2059
  			kmemleak_scan_area(log->ptr, log->size, GFP_KERNEL);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2060
2061
2062
2063
  			break;
  		case KMEMLEAK_NO_SCAN:
  			kmemleak_no_scan(log->ptr);
  			break;
94f4a1618   Catalin Marinas   mm: kmemleak: tre...
2064
2065
2066
2067
  		case KMEMLEAK_SET_EXCESS_REF:
  			object_set_excess_ref((unsigned long)log->ptr,
  					      log->excess_ref);
  			break;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2068
  		default:
5f79020cb   Catalin Marinas   kmemleak: Show wh...
2069
2070
2071
2072
  			kmemleak_warn("Unknown early log operation: %d
  ",
  				      log->op_type);
  		}
8910ae896   Li Zefan   kmemleak: change ...
2073
  		if (kmemleak_warning) {
5f79020cb   Catalin Marinas   kmemleak: Show wh...
2074
  			print_log_trace(log);
8910ae896   Li Zefan   kmemleak: change ...
2075
  			kmemleak_warning = 0;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2076
2077
2078
2079
2080
2081
2082
2083
2084
  		}
  	}
  }
  
  /*
   * Late initialization function.
   */
  static int __init kmemleak_late_init(void)
  {
8910ae896   Li Zefan   kmemleak: change ...
2085
  	kmemleak_initialized = 1;
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2086

282401df9   Greg Kroah-Hartman   mm: kmemleak: no ...
2087
  	debugfs_create_file("kmemleak", 0644, NULL, NULL, &kmemleak_fops);
b353756b2   Vincent Whitchurch   kmemleak: always ...
2088

8910ae896   Li Zefan   kmemleak: change ...
2089
  	if (kmemleak_error) {
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2090
  		/*
25985edce   Lucas De Marchi   Fix common misspe...
2091
  		 * Some error occurred and kmemleak was disabled. There is a
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2092
2093
2094
2095
  		 * small chance that kmemleak_disable() was called immediately
  		 * after setting kmemleak_initialized and we may end up with
  		 * two clean-up threads but serialized by scan_mutex.
  		 */
179a8100e   Catalin Marinas   kmemleak: Do no c...
2096
  		schedule_work(&cleanup_work);
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2097
2098
  		return -ENOMEM;
  	}
d53ce0422   Sri Krishna chowdary   kmemleak: add con...
2099
2100
2101
2102
2103
  	if (IS_ENABLED(CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN)) {
  		mutex_lock(&scan_mutex);
  		start_scan_thread();
  		mutex_unlock(&scan_mutex);
  	}
3c7b4e6b8   Catalin Marinas   kmemleak: Add the...
2104
2105
2106
2107
2108
2109
2110
  
  	pr_info("Kernel memory leak detector initialized
  ");
  
  	return 0;
  }
  late_initcall(kmemleak_late_init);