Skip to content

Commit

Permalink
kmemleak: Add the base support
Browse files Browse the repository at this point in the history
This patch adds the base support for the kernel memory leak
detector. It traces the memory allocation/freeing in a way similar to
the Boehm's conservative garbage collector, the difference being that
the unreferenced objects are not freed but only shown in
/sys/kernel/debug/kmemleak. Enabling this feature introduces an
overhead to memory allocations.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
  • Loading branch information
Catalin Marinas committed Jun 11, 2009
1 parent 991ec02 commit 3c7b4e6
Show file tree
Hide file tree
Showing 3 changed files with 1,597 additions and 1 deletion.
96 changes: 96 additions & 0 deletions include/linux/kmemleak.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* include/linux/kmemleak.h
*
* Copyright (C) 2008 ARM Limited
* Written by Catalin Marinas <catalin.marinas@arm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#ifndef __KMEMLEAK_H
#define __KMEMLEAK_H

#ifdef CONFIG_DEBUG_KMEMLEAK

extern void kmemleak_init(void);
extern void kmemleak_alloc(const void *ptr, size_t size, int min_count,
gfp_t gfp);
extern void kmemleak_free(const void *ptr);
extern void kmemleak_padding(const void *ptr, unsigned long offset,
size_t size);
extern void kmemleak_not_leak(const void *ptr);
extern void kmemleak_ignore(const void *ptr);
extern void kmemleak_scan_area(const void *ptr, unsigned long offset,
size_t length, gfp_t gfp);
extern void kmemleak_no_scan(const void *ptr);

static inline void kmemleak_alloc_recursive(const void *ptr, size_t size,
int min_count, unsigned long flags,
gfp_t gfp)
{
if (!(flags & SLAB_NOLEAKTRACE))
kmemleak_alloc(ptr, size, min_count, gfp);
}

static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags)
{
if (!(flags & SLAB_NOLEAKTRACE))
kmemleak_free(ptr);
}

static inline void kmemleak_erase(void **ptr)
{
*ptr = NULL;
}

#else

static inline void kmemleak_init(void)
{
}
static inline void kmemleak_alloc(const void *ptr, size_t size, int min_count,
gfp_t gfp)
{
}
static inline void kmemleak_alloc_recursive(const void *ptr, size_t size,
int min_count, unsigned long flags,
gfp_t gfp)
{
}
static inline void kmemleak_free(const void *ptr)
{
}
static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags)
{
}
static inline void kmemleak_not_leak(const void *ptr)
{
}
static inline void kmemleak_ignore(const void *ptr)
{
}
static inline void kmemleak_scan_area(const void *ptr, unsigned long offset,
size_t length, gfp_t gfp)
{
}
static inline void kmemleak_erase(void **ptr)
{
}
static inline void kmemleak_no_scan(const void *ptr)
{
}

#endif /* CONFIG_DEBUG_KMEMLEAK */

#endif /* __KMEMLEAK_H */
4 changes: 3 additions & 1 deletion init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <linux/debug_locks.h>
#include <linux/debugobjects.h>
#include <linux/lockdep.h>
#include <linux/kmemleak.h>
#include <linux/pid_namespace.h>
#include <linux/device.h>
#include <linux/kthread.h>
Expand Down Expand Up @@ -603,6 +604,7 @@ asmlinkage void __init start_kernel(void)
/* init some links before init_ISA_irqs() */
early_irq_init();
init_IRQ();
prio_tree_init();
pidhash_init();
init_timers();
hrtimers_init();
Expand Down Expand Up @@ -654,6 +656,7 @@ asmlinkage void __init start_kernel(void)
cpu_hotplug_init();
kmem_cache_init();
kmemtrace_init();
kmemleak_init();
debug_objects_mem_init();
idr_init_cache();
setup_per_cpu_pageset();
Expand All @@ -663,7 +666,6 @@ asmlinkage void __init start_kernel(void)
calibrate_delay();
pidmap_init();
pgtable_cache_init();
prio_tree_init();
anon_vma_init();
#ifdef CONFIG_X86
if (efi_enabled)
Expand Down
Loading

0 comments on commit 3c7b4e6

Please sign in to comment.