diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-06-18 15:39:48 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-18 15:39:48 -0700 |
commit | ef3a62d272f033989e83eb1f26505f93f93e3e69 (patch) | |
tree | 9ce3eea86642e33dbec68dd2b3f81298f5ece235 /net | |
parent | 6d1a3fb567a728d31474636e167c324702a0c38b (diff) | |
download | linux-ef3a62d272f033989e83eb1f26505f93f93e3e69.tar.gz linux-ef3a62d272f033989e83eb1f26505f93f93e3e69.tar.bz2 linux-ef3a62d272f033989e83eb1f26505f93f93e3e69.zip |
mac80211: detect driver tx bugs
When a driver rejects a frame in it's ->tx() callback, it must also
stop queues, otherwise mac80211 can go into a loop here. Detect this
situation and abort the loop after five retries, warning about the
driver bug.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/tx.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 28d8bd53bd3a..c80d5899f279 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1132,7 +1132,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, ieee80211_tx_handler *handler; struct ieee80211_tx_data tx; ieee80211_tx_result res = TX_DROP, res_prepare; - int ret, i; + int ret, i, retries = 0; WARN_ON(__ieee80211_queue_pending(local, control->queue)); @@ -1216,6 +1216,13 @@ retry: if (!__ieee80211_queue_stopped(local, control->queue)) { clear_bit(IEEE80211_LINK_STATE_PENDING, &local->state[control->queue]); + retries++; + /* + * Driver bug, it's rejecting packets but + * not stopping queues. + */ + if (WARN_ON_ONCE(retries > 5)) + goto drop; goto retry; } memcpy(&store->control, control, |