PERFORCE change 139523 for review
Sam Leffler
sam at FreeBSD.org
Mon Apr 7 16:39:07 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=139523
Change 139523 by sam at sam_ebb on 2008/04/07 16:38:42
switch the node table lock from a mtx to a rwlock; this allows
us to eliminate the scan lock and will permit conversion of some
fast path operations to a shared lock acquisition; in the process
rename "SCAN_LOCK" to "NODE_ITERATE_LOCK" to make it more clear
we're sharing the same lock
Affected files ...
.. //depot/projects/vap/sys/net80211/ieee80211_freebsd.h#23 edit
.. //depot/projects/vap/sys/net80211/ieee80211_node.c#28 edit
.. //depot/projects/vap/sys/net80211/ieee80211_node.h#18 edit
Differences ...
==== //depot/projects/vap/sys/net80211/ieee80211_freebsd.h#23 (text+ko) ====
@@ -28,6 +28,11 @@
#define _NET80211_IEEE80211_FREEBSD_H_
#ifdef _KERNEL
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+
/*
* Common state locking definitions.
*/
@@ -44,28 +49,22 @@
/*
* Node locking definitions.
*/
-typedef struct mtx ieee80211_node_lock_t;
+typedef struct rwlock ieee80211_node_lock_t;
#define IEEE80211_NODE_LOCK_INIT(_nt, _name) \
- mtx_init(&(_nt)->nt_nodelock, _name, "802.11 node table", \
- MTX_DEF | MTX_RECURSE)
-#define IEEE80211_NODE_LOCK_DESTROY(_nt) mtx_destroy(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_LOCK(_nt) mtx_lock(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_IS_LOCKED(_nt) mtx_owned(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_UNLOCK(_nt) mtx_unlock(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_LOCK_ASSERT(_nt) \
- mtx_assert(&(_nt)->nt_nodelock, MA_OWNED)
+ rw_init_flags(&(_nt)->nt_nodelock, _name, RW_RECURSE)
+#define IEEE80211_NODE_LOCK_DESTROY(_nt) rw_destroy(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK(_nt) rw_wlock(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_IS_LOCKED(_nt) rw_wowned(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_UNLOCK(_nt) rw_wunlock(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_ASSERT(_nt) \
+ rw_assert(&(_nt)->nt_nodelock, RA_WLOCKED)
/*
- * Node table scangen locking definitions.
+ * Node table iteration locking definitions; we piggyback on the node
+ * table lock by using a read/shared acquisition.
*/
-typedef struct mtx ieee80211_scan_lock_t;
-#define IEEE80211_SCAN_LOCK_INIT(_nt, _name) \
- mtx_init(&(_nt)->nt_scanlock, _name, "802.11 node scangen", MTX_DEF)
-#define IEEE80211_SCAN_LOCK_DESTROY(_nt) mtx_destroy(&(_nt)->nt_scanlock)
-#define IEEE80211_SCAN_LOCK(_nt) mtx_lock(&(_nt)->nt_scanlock)
-#define IEEE80211_SCAN_UNLOCK(_nt) mtx_unlock(&(_nt)->nt_scanlock)
-#define IEEE80211_SCAN_LOCK_ASSERT(_nt) \
- mtx_assert(&(_nt)->nt_scanlock, MA_OWNED)
+#define IEEE80211_NODE_ITERATE_LOCK(_nt) rw_rlock(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_ITERATE_UNLOCK(_nt) rw_runlock(&(_nt)->nt_nodelock)
#define _AGEQ_ENQUEUE(_ifq, _m, _qlen, _age) do { \
(_m)->m_nextpkt = NULL; \
==== //depot/projects/vap/sys/net80211/ieee80211_node.c#28 (text+ko) ====
@@ -1699,9 +1699,9 @@
const char *name, int inact, int keyixmax)
{
nt->nt_ic = ic;
- /* XXX need unit */
- IEEE80211_NODE_LOCK_INIT(nt, ic->ic_ifp->if_xname);
- IEEE80211_SCAN_LOCK_INIT(nt, ic->ic_ifp->if_xname);
+ snprintf(nt->nt_lockname, sizeof(nt->nt_lockname), "%s_node_lock",
+ ic->ic_ifp->if_xname);
+ IEEE80211_NODE_LOCK_INIT(nt, nt->nt_lockname);
TAILQ_INIT(&nt->nt_node);
nt->nt_name = name;
nt->nt_scangen = 1;
@@ -1772,7 +1772,6 @@
FREE(nt->nt_keyixmap, M_80211_NODE);
nt->nt_keyixmap = NULL;
}
- IEEE80211_SCAN_LOCK_DESTROY(nt);
IEEE80211_NODE_LOCK_DESTROY(nt);
}
@@ -1792,12 +1791,15 @@
struct ieee80211_node_table *nt = &ic->ic_sta;
struct ieee80211vap *vap;
struct ieee80211_node *ni;
- u_int gen;
+ int gen = 0;
- IEEE80211_SCAN_LOCK(nt);
- gen = ++nt->nt_scangen;
restart:
IEEE80211_NODE_LOCK(nt);
+ if (gen == 0) {
+ gen = ++nt->nt_scangen;
+ if (nt->nt_scangen == 0) /* NB: 0 is never used */
+ nt->nt_scangen++;
+ }
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if (ni->ni_scangen == gen) /* previously handled */
continue;
@@ -1918,8 +1920,6 @@
}
}
IEEE80211_NODE_UNLOCK(nt);
-
- IEEE80211_SCAN_UNLOCK(nt);
}
/*
@@ -2006,25 +2006,26 @@
ieee80211_iterate_nodes(struct ieee80211_node_table *nt, ieee80211_iter_func *f, void *arg)
{
struct ieee80211_node *ni;
- u_int gen;
+ u_int gen = 0;
- IEEE80211_SCAN_LOCK(nt);
- gen = ++nt->nt_scangen;
restart:
- IEEE80211_NODE_LOCK(nt);
+ IEEE80211_NODE_ITERATE_LOCK(nt);
+ if (gen == 0) {
+ gen = ++nt->nt_scangen;
+ if (nt->nt_scangen == 0) /* NB: 0 is never used */
+ nt->nt_scangen++;
+ }
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if (ni->ni_scangen != gen) {
ni->ni_scangen = gen;
(void) ieee80211_ref_node(ni);
- IEEE80211_NODE_UNLOCK(nt);
+ IEEE80211_NODE_ITERATE_UNLOCK(nt);
(*f)(arg, ni);
ieee80211_free_node(ni);
goto restart;
}
}
- IEEE80211_NODE_UNLOCK(nt);
-
- IEEE80211_SCAN_UNLOCK(nt);
+ IEEE80211_NODE_ITERATE_UNLOCK(nt);
}
void
==== //depot/projects/vap/sys/net80211/ieee80211_node.h#18 (text+ko) ====
@@ -295,13 +295,13 @@
*/
struct ieee80211_node_table {
struct ieee80211com *nt_ic; /* back reference */
+ char nt_lockname[16];/* e.g. "ath0_node_lock" */
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];
struct ieee80211_node **nt_keyixmap; /* key ix -> node map */
int nt_keyixmax; /* keyixmap size */
const char *nt_name; /* for debugging */
- ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */
u_int nt_scangen; /* gen# for timeout scan */
int nt_inact_init; /* initial node inact setting */
};
More information about the p4-projects
mailing list