add memory resource debug
main use is to find memory and buffer leaks at the moment
This commit is contained in:
parent
85337c9851
commit
8d5f6a65d3
|
@ -7,4 +7,4 @@ CONFIG_MISDN_HFCPCI=y
|
||||||
CONFIG_MISDN_SPEEDFAX=y
|
CONFIG_MISDN_SPEEDFAX=y
|
||||||
CONFIG_MISDN_W6692=y
|
CONFIG_MISDN_W6692=y
|
||||||
CONFIG_MISDN_DSP=y
|
CONFIG_MISDN_DSP=y
|
||||||
|
CONFIG_MISDN_MEMDEBUG=y
|
||||||
|
|
|
@ -13,6 +13,15 @@ config MISDN_DRV
|
||||||
|
|
||||||
if MISDN_DRV!=n
|
if MISDN_DRV!=n
|
||||||
|
|
||||||
|
config MISDN_MEMDEBUG
|
||||||
|
bool "Enable memory leak debug for mISDN"
|
||||||
|
help
|
||||||
|
This option is for watching the use of several resources in mISDN.
|
||||||
|
It includes extra code to maintain list of allocated memory and
|
||||||
|
sk_buffs. On module unload you can see not freed resources an
|
||||||
|
their allocation orging and some object specific informations.
|
||||||
|
If unsure, say 'N'.
|
||||||
|
|
||||||
config MISDN_AVM_FRITZ
|
config MISDN_AVM_FRITZ
|
||||||
bool "Support for AVM Fritz!Cards"
|
bool "Support for AVM Fritz!Cards"
|
||||||
depends on PCI || ISA
|
depends on PCI || ISA
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
# EXTRA_CFLAGS += -S -g
|
# EXTRA_CFLAGS += -S -g
|
||||||
#
|
#
|
||||||
|
|
||||||
|
ifdef CONFIG_MISDN_MEMDEBUG
|
||||||
|
EXTRA_CFLAGS += -DMISDN_MEMDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_MISDN_DRV) += mISDN_core.o
|
obj-$(CONFIG_MISDN_DRV) += mISDN_core.o
|
||||||
obj-$(CONFIG_MISDN_DRV) += mISDN_isac.o
|
obj-$(CONFIG_MISDN_DRV) += mISDN_isac.o
|
||||||
obj-$(CONFIG_MISDN_DRV) += mISDN_l1.o
|
obj-$(CONFIG_MISDN_DRV) += mISDN_l1.o
|
||||||
|
@ -43,6 +47,9 @@ hfcpci-objs := hfc_pci.o debug.o helper.o dchannel.o bchannel.o
|
||||||
w6692pci-objs := w6692.o debug.o helper.o dchannel.o bchannel.o
|
w6692pci-objs := w6692.o debug.o helper.o dchannel.o bchannel.o
|
||||||
mISDN_isac-objs := isac.o arcofi.o debug.o
|
mISDN_isac-objs := isac.o arcofi.o debug.o
|
||||||
mISDN_core-objs := core.o stack.o udevice.o helper.o
|
mISDN_core-objs := core.o stack.o udevice.o helper.o
|
||||||
|
ifdef CONFIG_MISDN_MEMDEBUG
|
||||||
|
mISDN_core-objs += memdbg.o
|
||||||
|
endif
|
||||||
mISDN_l1-objs := layer1.o helper.o debug.o fsm.o
|
mISDN_l1-objs := layer1.o helper.o debug.o fsm.o
|
||||||
mISDN_l2-objs := layer2.o tei.o helper.o debug.o fsm.o
|
mISDN_l2-objs := layer2.o tei.o helper.o debug.o fsm.o
|
||||||
l3udss1-objs := layer3.o helper.o l3helper.o debug.o fsm.o l3_udss1.o
|
l3udss1-objs := layer3.o helper.o l3helper.o debug.o fsm.o l3_udss1.o
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
# EXTRA_CFLAGS += -S -g
|
# EXTRA_CFLAGS += -S -g
|
||||||
#
|
#
|
||||||
|
|
||||||
|
ifdef CONFIG_MISDN_MEMDEBUG
|
||||||
|
EXTRA_CFLAGS += -DMISDN_MEMDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_MISDN_DRV) += mISDN_core.o
|
obj-$(CONFIG_MISDN_DRV) += mISDN_core.o
|
||||||
obj-$(CONFIG_MISDN_DRV) += mISDN_isac.o
|
obj-$(CONFIG_MISDN_DRV) += mISDN_isac.o
|
||||||
obj-$(CONFIG_MISDN_DRV) += mISDN_l1.o
|
obj-$(CONFIG_MISDN_DRV) += mISDN_l1.o
|
||||||
|
@ -43,6 +47,9 @@ hfcpci-objs := hfc_pci.o debug.o helper.o dchannel.o bchannel.o
|
||||||
w6692pci-objs := w6692.o debug.o helper.o dchannel.o bchannel.o
|
w6692pci-objs := w6692.o debug.o helper.o dchannel.o bchannel.o
|
||||||
mISDN_isac-objs := isac.o arcofi.o debug.o
|
mISDN_isac-objs := isac.o arcofi.o debug.o
|
||||||
mISDN_core-objs := core.o stack.o udevice.o helper.o
|
mISDN_core-objs := core.o stack.o udevice.o helper.o
|
||||||
|
ifdef CONFIG_MISDN_MEMDEBUG
|
||||||
|
mISDN_core-objs += memdbg.o
|
||||||
|
endif
|
||||||
mISDN_l1-objs := layer1.o helper.o debug.o fsm.o
|
mISDN_l1-objs := layer1.o helper.o debug.o fsm.o
|
||||||
mISDN_l2-objs := layer2.o tei.o helper.o debug.o fsm.o
|
mISDN_l2-objs := layer2.o tei.o helper.o debug.o fsm.o
|
||||||
l3udss1-objs := layer3.o helper.o l3helper.o debug.o fsm.o l3_udss1.o
|
l3udss1-objs := layer3.o helper.o l3helper.o debug.o fsm.o l3_udss1.o
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
|
|
||||||
O_TARGET := vmlinux-obj.o
|
O_TARGET := vmlinux-obj.o
|
||||||
|
|
||||||
ifdef MEMDBG
|
ifdef CONFIG_MISDN_MEMDEBUG
|
||||||
EXTRA_CFLAGS += -DMEMDBG
|
export-objs += memdbg.o
|
||||||
MX_OBJS += memdbg.o
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
export-objs := core.o isac.o
|
export-objs := core.o isac.o
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#ifdef MEMDBG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -609,6 +609,11 @@ mISDNInit(void)
|
||||||
|
|
||||||
printk(KERN_INFO "Modular ISDN Stack core %s\n", mISDN_core_revision);
|
printk(KERN_INFO "Modular ISDN Stack core %s\n", mISDN_core_revision);
|
||||||
core_debug = debug;
|
core_debug = debug;
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
err = __mid_init();
|
||||||
|
if (err)
|
||||||
|
return(err);
|
||||||
|
#endif
|
||||||
err = init_mISDNdev(debug);
|
err = init_mISDNdev(debug);
|
||||||
if (err)
|
if (err)
|
||||||
return(err);
|
return(err);
|
||||||
|
@ -652,6 +657,9 @@ void mISDN_cleanup(void) {
|
||||||
down(&sem);
|
down(&sem);
|
||||||
mISDN_thread.notify = NULL;
|
mISDN_thread.notify = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
__mid_cleanup();
|
||||||
|
#endif
|
||||||
printk(KERN_DEBUG "mISDNcore unloaded\n");
|
printk(KERN_DEBUG "mISDNcore unloaded\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/mISDNif.h>
|
#include <linux/mISDNif.h>
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#ifdef MEMDBG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#ifdef MEMDBG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#ifndef _mISDN_HELPER_H
|
#ifndef _mISDN_HELPER_H
|
||||||
#define _mISDN_HELPER_H
|
#define _mISDN_HELPER_H
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#ifdef MEMDBG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -69,12 +69,22 @@ discard_queue(struct sk_buff_head *q)
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
#define alloc_stack_skb(s, r) __mid_alloc_stack_skb(s, r, __FILE__, __LINE__)
|
||||||
|
static inline struct sk_buff *
|
||||||
|
__mid_alloc_stack_skb(size_t size, size_t reserve, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
if (!(skb = __mid_alloc_skb(size + reserve, GFP_ATOMIC, fn, line)))
|
||||||
|
#else
|
||||||
static inline struct sk_buff *
|
static inline struct sk_buff *
|
||||||
alloc_stack_skb(size_t size, size_t reserve)
|
alloc_stack_skb(size_t size, size_t reserve)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
if (!(skb = alloc_skb(size + reserve, GFP_ATOMIC)))
|
if (!(skb = alloc_skb(size + reserve, GFP_ATOMIC)))
|
||||||
|
#endif
|
||||||
printk(KERN_WARNING "%s(%d,%d): no skb size\n", __FUNCTION__,
|
printk(KERN_WARNING "%s(%d,%d): no skb size\n", __FUNCTION__,
|
||||||
size, reserve);
|
size, reserve);
|
||||||
else
|
else
|
||||||
|
@ -119,13 +129,22 @@ extern __inline__ int if_newhead(mISDNif_t *i, u_int prim, int dinfo,
|
||||||
return(i->func(i, skb));
|
return(i->func(i, skb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
#define create_link_skb(p, d, l, a, r) __mid_create_link_skb(p, d, l, a, r, __FILE__, __LINE__)
|
||||||
|
extern __inline__ struct sk_buff *
|
||||||
|
__mid_create_link_skb(u_int prim, int dinfo, int len, void *arg, int reserve, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
extern __inline__ struct sk_buff *create_link_skb(u_int prim, int dinfo,
|
if (!(skb = __mid_alloc_skb(len + reserve, GFP_ATOMIC, fn, line))) {
|
||||||
int len, void *arg, int reserve)
|
#else
|
||||||
|
extern __inline__ struct sk_buff *
|
||||||
|
create_link_skb(u_int prim, int dinfo, int len, void *arg, int reserve)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
if (!(skb = alloc_skb(len + reserve, GFP_ATOMIC))) {
|
if (!(skb = alloc_skb(len + reserve, GFP_ATOMIC))) {
|
||||||
|
#endif
|
||||||
printk(KERN_WARNING "%s: no skb size %d+%d\n",
|
printk(KERN_WARNING "%s: no skb size %d+%d\n",
|
||||||
__FUNCTION__, len, reserve);
|
__FUNCTION__, len, reserve);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
@ -137,13 +156,24 @@ extern __inline__ struct sk_buff *create_link_skb(u_int prim, int dinfo,
|
||||||
return(skb);
|
return(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ int if_link(mISDNif_t *i, u_int prim, int dinfo, int len,
|
#ifdef MISDN_MEMDEBUG
|
||||||
void *arg, int reserve)
|
#define if_link(i, p, d, l, a, r) __mid_if_link(i, p, d, l, a, r, __FILE__, __LINE__)
|
||||||
|
extern __inline__ int
|
||||||
|
__mid_if_link(mISDNif_t *i, u_int prim, int dinfo, int len, void *arg, int reserve, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!(skb = __mid_create_link_skb(prim, dinfo, len, arg, reserve, fn, line)))
|
||||||
|
#else
|
||||||
|
extern __inline__ int
|
||||||
|
if_link(mISDNif_t *i, u_int prim, int dinfo, int len, void *arg, int reserve)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!(skb = create_link_skb(prim, dinfo, len, arg, reserve)))
|
if (!(skb = create_link_skb(prim, dinfo, len, arg, reserve)))
|
||||||
|
#endif
|
||||||
return(-ENOMEM);
|
return(-ENOMEM);
|
||||||
if (!i)
|
if (!i)
|
||||||
err = -ENXIO;
|
err = -ENXIO;
|
||||||
|
@ -159,7 +189,12 @@ extern __inline__ int if_link(mISDNif_t *i, u_int prim, int dinfo, int len,
|
||||||
extern signed int l3_ie2pos(u_char);
|
extern signed int l3_ie2pos(u_char);
|
||||||
extern unsigned char l3_pos2ie(int);
|
extern unsigned char l3_pos2ie(int);
|
||||||
extern void initQ931_info(Q931_info_t *);
|
extern void initQ931_info(Q931_info_t *);
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
#define alloc_l3msg(a, b) __mid_alloc_l3msg(a, b, __FILE__, __LINE__)
|
||||||
|
extern struct sk_buff *__mid_alloc_l3msg(int, u_char, char *, int);
|
||||||
|
#else
|
||||||
extern struct sk_buff *alloc_l3msg(int, u_char);
|
extern struct sk_buff *alloc_l3msg(int, u_char);
|
||||||
|
#endif
|
||||||
extern void AddvarIE(struct sk_buff *, u_char *);
|
extern void AddvarIE(struct sk_buff *, u_char *);
|
||||||
extern void AddIE(struct sk_buff *, u_char, u_char *);
|
extern void AddIE(struct sk_buff *, u_char, u_char *);
|
||||||
extern void LogL3Msg(struct sk_buff *);
|
extern void LogL3Msg(struct sk_buff *);
|
||||||
|
|
|
@ -52,12 +52,20 @@ initQ931_info(Q931_info_t *qi) {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sk_buff *
|
struct sk_buff *
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
__mid_alloc_l3msg(int len, u_char type, char *fn, int line)
|
||||||
|
#else
|
||||||
alloc_l3msg(int len, u_char type)
|
alloc_l3msg(int len, u_char type)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
Q931_info_t *qi;
|
Q931_info_t *qi;
|
||||||
|
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
if (!(skb = __mid_alloc_skb(len + L3_EXTRA_SIZE +1, GFP_ATOMIC, fn, line))) {
|
||||||
|
#else
|
||||||
if (!(skb = alloc_skb(len + L3_EXTRA_SIZE +1, GFP_ATOMIC))) {
|
if (!(skb = alloc_skb(len + L3_EXTRA_SIZE +1, GFP_ATOMIC))) {
|
||||||
|
#endif
|
||||||
printk(KERN_WARNING "mISDN: No skb for L3\n");
|
printk(KERN_WARNING "mISDN: No skb for L3\n");
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include <linux/mISDNif.h>
|
#include <linux/mISDNif.h>
|
||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
#ifdef MEMDBG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <linux/mISDNif.h>
|
#include <linux/mISDNif.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
#ifdef MEMDBG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ l3_process_t
|
||||||
l3_process_t
|
l3_process_t
|
||||||
*new_l3_process(layer3_t *l3, int cr, int n303, u_int id)
|
*new_l3_process(layer3_t *l3, int cr, int n303, u_int id)
|
||||||
{
|
{
|
||||||
l3_process_t *p;
|
l3_process_t *p = NULL;
|
||||||
|
|
||||||
if (id == MISDN_ID_ANY) {
|
if (id == MISDN_ID_ANY) {
|
||||||
if (l3->entity == MISDN_ENTITY_NONE) {
|
if (l3->entity == MISDN_ENTITY_NONE) {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <linux/mISDNif.h>
|
#include <linux/mISDNif.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
#ifdef MEMDBG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
#include <linux/stddef.h>
|
||||||
|
#include <linux/config.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/mISDNif.h>
|
||||||
|
#ifdef CONFIG_KMOD
|
||||||
|
#include <linux/kmod.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct list_head mISDN_memdbg_list = LIST_HEAD_INIT(mISDN_memdbg_list);
|
||||||
|
static struct list_head mISDN_skbdbg_list = LIST_HEAD_INIT(mISDN_skbdbg_list);
|
||||||
|
static kmem_cache_t *mid_sitem_cache;
|
||||||
|
|
||||||
|
#define MAX_FILE_STRLEN (64 - 3*sizeof(u_int) - sizeof(struct list_head))
|
||||||
|
|
||||||
|
#define MID_ITEM_TYP_KMALLOC 1
|
||||||
|
#define MID_ITEM_TYP_VMALLOC 2
|
||||||
|
|
||||||
|
typedef struct _mid_item {
|
||||||
|
struct list_head head;
|
||||||
|
u_int typ;
|
||||||
|
u_int size;
|
||||||
|
u_int line;
|
||||||
|
char file[MAX_FILE_STRLEN];
|
||||||
|
} _mid_item_t;
|
||||||
|
|
||||||
|
typedef struct _mid_sitem {
|
||||||
|
struct list_head head;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
unsigned int size;
|
||||||
|
int line;
|
||||||
|
char file[MAX_FILE_STRLEN];
|
||||||
|
} _mid_sitem_t;
|
||||||
|
|
||||||
|
void *
|
||||||
|
__mid_kmalloc(size_t size, int ord, char *fn, int line)
|
||||||
|
{
|
||||||
|
_mid_item_t *mid;
|
||||||
|
|
||||||
|
mid = kmalloc(size + sizeof(_mid_item_t), ord);
|
||||||
|
if (mid) {
|
||||||
|
INIT_LIST_HEAD(&mid->head);
|
||||||
|
mid->typ = MID_ITEM_TYP_KMALLOC;
|
||||||
|
mid->size = size;
|
||||||
|
mid->line = line;
|
||||||
|
memcpy(mid->file, fn, MAX_FILE_STRLEN);
|
||||||
|
mid->file[MAX_FILE_STRLEN-1] = 0;
|
||||||
|
list_add_tail(&mid->head, &mISDN_memdbg_list);
|
||||||
|
return((void *)&mid->file[MAX_FILE_STRLEN]);
|
||||||
|
} else
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__mid_kfree(const void *p)
|
||||||
|
{
|
||||||
|
_mid_item_t *mid;
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
printk(KERN_ERR "zero pointer kfree at %p", __builtin_return_address(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mid = (_mid_item_t *)((u_char *)p - sizeof(_mid_item_t));
|
||||||
|
list_del(&mid->head);
|
||||||
|
kfree(mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
__mid_vmalloc(size_t size, char *fn, int line)
|
||||||
|
{
|
||||||
|
_mid_item_t *mid;
|
||||||
|
|
||||||
|
mid = vmalloc(size + sizeof(_mid_item_t));
|
||||||
|
if (mid) {
|
||||||
|
INIT_LIST_HEAD(&mid->head);
|
||||||
|
mid->typ = MID_ITEM_TYP_VMALLOC;
|
||||||
|
mid->size = size;
|
||||||
|
mid->line = line;
|
||||||
|
memcpy(mid->file, fn, MAX_FILE_STRLEN);
|
||||||
|
mid->file[MAX_FILE_STRLEN-1] = 0;
|
||||||
|
list_add_tail(&mid->head, &mISDN_memdbg_list);
|
||||||
|
return((void *)&mid->file[MAX_FILE_STRLEN]);
|
||||||
|
} else
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__mid_vfree(const void *p)
|
||||||
|
{
|
||||||
|
_mid_item_t *mid;
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
printk(KERN_ERR "zero pointer vfree at %p", __builtin_return_address(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mid = (_mid_item_t *)((u_char *)p - sizeof(_mid_item_t));
|
||||||
|
list_del(&mid->head);
|
||||||
|
vfree(mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__mid_skb_destructor(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct list_head *item, *next;
|
||||||
|
_mid_sitem_t *sid;
|
||||||
|
|
||||||
|
list_for_each_safe(item, next, &mISDN_skbdbg_list) {
|
||||||
|
sid = (_mid_sitem_t *)item;
|
||||||
|
if (sid->skb == skb) {
|
||||||
|
list_del(&sid->head);
|
||||||
|
kmem_cache_free(mid_sitem_cache, sid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printk(KERN_DEBUG "%s: item(%p) not in list\n", __FUNCTION__, skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void
|
||||||
|
__mid_sitem_setup(struct sk_buff *skb, unsigned int size, char *fn, int line)
|
||||||
|
{
|
||||||
|
_mid_sitem_t *sid;
|
||||||
|
|
||||||
|
sid = kmem_cache_alloc(mid_sitem_cache, GFP_ATOMIC);
|
||||||
|
if (!sid)
|
||||||
|
return;
|
||||||
|
INIT_LIST_HEAD(&sid->head);
|
||||||
|
sid->skb = skb;
|
||||||
|
sid->size = size;
|
||||||
|
sid->line = line;
|
||||||
|
memcpy(sid->file, fn, MAX_FILE_STRLEN);
|
||||||
|
sid->file[MAX_FILE_STRLEN-1] = 0;
|
||||||
|
skb->destructor = __mid_skb_destructor;
|
||||||
|
list_add_tail(&sid->head, &mISDN_skbdbg_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sk_buff *
|
||||||
|
__mid_alloc_skb(unsigned int size, int gfp_mask, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb = alloc_skb(size, gfp_mask);
|
||||||
|
|
||||||
|
if (!skb)
|
||||||
|
return(NULL);
|
||||||
|
__mid_sitem_setup(skb, size, fn, line);
|
||||||
|
return(skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sk_buff *
|
||||||
|
__mid_dev_alloc_skb(unsigned int size, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb = dev_alloc_skb(size);
|
||||||
|
|
||||||
|
if (!skb)
|
||||||
|
return(NULL);
|
||||||
|
__mid_sitem_setup(skb, size, fn, line);
|
||||||
|
return(skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sk_buff
|
||||||
|
*__mid_skb_clone(struct sk_buff *skb, int gfp_mask, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *nskb = skb_clone(skb, gfp_mask);
|
||||||
|
|
||||||
|
if (!nskb)
|
||||||
|
return(NULL);
|
||||||
|
__mid_sitem_setup(nskb, (nskb->end - nskb->head), fn, line);
|
||||||
|
return(nskb);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sk_buff
|
||||||
|
*__mid_skb_copy(struct sk_buff *skb, int gfp_mask, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *nskb = skb_copy(skb, gfp_mask);
|
||||||
|
|
||||||
|
if (!nskb)
|
||||||
|
return(NULL);
|
||||||
|
__mid_sitem_setup(nskb, (nskb->end - nskb->head), fn, line);
|
||||||
|
return(nskb);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sk_buff
|
||||||
|
*__mid_skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom, char *fn, int line)
|
||||||
|
{
|
||||||
|
struct sk_buff *nskb = skb_realloc_headroom(skb, headroom);
|
||||||
|
|
||||||
|
if (!nskb || (nskb == skb))
|
||||||
|
return(nskb);
|
||||||
|
__mid_sitem_setup(nskb, (nskb->end - nskb->head), fn, line);
|
||||||
|
return(nskb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__mid_cleanup(void)
|
||||||
|
{
|
||||||
|
struct list_head *item, *next;
|
||||||
|
_mid_item_t *mid;
|
||||||
|
_mid_sitem_t *sid;
|
||||||
|
mISDN_head_t *hh;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
list_for_each_safe(item, next, &mISDN_memdbg_list) {
|
||||||
|
mid = (_mid_item_t *)item;
|
||||||
|
switch(mid->typ) {
|
||||||
|
case MID_ITEM_TYP_KMALLOC:
|
||||||
|
printk(KERN_ERR "not freed kmalloc size(%d) from %s:%d\n",
|
||||||
|
mid->size, mid->file, mid->line);
|
||||||
|
kfree(mid);
|
||||||
|
break;
|
||||||
|
case MID_ITEM_TYP_VMALLOC:
|
||||||
|
printk(KERN_ERR "not freed vmalloc size(%d) from %s:%d\n",
|
||||||
|
mid->size, mid->file, mid->line);
|
||||||
|
vfree(mid);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_ERR "unknown mid->typ(%d) size(%d) from %s:%d\n",
|
||||||
|
mid->typ, mid->size, mid->file, mid->line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
printk(KERN_DEBUG "%s: %d kmalloc item(s) freed\n", __FUNCTION__, n);
|
||||||
|
n = 0;
|
||||||
|
list_for_each_safe(item, next, &mISDN_skbdbg_list) {
|
||||||
|
sid = (_mid_sitem_t *)item;
|
||||||
|
hh = mISDN_HEAD_P(sid->skb);
|
||||||
|
printk(KERN_ERR "not freed skb(%p) size(%d) prim(%x) dinfo(%x) allocated at %s:%d\n",
|
||||||
|
sid->skb, sid->size, hh->prim, hh->dinfo, sid->file, sid->line);
|
||||||
|
/*maybe the skb is still aktiv */
|
||||||
|
sid->skb->destructor = NULL;
|
||||||
|
list_del(&sid->head);
|
||||||
|
kmem_cache_free(mid_sitem_cache, sid);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mid_sitem_cache)
|
||||||
|
kmem_cache_destroy(mid_sitem_cache);
|
||||||
|
printk(KERN_DEBUG "%s: %d sk_buff item(s) freed\n", __FUNCTION__, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__mid_init(void)
|
||||||
|
{
|
||||||
|
mid_sitem_cache = kmem_cache_create("mISDN_skbdbg",
|
||||||
|
sizeof(_mid_sitem_t),
|
||||||
|
0, 0, NULL, NULL);
|
||||||
|
if (!mid_sitem_cache)
|
||||||
|
return(-ENOMEM);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE
|
||||||
|
EXPORT_SYMBOL(__mid_kmalloc);
|
||||||
|
EXPORT_SYMBOL(__mid_kfree);
|
||||||
|
EXPORT_SYMBOL(__mid_vmalloc);
|
||||||
|
EXPORT_SYMBOL(__mid_vfree);
|
||||||
|
EXPORT_SYMBOL(__mid_alloc_skb);
|
||||||
|
EXPORT_SYMBOL(__mid_dev_alloc_skb);
|
||||||
|
EXPORT_SYMBOL(__mid_skb_clone);
|
||||||
|
EXPORT_SYMBOL(__mid_skb_copy);
|
||||||
|
EXPORT_SYMBOL(__mid_skb_realloc_headroom);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef MEMDBG_H
|
||||||
|
#define MEMDBG_H
|
||||||
|
|
||||||
|
#ifdef MISDN_MEMDEBUG
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#undef kmalloc
|
||||||
|
#undef kfree
|
||||||
|
#undef vmalloc
|
||||||
|
#undef vfree
|
||||||
|
#undef alloc_skb
|
||||||
|
#undef dev_alloc_skb
|
||||||
|
#undef skb_clone
|
||||||
|
#undef skb_copy
|
||||||
|
#undef skb_realloc_headroom
|
||||||
|
|
||||||
|
#define kmalloc(a, b) __mid_kmalloc(a, b, __FILE__, __LINE__)
|
||||||
|
#define kfree(a) __mid_kfree(a)
|
||||||
|
#define vmalloc(s) __mid_vmalloc(s, __FILE__, __LINE__)
|
||||||
|
#define vfree(p) __mid_vfree(p)
|
||||||
|
#define alloc_skb(a, b) __mid_alloc_skb(a, b, __FILE__, __LINE__)
|
||||||
|
#define dev_alloc_skb(a) __mid_dev_alloc_skb(a, __FILE__, __LINE__)
|
||||||
|
#define skb_clone(a, b) __mid_skb_clone(a, b, __FILE__, __LINE__)
|
||||||
|
#define skb_copy(a, b) __mid_skb_copy(a, b, __FILE__, __LINE__)
|
||||||
|
#define skb_realloc_headroom(a, b) __mid_skb_realloc_headroom(a, b, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
extern void *__mid_kmalloc(size_t, int, char *, int);
|
||||||
|
extern void __mid_kfree(const void *);
|
||||||
|
extern void *__mid_vmalloc(size_t, char *, int);
|
||||||
|
extern void __mid_vfree(const void *);
|
||||||
|
extern void __mid_cleanup(void);
|
||||||
|
extern int __mid_init(void);
|
||||||
|
extern struct sk_buff *__mid_alloc_skb(unsigned int,int, char *, int);
|
||||||
|
extern struct sk_buff *__mid_dev_alloc_skb(unsigned int,char *, int);
|
||||||
|
extern struct sk_buff *__mid_skb_clone(struct sk_buff *, int, char *, int);
|
||||||
|
extern struct sk_buff *__mid_skb_copy(struct sk_buff *, int, char *, int);
|
||||||
|
extern struct sk_buff *__mid_skb_realloc_headroom(struct sk_buff *, unsigned int, char *, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,7 +1,7 @@
|
||||||
Vendor: SuSE GmbH, Nuernberg, Germany
|
Vendor: SuSE GmbH, Nuernberg, Germany
|
||||||
Distribution: SuSE Linux 8.2 (i386)
|
Distribution: SuSE Linux 8.2 (i386)
|
||||||
Name: km_mISDN
|
Name: km_mISDN
|
||||||
Release: 8
|
Release: 9
|
||||||
Packager: feedback@suse.de
|
Packager: feedback@suse.de
|
||||||
|
|
||||||
Copyright: Karsten Keil GPL
|
Copyright: Karsten Keil GPL
|
||||||
|
|
Loading…
Reference in New Issue