mirror of https://github.com/proski/madwifi
Simplification of kernel queue start/stop logic.
We had a local flag that was being used inconsistently to mirror the queue state, but was really brain dead. sc_devstopped could be off even when the queue was stopped and no matter how many buffers were freed, we would never restart the queue. This could lead to liveness issues (mostly after a buffer leak caused excessive buffers to be used). The kernel has an easy call to find out if the queue is stopped or not, so this checkin uses that. We will re-awaken the queue if: 1) we have some buffers we are willing to use for data 2) the channel is available (as opposed to being in DFS CAC) 3) the queue is stopped This is what we were originally going for with reap counters and sc_dev_stopped and all this other nonsense. The new logic is much simpler and cleaner. This also fixes a performance problem where the queue was being re-awakened when no buffers were available resulting in a constant ping-pong of buffers between the kernel and madwifi and a very very heavy CPU utilization at exactly the wrong time. git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3503 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
parent
9148c7a79a
commit
3a132792ff
39
ath/if_ath.c
39
ath/if_ath.c
|
@ -3082,8 +3082,6 @@ _take_txbuf_locked(struct ath_softc *sc, int for_management)
|
|||
"buffers.\n");
|
||||
sc->sc_stats.ast_tx_qstop++;
|
||||
netif_stop_queue(sc->sc_dev);
|
||||
sc->sc_devstopped = 1;
|
||||
ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, NULL);
|
||||
}
|
||||
|
||||
/* Only let us go further if management frame, or there are enough */
|
||||
|
@ -3276,11 +3274,6 @@ ath_hardstart(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
txq = sc->sc_ac2q[skb->priority];
|
||||
|
||||
if (txq->axq_depth > TAIL_DROP_COUNT) {
|
||||
/* Wish to reserve some DMA buffers, try again later. */
|
||||
requeue = 1;
|
||||
goto hardstart_fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the skb data is shared, we will copy it so we can strip padding
|
||||
|
@ -3511,7 +3504,6 @@ hardstart_fail:
|
|||
if (requeue) {
|
||||
/* Queue is full, let the kernel backlog the skb */
|
||||
netif_stop_queue(dev);
|
||||
sc->sc_devstopped = 1;
|
||||
/* Stop tracking again we are giving it back*/
|
||||
ieee80211_skb_untrack(skb);
|
||||
return NETDEV_TX_BUSY;
|
||||
|
@ -12176,6 +12168,7 @@ ath_return_txbuf_locked(struct ath_softc *sc, struct ath_buf **bf)
|
|||
cleanup_ath_buf(sc, (*bf), BUS_DMA_TODEVICE);
|
||||
#endif
|
||||
STAILQ_INSERT_TAIL(&sc->sc_txbuf, (*bf), bf_list);
|
||||
*bf = NULL;
|
||||
atomic_dec(&sc->sc_txbuf_counter);
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
DPRINTF(sc, ATH_DEBUG_TXBUF,
|
||||
|
@ -12183,22 +12176,22 @@ ath_return_txbuf_locked(struct ath_softc *sc, struct ath_buf **bf)
|
|||
ath_get_buffer_count(sc), ATH_TXBUF,
|
||||
func, line, bfaddr);
|
||||
#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
if (sc->sc_devstopped) {
|
||||
++sc->sc_reapcount;
|
||||
if (sc->sc_reapcount > ATH_TXBUF_FREE_THRESHOLD) {
|
||||
if (!ath_chan_unavail(sc)) {
|
||||
netif_wake_queue(sc->sc_dev);
|
||||
DPRINTF(sc, ATH_DEBUG_ANY,
|
||||
"Restarting queue.\n");
|
||||
}
|
||||
sc->sc_reapcount = 0;
|
||||
sc->sc_devstopped = 0;
|
||||
}
|
||||
else if (!ath_chan_unavail(sc))
|
||||
ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, NULL);
|
||||
if (netif_queue_stopped(sc->sc_dev) &&
|
||||
(ath_get_buffers_available(sc) > ATH_TXBUF_MGT_RESERVED) &&
|
||||
(!ath_chan_unavail(sc))) {
|
||||
DPRINTF(sc, ATH_DEBUG_TXBUF | ATH_DEBUG_RESET,
|
||||
"Waking device queue with %d available buffers.\n",
|
||||
ath_get_buffers_available(sc));
|
||||
netif_wake_queue(sc->sc_dev);
|
||||
}
|
||||
|
||||
*bf = NULL;
|
||||
#if 0
|
||||
else if (ath_chan_unavail(sc)) {
|
||||
DPRINTF(sc, (ATH_DEBUG_TXBUF | ATH_DEBUG_RESET |
|
||||
ATH_DEBUG_DOTH),
|
||||
"Not waking device queue. Channel "
|
||||
"is not available.\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Takes the TXBUF_LOCK */
|
||||
|
|
|
@ -220,14 +220,9 @@ static inline struct net_device *_alloc_netdev(int sizeof_priv, const char *mask
|
|||
#define ATH_MAXVAPS_MIN 2 /* minimum number of beacon buffers */
|
||||
#define ATH_MAXVAPS_MAX 64 /* maximum number of beacon buffers */
|
||||
#define ATH_MAXVAPS_DEFAULT 4 /* default number of beacon buffers */
|
||||
|
||||
/* free buffer threshold to restart net dev */
|
||||
#define ATH_TXBUF_FREE_THRESHOLD (ATH_TXBUF / 20)
|
||||
/* number of TX buffers reserved for mgt frames */
|
||||
#define ATH_TXBUF_MGT_RESERVED 5
|
||||
|
||||
#define TAIL_DROP_COUNT 50 /* maximum number of queued frames allowed */
|
||||
|
||||
/*
|
||||
* dynamic turbo specific macros.
|
||||
*/
|
||||
|
@ -671,7 +666,6 @@ struct ath_softc {
|
|||
unsigned int sc_xrgrppoll:1; /* xr group polls are active */
|
||||
unsigned int sc_syncbeacon:1; /* sync/resync beacon timers */
|
||||
unsigned int sc_hasclrkey:1; /* CLR key supported */
|
||||
unsigned int sc_devstopped:1; /* stopped due to of no tx bufs */
|
||||
unsigned int sc_stagbeacons:1; /* use staggered beacons */
|
||||
unsigned int sc_dfswait:1; /* waiting on channel for radar detect */
|
||||
unsigned int sc_ackrate:1; /* send acks at high bitrate */
|
||||
|
@ -787,7 +781,6 @@ struct ath_softc {
|
|||
struct ctl_table_header *sc_sysctl_header;
|
||||
struct ctl_table *sc_sysctls;
|
||||
|
||||
u_int16_t sc_reapcount; /* # of tx buffers reaped after net dev stopped */
|
||||
struct timer_list sc_mib_enable;
|
||||
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
|
|
Loading…
Reference in New Issue