Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Dec 2004 20:13:41 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 66208 for review
Message-ID:  <200412012013.iB1KDfuF009410@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=66208

Change 66208 by sam@sam_ebb on 2004/12/01 20:13:14

	add a mutex around nt_scangen so we can reuse it when doing
	arbitary node table scans

Affected files ...

.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#8 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#20 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#13 edit

Differences ...

==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#8 (text+ko) ====

@@ -54,6 +54,18 @@
 	mtx_assert(&(_nt)->nt_nodelock, MA_OWNED)
 
 /*
+ * Node table scangen locking definitions.
+ */
+typedef struct mtx ieee80211_scan_lock_t;
+#define	IEEE80211_SCAN_LOCK_INIT(_nt, _name) \
+	mtx_init(&(_nt)->nt_scanlock, _name, "802.11 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)
+
+/*
  * Per-node power-save queue definitions. 
  */
 #define	IEEE80211_NODE_SAVEQ_INIT(_ni, _name) do {		\

==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#20 (text+ko) ====

@@ -1324,7 +1324,8 @@
 	struct ieee80211_node *ni;
 	u_int gen;
 
-	gen = nt->nt_scangen++;			/* NB: ok 'cuz single-threaded*/
+	IEEE80211_SCAN_LOCK(nt);
+	gen = nt->nt_scangen++;
 	IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
 		"%s: sta scangen %u\n", __func__, gen);
 restart:
@@ -1416,18 +1417,38 @@
 	}
 	IEEE80211_NODE_UNLOCK(nt);
 
+	IEEE80211_SCAN_UNLOCK(nt);
+
 	nt->nt_inact_timer = IEEE80211_INACT_WAIT;
 }
 
 void
 ieee80211_iterate_nodes(struct ieee80211_node_table *nt, ieee80211_iter_func *f, void *arg)
 {
-	struct ieee80211_node *ni, *tni;
+	struct ieee80211com *ic = nt->nt_ic;
+	struct ieee80211_node *ni;
+	u_int gen;
+
+	IEEE80211_SCAN_LOCK(nt);
+	gen = nt->nt_scangen++;
 
+	IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
+		"%s: sta scangen %u\n", __func__, gen);
+restart:
 	IEEE80211_NODE_LOCK(nt);
-	TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, tni)
-		(*f)(arg, ni);
+	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);
+			(*f)(arg, ni);
+			ieee80211_free_node(ni);
+			goto restart;
+		}
+	}
 	IEEE80211_NODE_UNLOCK(nt);
+
+	IEEE80211_SCAN_UNLOCK(nt);
 }
 
 void
@@ -1778,6 +1799,7 @@
 	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);
 	TAILQ_INIT(&nt->nt_node);
 	nt->nt_name = name;
 	nt->nt_scangen = 1;
@@ -1824,6 +1846,7 @@
 		"%s %s table\n", __func__, nt->nt_name);
 
 	ieee80211_free_allnodes_locked(nt);
+	IEEE80211_SCAN_LOCK_DESTROY(nt);
 	IEEE80211_NODE_LOCK_DESTROY(nt);
 }
 

==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#13 (text+ko) ====

@@ -206,6 +206,7 @@
 	TAILQ_HEAD(, ieee80211_node) nt_node;	/* information of all nodes */
 	LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE];
 	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_timer;	/* inactivity timer */
 	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?200412012013.iB1KDfuF009410>