mirror of https://github.com/proski/madwifi
Re-enable skb debug destructor, chaining to original when present.
Split skb and node debug flags - one ending in _ref tracks minute changes to reference counts, while the non _ref flag trackes more coarse grained debug events. Fix a node reference leak before skb_orphan detected by the debug destructor. Fix debug flag display order for athdebug and 80211debug so that the shorter name comes first and matches, otherwise only the _ref flags match. git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@2964 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
parent
15587c9e84
commit
ec5e8e0a11
|
@ -446,7 +446,7 @@ enum {
|
||||||
ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */
|
ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */
|
||||||
ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
||||||
ATH_DEBUG_RESET = 0x00000020, /* reset processing */
|
ATH_DEBUG_RESET = 0x00000020, /* reset processing */
|
||||||
/* 0x00000040 was ATH_DEBUG_MODE */
|
ATH_DEBUG_SKB_REF = 0x00000040, /* sbk references */
|
||||||
ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */
|
ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */
|
||||||
ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */
|
ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */
|
||||||
ATH_DEBUG_INTR = 0x00001000, /* ISR */
|
ATH_DEBUG_INTR = 0x00001000, /* ISR */
|
||||||
|
@ -456,7 +456,6 @@ enum {
|
||||||
ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */
|
ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */
|
||||||
ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */
|
ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */
|
||||||
ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
|
ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
|
||||||
ATH_DEBUG_NODE = 0x00080000, /* node management */
|
|
||||||
ATH_DEBUG_LED = 0x00100000, /* led management */
|
ATH_DEBUG_LED = 0x00100000, /* led management */
|
||||||
ATH_DEBUG_FF = 0x00200000, /* fast frames */
|
ATH_DEBUG_FF = 0x00200000, /* fast frames */
|
||||||
ATH_DEBUG_TURBO = 0x00400000, /* turbo/dynamic turbo */
|
ATH_DEBUG_TURBO = 0x00400000, /* turbo/dynamic turbo */
|
||||||
|
@ -474,7 +473,7 @@ enum {
|
||||||
* to all vaps] */
|
* to all vaps] */
|
||||||
ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
||||||
ATH_DEBUG_ANY = 0xffffffff,
|
ATH_DEBUG_ANY = 0xffffffff,
|
||||||
ATH_DEBUG_GLOBAL = (ATH_DEBUG_SKB)
|
ATH_DEBUG_GLOBAL = (ATH_DEBUG_SKB|ATH_DEBUG_SKB_REF)
|
||||||
};
|
};
|
||||||
#define DPRINTF(sc, _m, _fmt, ...) do { \
|
#define DPRINTF(sc, _m, _fmt, ...) do { \
|
||||||
if (DFLAG_ISSET(sc, (_m))) { \
|
if (DFLAG_ISSET(sc, (_m))) { \
|
||||||
|
@ -5859,6 +5858,8 @@ ath_tx_capture(struct net_device *dev, const struct ath_buf *bf, struct sk_buff
|
||||||
SKB_CB(skb)->ni = ieee80211_ref_node(SKB_CB(skb_orig)->ni);
|
SKB_CB(skb)->ni = ieee80211_ref_node(SKB_CB(skb_orig)->ni);
|
||||||
ieee80211_dev_kfree_skb(&skb_orig);
|
ieee80211_dev_kfree_skb(&skb_orig);
|
||||||
} else {
|
} else {
|
||||||
|
if (SKB_CB(skb)->ni != NULL)
|
||||||
|
ieee80211_unref_node(&SKB_CB(skb)->ni);
|
||||||
skb_orphan(skb);
|
skb_orphan(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
/* Set to true if ANY sc has skb debugging on */
|
/* Set to true if ANY sc has skb debugging on */
|
||||||
extern int ath_debug_global;
|
extern int ath_debug_global;
|
||||||
enum {
|
enum {
|
||||||
|
GLOBAL_DEBUG_SKB_REF = 0x00000040, /* SKB referernce counting */
|
||||||
GLOBAL_DEBUG_SKB = 0x40000000, /* SKB usage/leak debugging,
|
GLOBAL_DEBUG_SKB = 0x40000000, /* SKB usage/leak debugging,
|
||||||
must match ATH_DEBUG_SKB */
|
must match ATH_DEBUG_SKB */
|
||||||
};
|
};
|
||||||
|
|
|
@ -392,6 +392,7 @@ struct ieee80211_cb {
|
||||||
#define M_RAW 0x10
|
#define M_RAW 0x10
|
||||||
#ifdef IEEE80211_DEBUG_REFCNT
|
#ifdef IEEE80211_DEBUG_REFCNT
|
||||||
int tracked;
|
int tracked;
|
||||||
|
void (*next_destructor)(struct sk_buff *skb);
|
||||||
#endif
|
#endif
|
||||||
struct sk_buff *next; /* fast frame sk_buf chain */
|
struct sk_buff *next; /* fast frame sk_buf chain */
|
||||||
};
|
};
|
||||||
|
|
|
@ -903,6 +903,7 @@ node_cleanup(struct ieee80211_node *ni)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void node_print_message(
|
static void node_print_message(
|
||||||
|
u_int32_t flags,
|
||||||
int show_counter,
|
int show_counter,
|
||||||
int refcnt_adjust,
|
int refcnt_adjust,
|
||||||
const struct ieee80211_node *ni,
|
const struct ieee80211_node *ni,
|
||||||
|
@ -918,7 +919,7 @@ static void node_print_message(
|
||||||
char node_count[32] = { '\0' };
|
char node_count[32] = { '\0' };
|
||||||
char expanded_message[1024] = { '\0' };
|
char expanded_message[1024] = { '\0' };
|
||||||
|
|
||||||
if (0 == (ni->ni_ic->ic_debug & IEEE80211_MSG_NODE_REF))
|
if (0 == (ni->ni_ic->ic_debug & flags) && (flags != IEEE80211_MSG_ANY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (adjusted_refcount == 0)
|
if (adjusted_refcount == 0)
|
||||||
|
@ -1080,7 +1081,8 @@ ieee80211_alloc_node(struct ieee80211vap *vap, const u_int8_t *macaddr)
|
||||||
ni->ni_vap = vap;
|
ni->ni_vap = vap;
|
||||||
ni->ni_ic = ic;
|
ni->ni_ic = ic;
|
||||||
atomic_inc(&ni->ni_ic->ic_node_counter);
|
atomic_inc(&ni->ni_ic->ic_node_counter);
|
||||||
node_print_message(1 /* show counter */,
|
node_print_message(IEEE80211_MSG_NODE|IEEE80211_MSG_NODE_REF,
|
||||||
|
1 /* show counter */,
|
||||||
0 /* adjust refcount */,
|
0 /* adjust refcount */,
|
||||||
ni,
|
ni,
|
||||||
#ifdef IEEE80211_DEBUG_REFCNT
|
#ifdef IEEE80211_DEBUG_REFCNT
|
||||||
|
@ -1629,7 +1631,8 @@ ieee80211_free_node(struct ieee80211_node *ni)
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
|
|
||||||
atomic_dec(&ni->ni_ic->ic_node_counter);
|
atomic_dec(&ni->ni_ic->ic_node_counter);
|
||||||
node_print_message(1 /* show counter */,
|
node_print_message(IEEE80211_MSG_NODE|IEEE80211_MSG_NODE_REF,
|
||||||
|
1 /* show counter */,
|
||||||
0 /* adjust refcount */,
|
0 /* adjust refcount */,
|
||||||
ni,
|
ni,
|
||||||
#ifdef IEEE80211_DEBUG_REFCNT
|
#ifdef IEEE80211_DEBUG_REFCNT
|
||||||
|
@ -2280,7 +2283,8 @@ ieee80211_ref_node(struct ieee80211_node *ni)
|
||||||
return ni;
|
return ni;
|
||||||
}
|
}
|
||||||
if (atomic_read(&ni->ni_refcnt) < 1) {
|
if (atomic_read(&ni->ni_refcnt) < 1) {
|
||||||
node_print_message(0 /* show counter */,
|
node_print_message(IEEE80211_MSG_ANY,
|
||||||
|
0 /* show counter */,
|
||||||
0 /* adjust refcount */,
|
0 /* adjust refcount */,
|
||||||
ni,
|
ni,
|
||||||
#ifdef IEEE80211_DEBUG_REFCNT
|
#ifdef IEEE80211_DEBUG_REFCNT
|
||||||
|
@ -2294,7 +2298,8 @@ ieee80211_ref_node(struct ieee80211_node *ni)
|
||||||
return ni;
|
return ni;
|
||||||
}
|
}
|
||||||
atomic_inc(&ni->ni_refcnt);
|
atomic_inc(&ni->ni_refcnt);
|
||||||
node_print_message(0 /* show counter */,
|
node_print_message(IEEE80211_MSG_NODE_REF,
|
||||||
|
0 /* show counter */,
|
||||||
0 /* adjust refcount */,
|
0 /* adjust refcount */,
|
||||||
ni,
|
ni,
|
||||||
#ifdef IEEE80211_DEBUG_REFCNT
|
#ifdef IEEE80211_DEBUG_REFCNT
|
||||||
|
@ -2330,7 +2335,8 @@ ieee80211_unref_node(struct ieee80211_node **pni)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (atomic_read(&ni->ni_refcnt) < 1) {
|
if (atomic_read(&ni->ni_refcnt) < 1) {
|
||||||
node_print_message(0 /* show counter */,
|
node_print_message(IEEE80211_MSG_ANY,
|
||||||
|
0 /* show counter */,
|
||||||
0 /* adjust refcount */,
|
0 /* adjust refcount */,
|
||||||
ni,
|
ni,
|
||||||
#ifdef IEEE80211_DEBUG_REFCNT
|
#ifdef IEEE80211_DEBUG_REFCNT
|
||||||
|
@ -2344,7 +2350,8 @@ ieee80211_unref_node(struct ieee80211_node **pni)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_print_message(0 /* show counter */,
|
node_print_message(IEEE80211_MSG_NODE_REF,
|
||||||
|
0 /* show counter */,
|
||||||
-1 /* adjust refcount */,
|
-1 /* adjust refcount */,
|
||||||
ni,
|
ni,
|
||||||
#ifdef IEEE80211_DEBUG_REFCNT
|
#ifdef IEEE80211_DEBUG_REFCNT
|
||||||
|
|
|
@ -195,11 +195,15 @@ ref_skb(struct sk_buff *skb,
|
||||||
static void skb_destructor(struct sk_buff* skb) {
|
static void skb_destructor(struct sk_buff* skb) {
|
||||||
/* Report any node reference leaks - caused by kernel net device queue
|
/* Report any node reference leaks - caused by kernel net device queue
|
||||||
* dropping buffer, rather than passing it to the driver. */
|
* dropping buffer, rather than passing it to the driver. */
|
||||||
if ((ath_debug_global & GLOBAL_DEBUG_SKB) && SKB_CB(skb)->ni != NULL) {
|
if (SKB_CB(skb)->ni != NULL) {
|
||||||
printk(KERN_ERR "%s:%d - ERROR: non-NULL node pointer in %p, %p<%s>! "
|
printk(KERN_ERR "%s:%d - ERROR: non-NULL node pointer in %p, %p<%s>! "
|
||||||
"Leak Detected!\n",
|
"Leak Detected!\n",
|
||||||
__func__, __LINE__,
|
__func__, __LINE__,
|
||||||
skb, SKB_CB(skb)->ni, ether_sprintf(SKB_CB(skb)->ni->ni_macaddr));
|
skb, SKB_CB(skb)->ni, ether_sprintf(SKB_CB(skb)->ni->ni_macaddr));
|
||||||
|
dump_stack();
|
||||||
|
}
|
||||||
|
if (SKB_CB(skb)->next_destructor != NULL) {
|
||||||
|
SKB_CB(skb)->next_destructor(skb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(skb_destructor);
|
EXPORT_SYMBOL(skb_destructor);
|
||||||
|
@ -232,7 +236,7 @@ static void print_skb_refchange_message(
|
||||||
const char* func2, int line2)
|
const char* func2, int line2)
|
||||||
{
|
{
|
||||||
char skb_desc[128] = { '\0' };
|
char skb_desc[128] = { '\0' };
|
||||||
if (0 == (ath_debug_global & GLOBAL_DEBUG_SKB))
|
if (0 == (ath_debug_global & GLOBAL_DEBUG_SKB_REF))
|
||||||
return;
|
return;
|
||||||
get_skb_description(skb_desc, sizeof(skb_desc),
|
get_skb_description(skb_desc, sizeof(skb_desc),
|
||||||
"skb", skb, users_adjustment);
|
"skb", skb, users_adjustment);
|
||||||
|
@ -293,8 +297,9 @@ track_skb(struct sk_buff *skb, int users_adjustment,
|
||||||
print_skb_trackchange_message(skb, users_adjustment,
|
print_skb_trackchange_message(skb, users_adjustment,
|
||||||
func1, line1, func2, line2,
|
func1, line1, func2, line2,
|
||||||
" is now ** TRACKED **");
|
" is now ** TRACKED **");
|
||||||
/* Always use our debug destructor, when we can... */
|
/* Install our debug destructor, chaining to the original... */
|
||||||
if (NULL == skb->destructor) {
|
if (skb->destructor != skb_destructor) {
|
||||||
|
SKB_CB(skb)->next_destructor = skb->destructor;
|
||||||
skb->destructor = skb_destructor;
|
skb->destructor = skb_destructor;
|
||||||
}
|
}
|
||||||
return skb;
|
return skb;
|
||||||
|
@ -327,6 +332,11 @@ untrack_skb(struct sk_buff *skb, int users_adjustment,
|
||||||
atomic_dec(&skb_total_counter);
|
atomic_dec(&skb_total_counter);
|
||||||
atomic_dec(&skb_refs_counter);
|
atomic_dec(&skb_refs_counter);
|
||||||
SKB_CB(skb)->tracked = 0;
|
SKB_CB(skb)->tracked = 0;
|
||||||
|
/* Install our debug destructor, chaining to the original... */
|
||||||
|
if (skb->destructor != skb_destructor) {
|
||||||
|
SKB_CB(skb)->next_destructor = skb->destructor;
|
||||||
|
skb->destructor = skb_destructor;
|
||||||
|
}
|
||||||
print_skb_trackchange_message(skb, users_adjustment,
|
print_skb_trackchange_message(skb, users_adjustment,
|
||||||
func1, line1, func2, line2,
|
func1, line1, func2, line2,
|
||||||
" is now ** UNTRACKED **");
|
" is now ** UNTRACKED **");
|
||||||
|
|
|
@ -89,7 +89,6 @@ static struct {
|
||||||
u_int bit;
|
u_int bit;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
} flags[] = {
|
} flags[] = {
|
||||||
{ "node_ref", IEEE80211_MSG_NODE_REF, "node ref counting (affects all devs)" },
|
|
||||||
{ "debug", IEEE80211_MSG_DEBUG, "IFF_DEBUG equivalent" },
|
{ "debug", IEEE80211_MSG_DEBUG, "IFF_DEBUG equivalent" },
|
||||||
{ "dumppkts", IEEE80211_MSG_DUMPPKTS, "dump packets" },
|
{ "dumppkts", IEEE80211_MSG_DUMPPKTS, "dump packets" },
|
||||||
{ "crypto", IEEE80211_MSG_CRYPTO, "crypto modules" },
|
{ "crypto", IEEE80211_MSG_CRYPTO, "crypto modules" },
|
||||||
|
@ -97,6 +96,7 @@ static struct {
|
||||||
{ "xrate", IEEE80211_MSG_XRATE, "rate set handling" },
|
{ "xrate", IEEE80211_MSG_XRATE, "rate set handling" },
|
||||||
{ "elemid", IEEE80211_MSG_ELEMID, "element id parsing"},
|
{ "elemid", IEEE80211_MSG_ELEMID, "element id parsing"},
|
||||||
{ "node", IEEE80211_MSG_NODE, "node management" },
|
{ "node", IEEE80211_MSG_NODE, "node management" },
|
||||||
|
{ "node_ref", IEEE80211_MSG_NODE_REF, "node ref counting (affects all devs)" },
|
||||||
{ "assoc", IEEE80211_MSG_ASSOC, "association handling" },
|
{ "assoc", IEEE80211_MSG_ASSOC, "association handling" },
|
||||||
{ "auth", IEEE80211_MSG_AUTH, "authentication handling" },
|
{ "auth", IEEE80211_MSG_AUTH, "authentication handling" },
|
||||||
{ "scan", IEEE80211_MSG_SCAN, "scanning" },
|
{ "scan", IEEE80211_MSG_SCAN, "scanning" },
|
||||||
|
|
|
@ -63,7 +63,7 @@ enum {
|
||||||
ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */
|
ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */
|
||||||
ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
||||||
ATH_DEBUG_RESET = 0x00000020, /* reset processing */
|
ATH_DEBUG_RESET = 0x00000020, /* reset processing */
|
||||||
ATH_DEBUG_MODE = 0x00000040, /* mode init/setup */
|
ATH_DEBUG_SKB_REF = 0x00000040, /* skb ref counting */
|
||||||
ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */
|
ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */
|
||||||
ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */
|
ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */
|
||||||
ATH_DEBUG_INTR = 0x00001000, /* ISR */
|
ATH_DEBUG_INTR = 0x00001000, /* ISR */
|
||||||
|
@ -73,7 +73,6 @@ enum {
|
||||||
ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */
|
ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */
|
||||||
ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */
|
ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */
|
||||||
ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
|
ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
|
||||||
ATH_DEBUG_NODE = 0x00080000, /* node management */
|
|
||||||
ATH_DEBUG_LED = 0x00100000, /* led management */
|
ATH_DEBUG_LED = 0x00100000, /* led management */
|
||||||
ATH_DEBUG_FF = 0x00200000, /* fast frames */
|
ATH_DEBUG_FF = 0x00200000, /* fast frames */
|
||||||
ATH_DEBUG_TURBO = 0x00400000, /* turbo/dynamic turbo */
|
ATH_DEBUG_TURBO = 0x00400000, /* turbo/dynamic turbo */
|
||||||
|
@ -100,7 +99,6 @@ static struct {
|
||||||
{ "recv_desc", ATH_DEBUG_RECV_DESC, "recv descriptors" },
|
{ "recv_desc", ATH_DEBUG_RECV_DESC, "recv descriptors" },
|
||||||
{ "rate", ATH_DEBUG_RATE, "rate control modules" },
|
{ "rate", ATH_DEBUG_RATE, "rate control modules" },
|
||||||
{ "reset", ATH_DEBUG_RESET, "reset processing and initialization" },
|
{ "reset", ATH_DEBUG_RESET, "reset processing and initialization" },
|
||||||
{ "mode", ATH_DEBUG_MODE, "mode initialization and changes" },
|
|
||||||
{ "beacon", ATH_DEBUG_BEACON, "beacon handling" },
|
{ "beacon", ATH_DEBUG_BEACON, "beacon handling" },
|
||||||
{ "watchdog", ATH_DEBUG_WATCHDOG, "watchdog timer" },
|
{ "watchdog", ATH_DEBUG_WATCHDOG, "watchdog timer" },
|
||||||
{ "intr", ATH_DEBUG_INTR, "interrupt processing" },
|
{ "intr", ATH_DEBUG_INTR, "interrupt processing" },
|
||||||
|
@ -110,9 +108,9 @@ static struct {
|
||||||
{ "calibrate", ATH_DEBUG_CALIBRATE, "periodic re-calibration" },
|
{ "calibrate", ATH_DEBUG_CALIBRATE, "periodic re-calibration" },
|
||||||
{ "keycache", ATH_DEBUG_KEYCACHE, "key cache management" },
|
{ "keycache", ATH_DEBUG_KEYCACHE, "key cache management" },
|
||||||
{ "state", ATH_DEBUG_STATE, "802.11 state transitions" },
|
{ "state", ATH_DEBUG_STATE, "802.11 state transitions" },
|
||||||
{ "node", ATH_DEBUG_NODE, "node management" },
|
|
||||||
{ "txbuf", ATH_DEBUG_TXBUF, "ath_buf management" },
|
{ "txbuf", ATH_DEBUG_TXBUF, "ath_buf management" },
|
||||||
{ "skb", ATH_DEBUG_SKB, "skb management (affects all devs)" },
|
{ "skb", ATH_DEBUG_SKB, "skb management (affects all devs)" },
|
||||||
|
{ "skb_ref", ATH_DEBUG_SKB_REF, "skb ref counting (affects all devs)" },
|
||||||
{ "led", ATH_DEBUG_LED, "led management" },
|
{ "led", ATH_DEBUG_LED, "led management" },
|
||||||
{ "ff", ATH_DEBUG_FF, "fast frame handling" },
|
{ "ff", ATH_DEBUG_FF, "fast frame handling" },
|
||||||
{ "turbo", ATH_DEBUG_TURBO, "dynamic turbo handling" },
|
{ "turbo", ATH_DEBUG_TURBO, "dynamic turbo handling" },
|
||||||
|
|
Loading…
Reference in New Issue