PERFORCE change 81314 for review

Sam Leffler sam at FreeBSD.org
Mon Aug 1 21:53:52 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=81314

Change 81314 by sam at 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) \


More information about the p4-projects mailing list