wlcore: don't take mutex before stopping queues
authorArik Nemtsov <arik@wizery.com>
Wed, 28 Nov 2012 09:42:44 +0000 (11:42 +0200)
committerLuciano Coelho <coelho@ti.com>
Tue, 11 Dec 2012 10:37:22 +0000 (12:37 +0200)
Protect all functions touching queue_stop_reasons by spin-lock, since
they are accessed by op_tx. Now there's no need to take the mutex
before caling wlcore_queue_xxx functions.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/tx.c
drivers/net/wireless/ti/wlcore/tx.h

index 89f69d949443f5fb91bedeb660e3bcc626a0aa2c..56a5308b5b03ebc3ad66e4f7a8531e4cd28b0190 100644 (file)
@@ -1200,8 +1200,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw,
         */
        if (hlid == WL12XX_INVALID_LINK_ID ||
            (!test_bit(hlid, wlvif->links_map)) ||
-            (wlcore_is_queue_stopped(wl, wlvif, q) &&
-             !wlcore_is_queue_stopped_by_reason(wl, wlvif, q,
+            (wlcore_is_queue_stopped_locked(wl, wlvif, q) &&
+             !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
                        WLCORE_QUEUE_STOP_REASON_WATERMARK))) {
                wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q);
                ieee80211_free_txskb(hw, skb);
@@ -1220,7 +1220,7 @@ static void wl1271_op_tx(struct ieee80211_hw *hw,
         * the queue here, otherwise the queue will get too long.
         */
        if (wlvif->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK &&
-           !wlcore_is_queue_stopped_by_reason(wl, wlvif, q,
+           !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
                                        WLCORE_QUEUE_STOP_REASON_WATERMARK)) {
                wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q);
                wlcore_stop_queue_locked(wl, wlvif, q,
@@ -3229,10 +3229,7 @@ static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                 * stop the queues and flush to ensure the next packets are
                 * in sync with FW spare block accounting
                 */
-               mutex_lock(&wl->mutex);
                wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
-               mutex_unlock(&wl->mutex);
-
                wl1271_tx_flush(wl);
        }
 
index d464a8eba7b0ab9868315bd99e165c3e8a55c563..894ddc73a89025632f3b1fd95ed60f40603a6993 100644 (file)
@@ -1287,14 +1287,33 @@ void wlcore_wake_queues(struct wl1271 *wl,
 bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl,
                                       struct wl12xx_vif *wlvif, u8 queue,
                                       enum wlcore_queue_stop_reason reason)
+{
+       unsigned long flags;
+       bool stopped;
+
+       spin_lock_irqsave(&wl->wl_lock, flags);
+       stopped = wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, queue,
+                                                          reason);
+       spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+       return stopped;
+}
+
+bool wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
+                                      struct wl12xx_vif *wlvif, u8 queue,
+                                      enum wlcore_queue_stop_reason reason)
 {
        int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
+
+       WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
        return test_bit(reason, &wl->queue_stop_reasons[hwq]);
 }
 
-bool wlcore_is_queue_stopped(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                            u8 queue)
+bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                                   u8 queue)
 {
        int hwq = wlcore_tx_get_mac80211_queue(wlvif, queue);
+
+       WARN_ON_ONCE(!spin_is_locked(&wl->wl_lock));
        return !!wl->queue_stop_reasons[hwq];
 }
index 751bb6f46cbf8124ca2254692cf671235944d8d9..55aa4acf9105a4e703036b0b12250ae19a9a7f81 100644 (file)
@@ -268,8 +268,13 @@ void wlcore_wake_queues(struct wl1271 *wl,
 bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl,
                                       struct wl12xx_vif *wlvif, u8 queue,
                                       enum wlcore_queue_stop_reason reason);
-bool wlcore_is_queue_stopped(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                            u8 queue);
+bool
+wlcore_is_queue_stopped_by_reason_locked(struct wl1271 *wl,
+                                        struct wl12xx_vif *wlvif,
+                                        u8 queue,
+                                        enum wlcore_queue_stop_reason reason);
+bool wlcore_is_queue_stopped_locked(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                                   u8 queue);
 
 /* from main.c */
 void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);