Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6037d22 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho
Browse files

wlcore: don't take mutex before stopping queues



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: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 1c33db78
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -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);
	}

+21 −2
Original line number Diff line number Diff line
@@ -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,
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];
}
+7 −2
Original line number Diff line number Diff line
@@ -268,7 +268,12 @@ 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,
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 */