Page MenuHomeFreeBSD

D7996.diff
No OneTemporary

D7996.diff

Index: head/sys/net80211/ieee80211_node.h
===================================================================
--- head/sys/net80211/ieee80211_node.h
+++ head/sys/net80211/ieee80211_node.h
@@ -359,6 +359,7 @@
ieee80211_node_lock_t nt_nodelock; /* on node table */
TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */
LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE];
+ int nt_count; /* number of nodes */
struct ieee80211_node **nt_keyixmap; /* key ix -> node map */
int nt_keyixmax; /* keyixmap size */
const char *nt_name; /* table name for debug msgs */
@@ -444,8 +445,8 @@
void ieee80211_node_timeout(void *arg);
typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
-int ieee80211_iterate_nt(struct ieee80211_node_table *,
- struct ieee80211_node **, uint16_t);
+int ieee80211_iterate_nodes_vap(struct ieee80211_node_table *,
+ struct ieee80211vap *, ieee80211_iter_func *, void *);
void ieee80211_iterate_nodes(struct ieee80211_node_table *,
ieee80211_iter_func *, void *);
Index: head/sys/net80211/ieee80211_node.c
===================================================================
--- head/sys/net80211/ieee80211_node.c
+++ head/sys/net80211/ieee80211_node.c
@@ -1214,13 +1214,44 @@
/* XXX EVM? */
}
+static void
+ieee80211_add_node_nt(struct ieee80211_node_table *nt,
+ struct ieee80211_node *ni)
+{
+ struct ieee80211com *ic = nt->nt_ic;
+ int hash;
+
+ IEEE80211_NODE_LOCK_ASSERT(nt);
+
+ hash = IEEE80211_NODE_HASH(ic, ni->ni_macaddr);
+ (void) ic; /* XXX IEEE80211_NODE_HASH */
+ TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);
+ LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);
+ nt->nt_count++;
+ ni->ni_table = nt;
+}
+
+static void
+ieee80211_del_node_nt(struct ieee80211_node_table *nt,
+ struct ieee80211_node *ni)
+{
+
+ IEEE80211_NODE_LOCK_ASSERT(nt);
+
+ TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
+ LIST_REMOVE(ni, ni_hash);
+ nt->nt_count--;
+ KASSERT(nt->nt_count >= 0,
+ ("nt_count is negative (%d)!\n", nt->nt_count));
+ ni->ni_table = NULL;
+}
+
struct ieee80211_node *
ieee80211_alloc_node(struct ieee80211_node_table *nt,
struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
struct ieee80211com *ic = nt->nt_ic;
struct ieee80211_node *ni;
- int hash;
ni = ic->ic_node_alloc(vap, macaddr);
if (ni == NULL) {
@@ -1233,7 +1264,6 @@
ether_sprintf(macaddr), nt->nt_name);
IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
- hash = IEEE80211_NODE_HASH(ic, macaddr);
ieee80211_node_initref(ni); /* mark referenced */
ni->ni_chan = IEEE80211_CHAN_ANYC;
ni->ni_authmode = IEEE80211_AUTH_OPEN;
@@ -1250,9 +1280,7 @@
ieee80211_mesh_node_init(vap, ni);
#endif
IEEE80211_NODE_LOCK(nt);
- TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);
- LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);
- ni->ni_table = nt;
+ ieee80211_add_node_nt(nt, ni);
ni->ni_vap = vap;
ni->ni_ic = ic;
IEEE80211_NODE_UNLOCK(nt);
@@ -1815,10 +1843,8 @@
if (vap->iv_aid_bitmap != NULL)
IEEE80211_AID_CLR(vap, ni->ni_associd);
}
- if (nt != NULL) {
- TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
- LIST_REMOVE(ni, ni_hash);
- }
+ if (nt != NULL)
+ ieee80211_del_node_nt(nt, ni);
ni->ni_ic->ic_node_free(ni);
}
@@ -1957,9 +1983,7 @@
* the references are dropped storage will be
* reclaimed.
*/
- TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
- LIST_REMOVE(ni, ni_hash);
- ni->ni_table = NULL; /* clear reference */
+ ieee80211_del_node_nt(nt, ni);
} else
_ieee80211_free_node(ni);
}
@@ -1977,6 +2001,7 @@
nt->nt_ic = ic;
IEEE80211_NODE_LOCK_INIT(nt, ic->ic_name);
TAILQ_INIT(&nt->nt_node);
+ nt->nt_count = 0;
nt->nt_name = name;
nt->nt_inact_init = inact;
nt->nt_keyixmax = keyixmax;
@@ -2261,117 +2286,68 @@
}
/*
- * Iterate over the node table and return an array of ref'ed nodes.
- *
- * This is separated out from calling the actual node function so that
- * no LORs will occur.
- *
- * If there are too many nodes (ie, the number of nodes doesn't fit
- * within 'max_aid' entries) then the node references will be freed
- * and an error will be returned.
- *
- * The responsibility of allocating and freeing "ni_arr" is up to
- * the caller.
+ * The same as ieee80211_iterate_nodes(), but for one vap only.
*/
int
-ieee80211_iterate_nt(struct ieee80211_node_table *nt,
- struct ieee80211_node **ni_arr, uint16_t max_aid)
+ieee80211_iterate_nodes_vap(struct ieee80211_node_table *nt,
+ struct ieee80211vap *vap, ieee80211_iter_func *f, void *arg)
{
- int i, j, ret;
+ struct ieee80211_node **ni_arr;
struct ieee80211_node *ni;
+ size_t size;
+ int count, i;
+ /*
+ * Iterate over the node table and save an array of ref'ed nodes.
+ *
+ * This is separated out from calling the actual node function so that
+ * no LORs will occur.
+ */
IEEE80211_NODE_LOCK(nt);
+ count = nt->nt_count;
+ size = count * sizeof(struct ieee80211_node *);
+ ni_arr = (struct ieee80211_node **) IEEE80211_MALLOC(size, M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
+ if (ni_arr == NULL) {
+ IEEE80211_NODE_UNLOCK(nt);
+ return (ENOMEM);
+ }
- i = ret = 0;
+ i = 0;
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
- if (i >= max_aid) {
- ret = E2BIG;
- ic_printf(nt->nt_ic, "Node array overflow: max=%u",
- max_aid);
- break;
- }
+ if (vap != NULL && ni->ni_vap != vap)
+ continue;
+ KASSERT(i < count,
+ ("node array overflow (vap %p, i %d, count %d)\n",
+ vap, i, count));
ni_arr[i] = ieee80211_ref_node(ni);
i++;
}
-
- /*
- * It's safe to unlock here.
- *
- * If we're successful, the list is returned.
- * If we're unsuccessful, the list is ignored
- * and we remove our references.
- *
- * This avoids any potential LOR with
- * ieee80211_free_node().
- */
IEEE80211_NODE_UNLOCK(nt);
- /*
- * If ret is non-zero, we hit some kind of error.
- * Rather than walking some nodes, we'll walk none
- * of them.
- */
- if (ret) {
- for (j = 0; j < i; j++) {
- /* ieee80211_free_node() locks by itself */
- ieee80211_free_node(ni_arr[j]);
- }
+ for (i = 0; i < count; i++) {
+ if (ni_arr[i] == NULL) /* end of the list */
+ break;
+ (*f)(arg, ni_arr[i]);
+ /* ieee80211_free_node() locks by itself */
+ ieee80211_free_node(ni_arr[i]);
}
- return (ret);
+ IEEE80211_FREE(ni_arr, M_80211_NODE);
+
+ return (0);
}
/*
* Just a wrapper, so we don't have to change every ieee80211_iterate_nodes()
* reference in the source.
- *
- * Note that this fetches 'max_aid' from the first VAP, rather than finding
- * the largest max_aid from all VAPs.
*/
void
ieee80211_iterate_nodes(struct ieee80211_node_table *nt,
ieee80211_iter_func *f, void *arg)
{
- struct ieee80211_node **ni_arr;
- size_t size;
- int i;
- uint16_t max_aid;
- struct ieee80211vap *vap;
-
- /* Overdoing it default */
- max_aid = IEEE80211_AID_MAX;
-
- /* Handle the case of there being no vaps just yet */
- vap = TAILQ_FIRST(&nt->nt_ic->ic_vaps);
- if (vap != NULL)
- max_aid = vap->iv_max_aid;
-
- size = max_aid * sizeof(struct ieee80211_node *);
- ni_arr = (struct ieee80211_node **) IEEE80211_MALLOC(size, M_80211_NODE,
- IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
- if (ni_arr == NULL)
- return;
-
- /*
- * If this fails, the node table won't have any
- * valid entries - ieee80211_iterate_nt() frees
- * the references to them. So don't try walking
- * the table; just skip to the end and free the
- * temporary memory.
- */
- if (ieee80211_iterate_nt(nt, ni_arr, max_aid) != 0)
- goto done;
-
- for (i = 0; i < max_aid; i++) {
- if (ni_arr[i] == NULL) /* end of the list */
- break;
- (*f)(arg, ni_arr[i]);
- /* ieee80211_free_node() locks by itself */
- ieee80211_free_node(ni_arr[i]);
- }
-
-done:
- IEEE80211_FREE(ni_arr, M_80211_NODE);
+ /* XXX no way to pass error to the caller. */
+ (void) ieee80211_iterate_nodes_vap(nt, NULL, f, arg);
}
void

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 27, 12:30 AM (12 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15609491
Default Alt Text
D7996.diff (7 KB)

Event Timeline