Is possible that we stop queue and then do not wake up it again, especially when packets are transmitted fast. That can be easily reproduced with modified tx queue entry_num to some small value e.g. 16. If mac80211 already hold local->queue_stop_reason_lock, then we can wait on that lock in both rt2x00queue_pause_queue() and rt2x00queue_unpause_queue(). After drooping ->queue_stop_reason_lock is possible that __ieee80211_wake_queue() will be performed before __ieee80211_stop_queue(), hence we stop queue and newer wake up it again. Another race condition is possible when between rt2x00queue_threshold() check and rt2x00queue_pause_queue() we will process all pending tx buffers on different cpu. This might happen if for example interrupt will be triggered on cpu performing rt2x00mac_tx(). To prevent race conditions serialize pause/unpause by queue->tx_lock. Cc: stable@vger.kernel.org Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> |
||
---|---|---|
.. | ||
Kconfig | ||
Makefile | ||
rt2x00.h | ||
rt2x00config.c | ||
rt2x00crypto.c | ||
rt2x00debug.c | ||
rt2x00debug.h | ||
rt2x00dev.c | ||
rt2x00dump.h | ||
rt2x00firmware.c | ||
rt2x00leds.c | ||
rt2x00leds.h | ||
rt2x00lib.h | ||
rt2x00link.c | ||
rt2x00mac.c | ||
rt2x00pci.c | ||
rt2x00pci.h | ||
rt2x00queue.c | ||
rt2x00queue.h | ||
rt2x00reg.h | ||
rt2x00soc.c | ||
rt2x00soc.h | ||
rt2x00usb.c | ||
rt2x00usb.h | ||
rt61pci.c | ||
rt61pci.h | ||
rt73usb.c | ||
rt73usb.h | ||
rt2400pci.c | ||
rt2400pci.h | ||
rt2500pci.c | ||
rt2500pci.h | ||
rt2500usb.c | ||
rt2500usb.h | ||
rt2800.h | ||
rt2800lib.c | ||
rt2800lib.h | ||
rt2800pci.c | ||
rt2800pci.h | ||
rt2800usb.c | ||
rt2800usb.h |