rt2x00: Fix txdone race condition
Subsystems (3)
PATCH 21/26 rt2x00: Fix txdone race condition
Always call ieee80211_wake_queue if the ring is not full after the txrun. The ieee80211_wake_queue is responsible for chacking if the queue was stopped or not.
The current implementation of checking the ring_full before the txdone run was flawed and race conditions could occur that blocked all tx handling.
Signed-off-by Ivo van Doorn <[email protected]>
---
drivers/net/wireless/d80211/rt2x00/rt2400pci.c +1 -7
@@ -1613,14 +1613,8 @@u32 word;int tx_status;int ack; -int ring_full;int rts; -/* -* Store the current status of the ring. -*/ - ring_full =rt2x00_ring_full (ring); -while (!rt2x00_ring_empty (ring)) { entry =rt2x00_get_data_entry_done (ring); txd =rt2x00_desc_addr (entry);
@@ -1687,7 +1681,7 @@* is reenabled when the txdone handler has finished. */ entry = ring->entry; -if (ring_full && !rt2x00_ring_full (ring)) +if (!rt2x00_ring_full (ring))ieee80211_wake_queue (rt2x00dev->hw, entry->tx_status.control.queue); }
drivers/net/wireless/d80211/rt2x00/rt2500pci.c +1 -7
@@ -1776,14 +1776,8 @@u32 word;int tx_status;int ack; -int ring_full;int rts; -/* -* Store the current status of the ring. -*/ - ring_full =rt2x00_ring_full (ring); -while (!rt2x00_ring_empty (ring)) { entry =rt2x00_get_data_entry_done (ring); txd =rt2x00_desc_addr (entry);
@@ -1850,7 +1844,7 @@* is reenabled when the txdone handler has finished. */ entry = ring->entry; -if (ring_full && !rt2x00_ring_full (ring)) +if (!rt2x00_ring_full (ring))ieee80211_wake_queue (rt2x00dev->hw, entry->tx_status.control.queue); }
drivers/net/wireless/d80211/rt2x00/rt2500usb.c +1 -7
@@ -1753,14 +1753,8 @@struct urb *urb;u32 word;int ack; -int ring_full;int rts; -/* -* Store the current status of the ring. -*/ - ring_full =rt2x00_ring_full (ring); -while (!rt2x00_ring_empty (ring)) { entry =rt2x00_get_data_entry_done (ring); txd =rt2x00_txdesc_addr (entry);
@@ -1821,7 +1815,7 @@* is reenabled when the txdone handler has finished. */ entry = ring->entry; -if (ring_full && !rt2x00_ring_full (ring)) +if (!rt2x00_ring_full (ring))ieee80211_wake_queue (rt2x00dev->hw, entry->tx_status.control.queue); }
drivers/net/wireless/d80211/rt2x00/rt61pci.c +2 -7
@@ -2235,7 +2235,6 @@u32 word;int tx_status;int ack; -int ring_full;int rts; txd =rt2x00_desc_addr (entry);
@@ -2285,11 +2284,6 @@CLEAR_FLAG (entry,ENTRY_RTS_FRAME ); entry->skb =NULL ; -/* -* Store the current status of the ring. -*/ - ring_full =rt2x00_ring_full (entry->ring); -rt2x00_ring_index_done_inc (entry->ring);/*
@@ -2297,7 +2291,8 @@* we must make sure the packet queue in the d80211 stack * is reenabled when the txdone handler has finished. */ -if (ring_full && !rt2x00_ring_full (entry->ring)) + entry = ring->entry; +if (!rt2x00_ring_full (ring))ieee80211_wake_queue (rt2x00dev->hw, entry->tx_status.control.queue); }
drivers/net/wireless/d80211/rt2x00/rt73usb.c +1 -7
@@ -2026,14 +2026,8 @@struct urb *urb;u32 word;int ack; -int ring_full;int rts; -/* -* Store the current status of the ring. -*/ - ring_full =rt2x00_ring_full (ring); -while (!rt2x00_ring_empty (ring)) { entry =rt2x00_get_data_entry_done (ring); txd =rt2x00_desc_addr (entry);
@@ -2096,7 +2090,7 @@* is reenabled when the txdone handler has finished. */ entry = ring->entry; -if (ring_full && !rt2x00_ring_full (ring)) +if (!rt2x00_ring_full (ring))ieee80211_wake_queue (rt2x00dev->hw, entry->tx_status.control.queue); }