Date: Mon, 1 Aug 2005 21:53:50 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 81314 for review Message-ID: <200508012153.j71LroWW029522@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=81314 Change 81314 by sam@sam_ebb on 2005/08/01 21:53:50 Fix problems with key map table handling: o correct braino in ieee80211_free_node (premature node reclaim) o special case ieee80211_free_node handling when the last reference is in the key map; otherwise we orphan nodes until someone resets state o bandaid ieee80211_node_delkey locking; can be called w/ and w/o the node table lock held (still need to fix LOR too) o fix refcnt debug code o add some debug msgs While here make ieee80211_node_table_reset static; no longer needs to be public with new scan code. Also remove extraneous ieee80211_reset_erp call in clearing the node table (didn't belong here anyway). Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_node.c#58 edit .. //depot/projects/wifi/sys/net80211/ieee80211_node.h#28 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#58 (text+ko) ==== @@ -72,6 +72,7 @@ static void ieee80211_node_table_init(struct ieee80211com *ic, struct ieee80211_node_table *nt, const char *name, int inact); +static void ieee80211_node_table_reset(struct ieee80211_node_table *); static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt); MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state"); @@ -943,7 +944,7 @@ struct ieee80211_node * #ifdef IEEE80211_DEBUG_REFCNT ieee80211_find_rxnode_withkey_debug(struct ieee80211com *ic, - const struct ieee80211_frame_min *wh, , u_int16_t keyix, + const struct ieee80211_frame_min *wh, u_int16_t keyix, const char *func, int line) #else ieee80211_find_rxnode_withkey(struct ieee80211com *ic, @@ -974,8 +975,13 @@ ("keyix %u out of bounds (2)", keyix)); /* XXX can keyixmap[keyix] != NULL? */ if (keyix != IEEE80211_KEYIX_NONE && - nt->nt_keyixmap[keyix] == NULL) + nt->nt_keyixmap[keyix] == NULL) { + IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, + "%s: add key map entry %p<%s> refcnt %d\n", + __func__, ni, ether_sprintf(ni->ni_macaddr), + ieee80211_node_refcnt(ni)+1); nt->nt_keyixmap[keyix] = ieee80211_ref_node(ni); + } } else ieee80211_ref_node(ni); IEEE80211_NODE_UNLOCK(nt); @@ -1125,11 +1131,31 @@ #endif if (nt != NULL) { IEEE80211_NODE_LOCK(nt); - if (ieee80211_node_dectestref(ni)) + if (ieee80211_node_dectestref(ni)) { + /* + * Last reference, reclaim state. + */ _ieee80211_free_node(ni); + } else if (ieee80211_node_refcnt(ni) == 1) { + u_int16_t keyix; + /* + * Check for a last reference in the key mapping table. + */ + keyix = ni->ni_ucastkey.wk_keyix; + if (keyix != IEEE80211_KEYIX_NONE && + nt->nt_keyixmap[keyix] == ni) { + IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, + "%s: %p<%s> clear key map entry", __func__, + ni, ether_sprintf(ni->ni_macaddr)); + nt->nt_keyixmap[keyix] = NULL; + ieee80211_node_decref(ni); /* XXX needed? */ + _ieee80211_free_node(ni); + } + } IEEE80211_NODE_UNLOCK(nt); } else { - _ieee80211_free_node(ni); + if (ieee80211_node_dectestref(ni)) + _ieee80211_free_node(ni); } } @@ -1141,14 +1167,23 @@ ieee80211_node_delkey(struct ieee80211_node_table *nt, u_int16_t keyix) { struct ieee80211_node *ni; + int isowned = mtx_owned(&nt->nt_nodelock); - IEEE80211_NODE_LOCK(nt); + /* XXX can be entered w/ or w/o lock */ + if (!isowned) + IEEE80211_NODE_LOCK(nt); ni = nt->nt_keyixmap[keyix]; nt->nt_keyixmap[keyix] = NULL;; - IEEE80211_NODE_UNLOCK(nt); + if (!isowned) + IEEE80211_NODE_UNLOCK(nt); - if (ni != NULL) + if (ni != NULL) { + IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, + "%s: delete key map entry %p<%s> refcnt %d\n", + __func__, ni, ether_sprintf(ni->ni_macaddr), + ieee80211_node_refcnt(ni)-1); ieee80211_free_node(ni); + } } /* @@ -1176,6 +1211,9 @@ */ keyix = ni->ni_ucastkey.wk_keyix; if (keyix != IEEE80211_KEYIX_NONE && nt->nt_keyixmap[keyix] == ni) { + IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, + "%s: %p<%s> clear key map entry\n", + __func__, ni, ether_sprintf(ni->ni_macaddr)); nt->nt_keyixmap[keyix] = NULL; ieee80211_node_decref(ni); } @@ -1210,7 +1248,6 @@ } node_reclaim(nt, ni); } - ieee80211_reset_erp(ic); } /* @@ -1716,7 +1753,7 @@ nt->nt_inact_init = inact; } -void +static void ieee80211_node_table_reset(struct ieee80211_node_table *nt) { ==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#28 (text+ko) ==== @@ -216,7 +216,6 @@ u_int nt_scangen; /* gen# for timeout scan */ int nt_inact_init; /* initial node inact setting */ }; -void ieee80211_node_table_reset(struct ieee80211_node_table *); struct ieee80211_node *ieee80211_alloc_node( struct ieee80211_node_table *, const u_int8_t *); @@ -231,6 +230,10 @@ struct ieee80211_node * ieee80211_find_rxnode_debug(struct ieee80211com *, const struct ieee80211_frame_min *, const char *func, int line); +struct ieee80211_node * ieee80211_find_rxnode_withkey_debug( + struct ieee80211com *, + const struct ieee80211_frame_min *, u_int16_t keyix, + const char *func, int line); struct ieee80211_node *ieee80211_find_txnode_debug(struct ieee80211com *, const u_int8_t *, const char *func, int line); @@ -244,6 +247,8 @@ ieee80211_find_node_debug(nt, mac, __func__, __LINE__) #define ieee80211_find_rxnode(nt, wh) \ ieee80211_find_rxnode_debug(nt, wh, __func__, __LINE__) +#define ieee80211_find_rxnode_withkey(nt, wh, keyix) \ + ieee80211_find_rxnode_withkey_debug(nt, wh, keyix, __func__, __LINE__) #define ieee80211_find_txnode(nt, mac) \ ieee80211_find_txnode_debug(nt, mac, __func__, __LINE__) #define ieee80211_find_node_with_ssid(nt, mac, sl, ss) \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508012153.j71LroWW029522>