Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759474Ab3IHDUi (ORCPT ); Sat, 7 Sep 2013 23:20:38 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:55994 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754049Ab3IHDSv (ORCPT ); Sat, 7 Sep 2013 23:18:51 -0400 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Stanislaw Gruszka" , "John W. Linville" Date: Sun, 08 Sep 2013 03:52:01 +0100 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [048/121] rt2x00: fix stop queue In-Reply-To: X-SA-Exim-Connect-IP: 192.168.4.101 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2590 Lines: 78 3.2.51-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Stanislaw Gruszka commit e2288b66fe7ff0288382b2af671b4da558b44472 upstream. Since we clear QUEUE_STARTED in rt2x00queue_stop_queue(), following call to rt2x00queue_pause_queue() reduce to noop, i.e we do not stop queue in mac80211. To fix that introduce rt2x00queue_pause_queue_nocheck() function, which will stop queue in mac80211 directly. Note that rt2x00_start_queue() explicitly set QUEUE_PAUSED bit. Note also that reordering operations i.e. first call to rt2x00queue_pause_queue() and then clear QUEUE_STARTED bit, will race with rt2x00queue_unpause_queue(), so calling ieee80211_stop_queue() directly is the only available solution to fix the problem without major rework. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville Signed-off-by: Ben Hutchings --- drivers/net/wireless/rt2x00/rt2x00queue.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -856,13 +856,8 @@ void rt2x00queue_index_inc(struct queue_ spin_unlock_irqrestore(&queue->index_lock, irqflags); } -void rt2x00queue_pause_queue(struct data_queue *queue) +void rt2x00queue_pause_queue_nocheck(struct data_queue *queue) { - if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || - !test_bit(QUEUE_STARTED, &queue->flags) || - test_and_set_bit(QUEUE_PAUSED, &queue->flags)) - return; - switch (queue->qid) { case QID_AC_VO: case QID_AC_VI: @@ -878,6 +873,15 @@ void rt2x00queue_pause_queue(struct data break; } } +void rt2x00queue_pause_queue(struct data_queue *queue) +{ + if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || + !test_bit(QUEUE_STARTED, &queue->flags) || + test_and_set_bit(QUEUE_PAUSED, &queue->flags)) + return; + + rt2x00queue_pause_queue_nocheck(queue); +} EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); void rt2x00queue_unpause_queue(struct data_queue *queue) @@ -939,7 +943,7 @@ void rt2x00queue_stop_queue(struct data_ return; } - rt2x00queue_pause_queue(queue); + rt2x00queue_pause_queue_nocheck(queue); queue->rt2x00dev->ops->lib->stop_queue(queue); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/