Date: Mon, 7 Apr 2008 16:39:05 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 139523 for review Message-ID: <200804071639.m37Gd5FT055630@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=139523 Change 139523 by sam@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 */ };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804071639.m37Gd5FT055630>