diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2012-07-16 14:51:47 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2012-07-16 14:51:47 +0000 |
commit | 6fece20efd9454a02d165d45cc4207a003e7465a (patch) | |
tree | 1b40cc48421f55fedd12956d3d4570f270a949f6 /sys/net80211 | |
parent | 55f7f71177514bb7e1460945961f21c3c23cceb9 (diff) |
Move increment of ic_nnodes closer to where the node is actually inserted
into the cache. Make sure we're at IPL_NET while incrementing/decrementing
ic_nnodes. Add a debug message that warns about possible node leaks.
All of this affects hostap mode only.
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211_node.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 38cfba37939..21639714169 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.c,v 1.69 2012/07/13 09:46:33 stsp Exp $ */ +/* $OpenBSD: ieee80211_node.c,v 1.70 2012/07/16 14:51:46 stsp Exp $ */ /* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */ /*- @@ -189,8 +189,6 @@ ieee80211_alloc_node_helper(struct ieee80211com *ic) if (ic->ic_nnodes >= ic->ic_max_nnodes) return NULL; ni = (*ic->ic_node_alloc)(ic); - if (ni != NULL) - ic->ic_nnodes++; return ni; } @@ -815,6 +813,7 @@ ieee80211_setup_node(struct ieee80211com *ic, #endif s = splnet(); RB_INSERT(ieee80211_tree, &ic->ic_tree, ni); + ic->ic_nnodes++; splx(s); } @@ -1081,6 +1080,8 @@ ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni) if (ni == ic->ic_bss) panic("freeing bss node"); + splassert(IPL_NET); + DPRINTF(("%s\n", ether_sprintf(ni->ni_macaddr))); #ifndef IEEE80211_STA_ONLY timeout_del(&ni->ni_eapol_to); @@ -1150,6 +1151,10 @@ ieee80211_clean_nodes(struct ieee80211com *ic, int cache_timeout) struct ieee80211_node *ni, *next_ni; u_int gen = ic->ic_scangen++; /* NB: ok 'cuz single-threaded*/ int s; +#ifndef IEEE80211_STA_ONLY + int nnodes = 0; + struct ifnet *ifp = &ic->ic_if; +#endif s = splnet(); for (ni = RB_MIN(ieee80211_tree, &ic->ic_tree); @@ -1159,6 +1164,9 @@ ieee80211_clean_nodes(struct ieee80211com *ic, int cache_timeout) break; if (ni->ni_scangen == gen) /* previously handled */ continue; +#ifndef IEEE80211_STA_ONLY + nnodes++; +#endif ni->ni_scangen = gen; if (ni->ni_refcnt > 0) continue; @@ -1195,6 +1203,7 @@ ieee80211_clean_nodes(struct ieee80211com *ic, int cache_timeout) * the driver calls ieee80211_release_node(). */ #ifndef IEEE80211_STA_ONLY + nnodes--; if (ic->ic_opmode == IEEE80211_M_HOSTAP && ni->ni_state >= IEEE80211_STA_AUTH && ni->ni_state != IEEE80211_STA_COLLECT) { @@ -1209,6 +1218,20 @@ ieee80211_clean_nodes(struct ieee80211com *ic, int cache_timeout) ieee80211_free_node(ic, ni); ic->ic_stats.is_node_timeout++; } + +#ifndef IEEE80211_STA_ONLY + /* + * During a cache timeout we iterate over all nodes. + * Check for node leaks by comparing the actual number of cached + * nodes with the ic_nnodes count, which is maintained while adding + * and removing nodes from the cache. + */ + if ((ifp->if_flags & IFF_DEBUG) && cache_timeout && + nnodes != ic->ic_nnodes) + printf("%s: number of cached nodes is %d, expected %d," + "possible nodes leak\n", ifp->if_xname, nnodes, + ic->ic_nnodes); +#endif splx(s); } |