PERFORCE change 134238 for review
Sam Leffler
sam at FreeBSD.org
Sun Jan 27 12:39:10 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=134238
Change 134238 by sam at sam_ebb on 2008/01/27 20:38:25
Reclaim old bss directly when re-joining a bss (or similar); the
old bss node has refcnt 2 (1 for the sta table and 1 for the old
ref in ivs_bss) but we were only free'ing the iv_bss reference.
We need to explicitly purge the sta table reference; do this with
a new ieee80211_node_reclaim routine.
Affected files ...
.. //depot/projects/vap/sys/net80211/ieee80211_node.c#23 edit
Differences ...
==== //depot/projects/vap/sys/net80211/ieee80211_node.c#23 (text+ko) ====
@@ -82,6 +82,7 @@
int inact, int keymaxix);
static void ieee80211_node_table_reset(struct ieee80211_node_table *,
struct ieee80211vap *);
+static void ieee80211_node_reclaim(struct ieee80211_node *);
static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt);
static void ieee80211_erp_timeout(struct ieee80211com *);
@@ -600,7 +601,8 @@
vap->iv_bss = selbs; /* NB: caller assumed to bump refcnt */
if (obss != NULL) {
copy_bss(selbs, obss);
- ieee80211_free_node(obss);
+ ieee80211_node_reclaim(obss);
+ obss = NULL; /* NB: guard against later use */
}
/*
@@ -1544,6 +1546,65 @@
}
/*
+ * Reclaim a (bss) node. Decrement the refcnt and reclaim
+ * the node if the only other reference to it is in the sta
+ * table. This is effectively ieee80211_free_node followed
+ * by node_reclaim when the refcnt is 1 (after the free).
+ */
+static void
+ieee80211_node_reclaim(struct ieee80211_node *ni)
+{
+ struct ieee80211_node_table *nt = ni->ni_table;
+
+ KASSERT(nt != NULL, ("reclaim node not in table"));
+
+#ifdef IEEE80211_DEBUG_REFCNT
+ IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
+ "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni,
+ ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)-1);
+#endif
+ IEEE80211_NODE_LOCK(nt);
+ if (ieee80211_node_dectestref(ni)) {
+ /*
+ * Last reference, reclaim state.
+ */
+ _ieee80211_free_node(ni);
+ nt = NULL;
+ } else if (ieee80211_node_refcnt(ni) == 1 &&
+ nt->nt_keyixmap != NULL) {
+ ieee80211_keyix keyix;
+ /*
+ * Check for a last reference in the key mapping table.
+ */
+ keyix = ni->ni_ucastkey.wk_rxkeyix;
+ if (keyix < nt->nt_keyixmax &&
+ nt->nt_keyixmap[keyix] == ni) {
+ IEEE80211_DPRINTF(ni->ni_vap,
+ 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);
+ nt = NULL;
+ }
+ }
+ if (nt != NULL && ieee80211_node_refcnt(ni) == 1) {
+ /*
+ * Last reference is in the sta table; complete
+ * the reclaim. This handles bss nodes being
+ * recycled: the node has two references, one for
+ * iv_bss and one for the table. After dropping
+ * the iv_bss ref above we need to reclaim the sta
+ * table reference.
+ */
+ ieee80211_node_decref(ni); /* NB: be pendantic */
+ _ieee80211_free_node(ni);
+ }
+ IEEE80211_NODE_UNLOCK(nt);
+}
+
+/*
* Node table support.
*/
More information about the p4-projects
mailing list