From 06f7bc7db79fabe6b2ec16eff0f59e4acc21eb72 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Mon, 22 Feb 2010 08:38:33 +0200 Subject: wl1271: Fix queue stopping/waking for TX path The queue stopping/waking functionality was broken in a way that could cause huge latencies in TX transfers and even cause the TX to stall in the right circumstances. Correct these problems. Signed-off-by: Juuso Oikarinen Reviewed-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_main.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/wl12xx/wl1271_main.c') diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 81fb02e82923..184264a53b20 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -791,15 +791,13 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * The workqueue is slow to process the tx_queue and we need stop * the queue here, otherwise the queue will get too long. */ - if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) { - ieee80211_stop_queues(wl->hw); + if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { + wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); - /* - * FIXME: this is racy, the variable is not properly - * protected. Maybe fix this by removing the stupid - * variable altogether and checking the real queue state? - */ + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_stop_queues(wl->hw); set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); } return NETDEV_TX_OK; -- cgit v1.2.2