Date: Sun, 19 Mar 2017 20:05:21 +0000 (UTC) From: Andriy Voskoboinyk <avos@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r315583 - head/sys/net80211 Message-ID: <201703192005.v2JK5LL7005539@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avos Date: Sun Mar 19 20:05:21 2017 New Revision: 315583 URL: https://svnweb.freebsd.org/changeset/base/315583 Log: net80211: add a timer to flush fast-frames queues. This should allow to drop 'ieee80211_ff_[age/flush]' calls from drivers (an additional call can be made from ieee80211_tx_complete() for non-default ieee80211_ffagemax values to prevent stalls - but it will require an additional counter for transmitted frames). Tested with RTL8821AU, STA mode (A-MSDU part only). Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D9984 Modified: head/sys/net80211/ieee80211_superg.c head/sys/net80211/ieee80211_superg.h Modified: head/sys/net80211/ieee80211_superg.c ============================================================================== --- head/sys/net80211/ieee80211_superg.c Sun Mar 19 20:04:57 2017 (r315582) +++ head/sys/net80211/ieee80211_superg.c Sun Mar 19 20:05:21 2017 (r315583) @@ -94,6 +94,33 @@ SYSCTL_PROC(_net_wlan, OID_AUTO, ffagema &ieee80211_ffagemax, 0, ieee80211_sysctl_msecs_ticks, "I", "max hold time for fast-frame staging (ms)"); +static void +ff_age_all(void *arg, int npending) +{ + struct ieee80211com *ic = arg; + + /* XXX cache timer value somewhere (racy) */ + ieee80211_ff_age_all(ic, ieee80211_ffagemax + 1); +} + +static void +ff_check_cancel_age_timer(struct ieee80211com *ic) +{ + struct ieee80211_superg *sg = ic->ic_superg; + + IEEE80211_FF_LOCK_ASSERT(ic); + + if (sg->ff_stageq[WME_AC_VO].depth == 0 && + sg->ff_stageq[WME_AC_VI].depth == 0 && + sg->ff_stageq[WME_AC_BE].depth == 0 && + sg->ff_stageq[WME_AC_BK].depth == 0) { + struct timeout_task *qtask = &sg->ff_qtimer; + + /* NB: may be called from the task itself */ + (void) taskqueue_cancel_timeout(ic->ic_tq, qtask, NULL); + } +} + void ieee80211_superg_attach(struct ieee80211com *ic) { @@ -109,6 +136,7 @@ ieee80211_superg_attach(struct ieee80211 __func__); return; } + TIMEOUT_TASK_INIT(ic->ic_tq, &sg->ff_qtimer, 0, ff_age_all, ic); ic->ic_superg = sg; /* @@ -122,12 +150,16 @@ ieee80211_superg_attach(struct ieee80211 void ieee80211_superg_detach(struct ieee80211com *ic) { - IEEE80211_FF_LOCK_DESTROY(ic); if (ic->ic_superg != NULL) { + struct timeout_task *qtask = &ic->ic_superg->ff_qtimer; + + while (taskqueue_cancel_timeout(ic->ic_tq, qtask, NULL) != 0) + taskqueue_drain_timeout(ic->ic_tq, qtask); IEEE80211_FREE(ic->ic_superg, M_80211_VAP); ic->ic_superg = NULL; } + IEEE80211_FF_LOCK_DESTROY(ic); } void @@ -647,9 +679,10 @@ ieee80211_ff_age(struct ieee80211com *ic sq->head = m->m_nextpkt; sq->depth--; } - if (m == NULL) + if (m == NULL) { sq->tail = NULL; - else + ff_check_cancel_age_timer(ic); + } else M_AGE_SUB(m, quanta); IEEE80211_FF_UNLOCK(ic); @@ -668,8 +701,13 @@ stageq_add(struct ieee80211com *ic, stru if (sq->tail != NULL) { sq->tail->m_nextpkt = m; age -= M_AGE_GET(sq->head); - } else + } else { sq->head = m; + + /* Do not restart the timer if task was already scheduled. */ + struct timeout_task *qtask = &ic->ic_superg->ff_qtimer; + taskqueue_enqueue_timeout(ic->ic_tq, qtask, -age); + } KASSERT(age >= 0, ("age %d", age)); M_AGE_SET(m, age); m->m_nextpkt = NULL; @@ -694,6 +732,7 @@ stageq_remove(struct ieee80211com *ic, s if (sq->tail == m) sq->tail = mprev; sq->depth--; + ff_check_cancel_age_timer(ic); return; } mprev = m; Modified: head/sys/net80211/ieee80211_superg.h ============================================================================== --- head/sys/net80211/ieee80211_superg.h Sun Mar 19 20:04:57 2017 (r315582) +++ head/sys/net80211/ieee80211_superg.h Sun Mar 19 20:05:21 2017 (r315583) @@ -66,6 +66,8 @@ struct ieee80211_stageq { struct ieee80211_superg { /* fast-frames staging q */ struct ieee80211_stageq ff_stageq[WME_NUM_AC]; + /* flush queues automatically */ + struct timeout_task ff_qtimer; }; void ieee80211_superg_attach(struct ieee80211com *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703192005.v2JK5LL7005539>