aboutsummaryrefslogtreecommitdiff
path: root/sys/net80211/ieee80211_superg.h
diff options
context:
space:
mode:
authorAndriy Voskoboinyk <avos@FreeBSD.org>2016-06-29 17:25:46 +0000
committerAndriy Voskoboinyk <avos@FreeBSD.org>2016-06-29 17:25:46 +0000
commitcdc0cf21ebfc577ffb687dbbb11ba77cd8463adf (patch)
tree7edfcd8a5ab830fc811418da4c0893551af5d185 /sys/net80211/ieee80211_superg.h
parentd95fa042491e37c7cab6fd84fad209a160c6e8fa (diff)
downloadsrc-cdc0cf21ebfc577ffb687dbbb11ba77cd8463adf.tar.gz
src-cdc0cf21ebfc577ffb687dbbb11ba77cd8463adf.zip
net80211: fix LOR/deadlock in ieee80211_ff_node_cleanup().
Add new lock for stageq (part of ieee80211_superg structure) and ni_tx_superg (part of ieee80211_node structure); drop com_lock protection where it is used to protect them. While here, drop duplicate OPACKETS counter incrementation. ni_tx_ampdu is not protected with it (however, it is also used without locking in other places; probably, it requires some other solution to be thread-safe). Tested with RTL8188CUS (AP) and RTL8188EU (STA). NOTE: Since this change breaks KBI, all wireless drivers need to be recompiled. Reviewed by: adrian Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D6958
Notes
Notes: svn path=/head/; revision=302283
Diffstat (limited to 'sys/net80211/ieee80211_superg.h')
-rw-r--r--sys/net80211/ieee80211_superg.h38
1 files changed, 16 insertions, 22 deletions
diff --git a/sys/net80211/ieee80211_superg.h b/sys/net80211/ieee80211_superg.h
index ced3c9b68243..2f8628c314ae 100644
--- a/sys/net80211/ieee80211_superg.h
+++ b/sys/net80211/ieee80211_superg.h
@@ -107,38 +107,32 @@ struct mbuf *ieee80211_ff_check(struct ieee80211_node *, struct mbuf *);
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 *,