mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-12 09:58:36 +00:00
Atheros SuperG bug fixes, as part of hunting down kern/174283.
The stageqdepth (global, over all staging queues) was being kept incorrectly. It was being incremented whenever things were added, but only decremented during a flush. During active fast frames activity it wasn't being decremented, resulting in it always having a non-zero value during normal fast-frames operation. It was only used when checking if the aging queue should be checked; we may as well just defer to each of those staging queue counters (which look correct, thankfully.) Whilst I'm here, add locking assertions in the staging queue add/remove functions. The current crash shows that the staging queue has one frame, but only has a tail pointer set (the head pointer being set to NULL.) I'd like to grab a few more crashes where these locking assertions are in place so I can narrow down the issue between "somehow locking is messed up and things are racy" and "the stage queue head/tail pointer manipulation logic is subtly wrong." Tested: * AR5416 STA, AR5413 AP; with FastFrames enabled in the AR5416 HAL. PR: kern/174283
This commit is contained in:
parent
7a50e936c0
commit
b3c69eef25
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=244051
@ -560,7 +560,6 @@ void
|
||||
ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq,
|
||||
int quanta)
|
||||
{
|
||||
struct ieee80211_superg *sg = ic->ic_superg;
|
||||
struct mbuf *m, *head;
|
||||
struct ieee80211_node *ni;
|
||||
struct ieee80211_tx_ampdu *tap;
|
||||
@ -582,7 +581,6 @@ ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq,
|
||||
|
||||
sq->head = m->m_nextpkt;
|
||||
sq->depth--;
|
||||
sg->ff_stageqdepth--;
|
||||
}
|
||||
if (m == NULL)
|
||||
sq->tail = NULL;
|
||||
@ -594,9 +592,12 @@ ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq,
|
||||
}
|
||||
|
||||
static void
|
||||
stageq_add(struct ieee80211_stageq *sq, struct mbuf *m)
|
||||
stageq_add(struct ieee80211com *ic, struct ieee80211_stageq *sq, struct mbuf *m)
|
||||
{
|
||||
int age = ieee80211_ffagemax;
|
||||
|
||||
IEEE80211_LOCK_ASSERT(ic);
|
||||
|
||||
if (sq->tail != NULL) {
|
||||
sq->tail->m_nextpkt = m;
|
||||
age -= M_AGE_GET(sq->head);
|
||||
@ -610,10 +611,12 @@ stageq_add(struct ieee80211_stageq *sq, struct mbuf *m)
|
||||
}
|
||||
|
||||
static void
|
||||
stageq_remove(struct ieee80211_stageq *sq, struct mbuf *mstaged)
|
||||
stageq_remove(struct ieee80211com *ic, struct ieee80211_stageq *sq, struct mbuf *mstaged)
|
||||
{
|
||||
struct mbuf *m, *mprev;
|
||||
|
||||
IEEE80211_LOCK_ASSERT(ic);
|
||||
|
||||
mprev = NULL;
|
||||
for (m = sq->head; m != NULL; m = m->m_nextpkt) {
|
||||
if (m == mstaged) {
|
||||
@ -725,7 +728,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m)
|
||||
|
||||
tap->txa_private = NULL;
|
||||
if (mstaged != NULL)
|
||||
stageq_remove(sq, mstaged);
|
||||
stageq_remove(ic, sq, mstaged);
|
||||
IEEE80211_UNLOCK(ic);
|
||||
|
||||
if (mstaged != NULL) {
|
||||
@ -745,7 +748,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m)
|
||||
*/
|
||||
if (mstaged != NULL) {
|
||||
tap->txa_private = NULL;
|
||||
stageq_remove(sq, mstaged);
|
||||
stageq_remove(ic, sq, mstaged);
|
||||
IEEE80211_UNLOCK(ic);
|
||||
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni,
|
||||
@ -766,8 +769,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m)
|
||||
("txa_private %p", tap->txa_private));
|
||||
tap->txa_private = m;
|
||||
|
||||
stageq_add(sq, m);
|
||||
sg->ff_stageqdepth++;
|
||||
stageq_add(ic, sq, m);
|
||||
IEEE80211_UNLOCK(ic);
|
||||
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni,
|
||||
@ -806,7 +808,7 @@ ieee80211_ff_node_cleanup(struct ieee80211_node *ni)
|
||||
m = tap->txa_private;
|
||||
if (m != NULL) {
|
||||
tap->txa_private = NULL;
|
||||
stageq_remove(&sg->ff_stageq[ac], m);
|
||||
stageq_remove(ic, &sg->ff_stageq[ac], m);
|
||||
m->m_nextpkt = head;
|
||||
head = m;
|
||||
}
|
||||
|
@ -66,7 +66,6 @@ struct ieee80211_stageq {
|
||||
struct ieee80211_superg {
|
||||
/* fast-frames staging q */
|
||||
struct ieee80211_stageq ff_stageq[WME_NUM_AC];
|
||||
int ff_stageqdepth; /* cumulative depth */
|
||||
};
|
||||
|
||||
void ieee80211_superg_attach(struct ieee80211com *);
|
||||
@ -109,7 +108,7 @@ ieee80211_ff_age_all(struct ieee80211com *ic, int quanta)
|
||||
{
|
||||
struct ieee80211_superg *sg = ic->ic_superg;
|
||||
|
||||
if (sg != NULL && sg->ff_stageqdepth) {
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user