Date: Sun, 20 May 2012 17:21:28 GMT From: Adrian Chadd <adrian@FreeBSD.org> To: freebsd-gnats-submit@FreeBSD.org Subject: misc/168170: [net80211] ieee80211_send_bar() doesn't complete correctly if there's a resource shortage Message-ID: <201205201721.q4KHLSc6021477@red.freebsd.org> Resent-Message-ID: <201205201730.q4KHU2x2026292@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 168170 >Category: misc >Synopsis: [net80211] ieee80211_send_bar() doesn't complete correctly if there's a resource shortage >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun May 20 17:30:02 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Adrian Chadd >Release: -HEAD >Organization: >Environment: FreeBSD freebsd-wifi-build 10.0-CURRENT FreeBSD 10.0-CURRENT #5 r235338:235659M: Wed Dec 31 16:00:00 PST 1969 adrian@dummy:/home/adrian/work/freebsd/svn/obj/mipseb/mips.mips/usr/home/adrian/work/freebsd/svn/src/sys/RSPRO mips >Description: I'm seeing scenarios where the TID pauses, tying up all ath_buf entries (and mbufs, further up in the network stack) until the STA is forcibly removed. Here's a snippet from the AP log: ath1: ath_tx_tid_drain: node 0xc1d8a000: bf=0xc1cd417c: addbaw=1, dobaw=1, seqno_assign=1, seqno_required=1, seqno=1560, retry=10 ath1: ath_tx_tid_drain: node 0xc1d8a000: bf=0xc1cd417c: tid txq_depth=78 hwq_depth=0, bar_wait=1 ath1: ath_tx_tid_drain: node 0xc1d8a000: bf=0xc1cd417c: tid 0: txq_depth=0, txq_aggr_depth=0, sched=0, paused=1, hwq_depth=0, incomp=0, baw_head=123, baw_tail=33 txa_start=1537, ni_txseqs=1575 After doing a whole lot of digging, I found this: * ieee80211_bar_send() is called from the wifi driver. If it fails there then the wifi driver will have to consider the BAR failed and continue. * if it succeeds, then the wifi driver should hold TXing any further frames until it completes. * If it does succeed, then bar_start_timer() is called. * If the TX completes succesfully, then everything is ok * But then, if it fails - either it's told that it fails or it times out, bar_timeout() is (eventually) called. The timer here has completed, so it won't be called again. * It then calls ieee80211_send_bar(), which should try sending again. * .. but if the call to ieee80211_send_bar() fails, the timer is never restarted - its only restarted _if_ ieee80211_send_bar() actually successfully completed. >How-To-Repeat: Fire up 802.11n on ath(4) in hostap mode; wait for TX failures to occur. >Fix: I'm not entirely sure. It may be good enough to just call bar_start_timer() from bar_timeout(), just to enforce that the timer needs to be kicked along whether or not ieee80211_send_bar() succeeded. The other problem is resource exhaustion. At this point, all ieee80211_send_bar() calls may fail because the driver is completely out of internal buffers (here ath_buf), or the network stack has exhausted all mbufs. So it likely requires a few fixes in a few places. >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205201721.q4KHLSc6021477>