Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148855240
D6958.id17863.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D6958.id17863.diff
View Options
Index: sys/net80211/ieee80211_ddb.c
===================================================================
--- sys/net80211/ieee80211_ddb.c
+++ sys/net80211/ieee80211_ddb.c
@@ -506,6 +506,8 @@
db_printf("\tsoftc %p", ic->ic_softc);
db_printf("\tname %s", ic->ic_name);
db_printf(" comlock %p", &ic->ic_comlock);
+ db_printf(" txlock %p", &ic->ic_txlock);
+ db_printf(" fflock %p", &ic->ic_fflock);
db_printf("\n");
db_printf("\theadroom %d", ic->ic_headroom);
db_printf(" phytype %d", ic->ic_phytype);
Index: sys/net80211/ieee80211_freebsd.h
===================================================================
--- sys/net80211/ieee80211_freebsd.h
+++ sys/net80211/ieee80211_freebsd.h
@@ -83,6 +83,25 @@
mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED)
/*
+ * Stageq / ni_tx_superg lock
+ */
+typedef struct {
+ char name[16]; /* e.g. "ath0_ff_lock" */
+ struct mtx mtx;
+} ieee80211_ff_lock_t;
+#define IEEE80211_FF_LOCK_INIT(_ic, _name) do { \
+ ieee80211_ff_lock_t *fl = &(_ic)->ic_fflock; \
+ snprintf(fl->name, sizeof(fl->name), "%s_ff_lock", _name); \
+ mtx_init(&fl->mtx, fl->name, NULL, MTX_DEF); \
+} while (0)
+#define IEEE80211_FF_LOCK_OBJ(_ic) (&(_ic)->ic_fflock.mtx)
+#define IEEE80211_FF_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_FF_LOCK_OBJ(_ic))
+#define IEEE80211_FF_LOCK(_ic) mtx_lock(IEEE80211_FF_LOCK_OBJ(_ic))
+#define IEEE80211_FF_UNLOCK(_ic) mtx_unlock(IEEE80211_FF_LOCK_OBJ(_ic))
+#define IEEE80211_FF_LOCK_ASSERT(_ic) \
+ mtx_assert(IEEE80211_FF_LOCK_OBJ(_ic), MA_OWNED)
+
+/*
* Node locking definitions.
*/
typedef struct {
Index: sys/net80211/ieee80211_superg.h
===================================================================
--- sys/net80211/ieee80211_superg.h
+++ sys/net80211/ieee80211_superg.h
@@ -107,38 +107,32 @@
void ieee80211_ff_age(struct ieee80211com *, struct ieee80211_stageq *,
int quanta);
-/*
- * See ieee80211_ff_age() for a description of the locking
- * expectation here.
- */
static __inline void
-ieee80211_ff_flush(struct ieee80211com *ic, int ac)
+ieee80211_ff_age_all(struct ieee80211com *ic, int quanta)
{
struct ieee80211_superg *sg = ic->ic_superg;
- if (sg != NULL && sg->ff_stageq[ac].depth)
- ieee80211_ff_age(ic, &sg->ff_stageq[ac], 0x7fffffff);
+ if (sg != NULL) {
+ ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VO], quanta);
+ ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VI], quanta);
+ ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BE], quanta);
+ ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BK], quanta);
+ }
}
-/*
- * See ieee80211_ff_age() for a description of the locking
- * expectation here.
- */
static __inline void
-ieee80211_ff_age_all(struct ieee80211com *ic, int quanta)
+ieee80211_ff_flush(struct ieee80211com *ic, int ac)
{
struct ieee80211_superg *sg = ic->ic_superg;
- if (sg != NULL) {
- if (sg->ff_stageq[WME_AC_VO].depth)
- ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VO], quanta);
- if (sg->ff_stageq[WME_AC_VI].depth)
- ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VI], quanta);
- if (sg->ff_stageq[WME_AC_BE].depth)
- ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BE], quanta);
- if (sg->ff_stageq[WME_AC_BK].depth)
- ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BK], quanta);
- }
+ if (sg != NULL)
+ ieee80211_ff_age(ic, &sg->ff_stageq[ac], 0x7fffffff);
+}
+
+static __inline void
+ieee80211_ff_flush_all(struct ieee80211com *ic)
+{
+ ieee80211_ff_age_all(ic, 0x7fffffff);
}
struct mbuf *ieee80211_ff_encap(struct ieee80211vap *, struct mbuf *,
Index: sys/net80211/ieee80211_superg.c
===================================================================
--- sys/net80211/ieee80211_superg.c
+++ sys/net80211/ieee80211_superg.c
@@ -99,6 +99,8 @@
{
struct ieee80211_superg *sg;
+ IEEE80211_FF_LOCK_INIT(ic, ic->ic_name);
+
sg = (struct ieee80211_superg *) IEEE80211_MALLOC(
sizeof(struct ieee80211_superg), M_80211_VAP,
IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
@@ -120,6 +122,8 @@
void
ieee80211_superg_detach(struct ieee80211com *ic)
{
+ IEEE80211_FF_LOCK_DESTROY(ic);
+
if (ic->ic_superg != NULL) {
IEEE80211_FREE(ic->ic_superg, M_80211_VAP);
ic->ic_superg = NULL;
@@ -575,19 +579,14 @@
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- int error;
- IEEE80211_TX_LOCK_ASSERT(vap->iv_ic);
+ IEEE80211_TX_LOCK_ASSERT(ic);
/* encap and xmit */
m = ieee80211_encap(vap, ni, m);
- if (m != NULL) {
- struct ifnet *ifp = vap->iv_ifp;
-
- error = ieee80211_parent_xmitpkt(ic, m);
- if (!error)
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- } else
+ if (m != NULL)
+ (void) ieee80211_parent_xmitpkt(ic, m);
+ else
ieee80211_free_node(ni);
}
@@ -620,14 +619,6 @@
/*
* Age frames on the staging queue.
- *
- * This is called without the comlock held, but it does all its work
- * behind the comlock. Because of this, it's possible that the
- * staging queue will be serviced between the function which called
- * it and now; thus simply checking that the queue has work in it
- * may fail.
- *
- * See PR kern/174283 for more details.
*/
void
ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq,
@@ -636,11 +627,14 @@
struct mbuf *m, *head;
struct ieee80211_node *ni;
-#if 0
+ IEEE80211_FF_LOCK(ic);
+ if (sq->depth == 0) {
+ IEEE80211_FF_UNLOCK(ic);
+ return; /* nothing to do */
+ }
+
KASSERT(sq->head != NULL, ("stageq empty"));
-#endif
- IEEE80211_LOCK(ic);
head = sq->head;
while ((m = sq->head) != NULL && M_AGE_GET(m) < quanta) {
int tid = WME_AC_TO_TID(M_WME_GETAC(m));
@@ -657,7 +651,7 @@
sq->tail = NULL;
else
M_AGE_SUB(m, quanta);
- IEEE80211_UNLOCK(ic);
+ IEEE80211_FF_UNLOCK(ic);
IEEE80211_TX_LOCK(ic);
ff_flush(head, m);
@@ -669,7 +663,7 @@
{
int age = ieee80211_ffagemax;
- IEEE80211_LOCK_ASSERT(ic);
+ IEEE80211_FF_LOCK_ASSERT(ic);
if (sq->tail != NULL) {
sq->tail->m_nextpkt = m;
@@ -688,7 +682,7 @@
{
struct mbuf *m, *mprev;
- IEEE80211_LOCK_ASSERT(ic);
+ IEEE80211_FF_LOCK_ASSERT(ic);
mprev = NULL;
for (m = sq->head; m != NULL; m = m->m_nextpkt) {
@@ -767,6 +761,11 @@
IEEE80211_TX_UNLOCK_ASSERT(ic);
+ IEEE80211_LOCK(ic);
+ limit = IEEE80211_TXOP_TO_US(
+ ic->ic_wme.wme_chanParams.cap_wmeParams[pri].wmep_txopLimit);
+ IEEE80211_UNLOCK(ic);
+
/*
* Check if the supplied frame can be aggregated.
*
@@ -774,7 +773,7 @@
* Do 802.1x EAPOL frames proceed in the clear? Then they couldn't
* be aggregated with other types of frames when encryption is on?
*/
- IEEE80211_LOCK(ic);
+ IEEE80211_FF_LOCK(ic);
tap = &ni->ni_tx_ampdu[WME_AC_TO_TID(pri)];
mstaged = ni->ni_tx_superg[WME_AC_TO_TID(pri)];
/* XXX NOTE: reusing packet counter state from A-MPDU */
@@ -792,7 +791,7 @@
if (vap->iv_opmode != IEEE80211_M_STA &&
ETHER_IS_MULTICAST(mtod(m, struct ether_header *)->ether_dhost)) {
/* XXX flush staged frame? */
- IEEE80211_UNLOCK(ic);
+ IEEE80211_FF_UNLOCK(ic);
return m;
}
/*
@@ -801,15 +800,13 @@
*/
if (mstaged == NULL &&
ieee80211_txampdu_getpps(tap) < ieee80211_ffppsmin) {
- IEEE80211_UNLOCK(ic);
+ IEEE80211_FF_UNLOCK(ic);
return m;
}
sq = &sg->ff_stageq[pri];
/*
* Check the txop limit to insure the aggregate fits.
*/
- limit = IEEE80211_TXOP_TO_US(
- ic->ic_wme.wme_chanParams.cap_wmeParams[pri].wmep_txopLimit);
if (limit != 0 &&
(txtime = ff_approx_txtime(ni, m, mstaged)) > limit) {
/*
@@ -824,7 +821,7 @@
ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL;
if (mstaged != NULL)
stageq_remove(ic, sq, mstaged);
- IEEE80211_UNLOCK(ic);
+ IEEE80211_FF_UNLOCK(ic);
if (mstaged != NULL) {
IEEE80211_TX_LOCK(ic);
@@ -846,7 +843,7 @@
if (mstaged != NULL) {
ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL;
stageq_remove(ic, sq, mstaged);
- IEEE80211_UNLOCK(ic);
+ IEEE80211_FF_UNLOCK(ic);
IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni,
"%s: aggregate fast-frame", __func__);
@@ -862,13 +859,13 @@
mstaged->m_nextpkt = m;
mstaged->m_flags |= M_FF; /* NB: mark for encap work */
} else {
- KASSERT(ni->ni_tx_superg[WME_AC_TO_TID(pri)]== NULL,
+ KASSERT(ni->ni_tx_superg[WME_AC_TO_TID(pri)] == NULL,
("ni_tx_superg[]: %p",
ni->ni_tx_superg[WME_AC_TO_TID(pri)]));
ni->ni_tx_superg[WME_AC_TO_TID(pri)] = m;
stageq_add(ic, sq, m);
- IEEE80211_UNLOCK(ic);
+ IEEE80211_FF_UNLOCK(ic);
IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni,
"%s: stage frame, %u queued", __func__, sq->depth);
@@ -926,7 +923,7 @@
struct mbuf *m, *next_m, *head;
int tid;
- IEEE80211_LOCK(ic);
+ IEEE80211_FF_LOCK(ic);
head = NULL;
for (tid = 0; tid < WME_NUM_TID; tid++) {
int ac = TID_TO_WME_AC(tid);
@@ -945,7 +942,7 @@
head = m;
}
}
- IEEE80211_UNLOCK(ic);
+ IEEE80211_FF_UNLOCK(ic);
/*
* Free mbufs, taking care to not dereference the mbuf after
Index: sys/net80211/ieee80211_var.h
===================================================================
--- sys/net80211/ieee80211_var.h
+++ sys/net80211/ieee80211_var.h
@@ -121,6 +121,7 @@
const char *ic_name; /* usually device name */
ieee80211_com_lock_t ic_comlock; /* state update lock */
ieee80211_tx_lock_t ic_txlock; /* ic/vap TX lock */
+ ieee80211_ff_lock_t ic_fflock; /* stageq/ni_tx_superg lock */
LIST_ENTRY(ieee80211com) ic_next; /* on global list */
TAILQ_HEAD(, ieee80211vap) ic_vaps; /* list of vap instances */
int ic_headroom; /* driver tx headroom needs */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 21, 1:48 PM (7 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30078837
Default Alt Text
D6958.id17863.diff (9 KB)
Attached To
Mode
D6958: net80211: fix LOR in ieee80211_ff_node_cleanup()
Attached
Detach File
Event Timeline
Log In to Comment