diff options
author | Chris Kelly <ckelly@ozmodevices.com> | 2012-02-20 21:12:35 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-02-24 09:26:52 -0800 |
commit | 066b2229410f2f58fa91baedd22b4dcf048e28dd (patch) | |
tree | f2ce1ae3878d72254c6eec9b9e04f38859e09a65 /drivers/staging/ozwpan/ozalloc.c | |
parent | 56ff32fe1cf24d624ca4a68a409753fb3fd593f6 (diff) |
staging: ozwpan: Added debug support
Added tracing facilities and also memory allocation and URB tracking.
This is for debugging purposes and is all optional and can be switched
out at compile time.
Signed-off-by: Chris Kelly <ckelly@ozmodevices.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/ozwpan/ozalloc.c')
-rw-r--r-- | drivers/staging/ozwpan/ozalloc.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/drivers/staging/ozwpan/ozalloc.c b/drivers/staging/ozwpan/ozalloc.c new file mode 100644 index 000000000000..fe3cd406e4fa --- /dev/null +++ b/drivers/staging/ozwpan/ozalloc.c @@ -0,0 +1,107 @@ +/* ----------------------------------------------------------------------------- + * Copyright (c) 2011 Ozmo Inc + * Released under the GNU General Public License Version 2 (GPLv2). + * This file contains debug allocation and free functions. These are turned on + * by the configuration switch WANT_DEBUG_KMALLOC. This flags should be turned + * off in the release version but facilitate memory leak and corruption during + * development. + * ----------------------------------------------------------------------------- + */ +#include <linux/module.h> +#include "ozconfig.h" +#include "ozalloc.h" +#include "oztrace.h" +#ifdef WANT_DEBUG_KMALLOC +/*------------------------------------------------------------------------------ + */ +#define MAGIC_1 0x12848796 +#define MAGIC_2 0x87465920 +#define MAGIC_3 0x80288264 +/*------------------------------------------------------------------------------ + */ +struct oz_alloc_hdr { + int size; + int line; + unsigned magic; + struct list_head link; +}; +/*------------------------------------------------------------------------------ + */ +static unsigned long g_total_alloc_size; +static int g_alloc_count; +static DEFINE_SPINLOCK(g_alloc_lock); +static LIST_HEAD(g_alloc_list); +/*------------------------------------------------------------------------------ + * Context: any + */ +void *oz_alloc_debug(size_t size, gfp_t flags, int line) +{ + struct oz_alloc_hdr *hdr = (struct oz_alloc_hdr *) + kmalloc(size + sizeof(struct oz_alloc_hdr) + + sizeof(unsigned), flags); + if (hdr) { + unsigned long irq_state; + hdr->size = size; + hdr->line = line; + hdr->magic = MAGIC_1; + *(unsigned *)(((u8 *)(hdr + 1)) + size) = MAGIC_2; + spin_lock_irqsave(&g_alloc_lock, irq_state); + g_total_alloc_size += size; + g_alloc_count++; + list_add_tail(&hdr->link, &g_alloc_list); + spin_unlock_irqrestore(&g_alloc_lock, irq_state); + return hdr + 1; + } + return 0; +} +/*------------------------------------------------------------------------------ + * Context: any + */ +void oz_free_debug(void *p) +{ + if (p) { + struct oz_alloc_hdr *hdr = (struct oz_alloc_hdr *) + (((unsigned char *)p) - sizeof(struct oz_alloc_hdr)); + if (hdr->magic == MAGIC_1) { + unsigned long irq_state; + if (*(unsigned *)(((u8 *)(hdr + 1)) + hdr->size) + != MAGIC_2) { + oz_trace("oz_free_debug: Corrupted beyond" + " %p size %d\n", hdr+1, hdr->size); + return; + } + spin_lock_irqsave(&g_alloc_lock, irq_state); + g_total_alloc_size -= hdr->size; + g_alloc_count--; + list_del(&hdr->link); + spin_unlock_irqrestore(&g_alloc_lock, irq_state); + hdr->magic = MAGIC_3; + kfree(hdr); + } else { + oz_trace("oz_free_debug: Invalid magic number %u\n", + hdr->magic); + } + } +} +/*------------------------------------------------------------------------------ + * Context: process + */ +void oz_trace_leaks(void) +{ +#ifdef WANT_TRACE + struct list_head *e; + oz_trace("Total alloc size:%ld Alloc count:%d\n", + g_total_alloc_size, g_alloc_count); + if (g_alloc_count) + oz_trace("Trace of leaks.\n"); + else + oz_trace("No memory leaks.\n"); + list_for_each(e, &g_alloc_list) { + struct oz_alloc_hdr *hdr = + container_of(e, struct oz_alloc_hdr, link); + oz_trace("LEAK size %d line %d\n", hdr->size, hdr->line); + } +#endif /* #ifdef WANT_TRACE */ +} +#endif /* #ifdef WANT_DEBUG_KMALLOC */ + |