aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/txrx.c
diff options
context:
space:
mode:
authorQi Zhou <qizhou@google.com>2015-07-22 16:38:24 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2015-07-29 11:27:24 +0300
commit005fb161310f72070ad5f4352d6b81ffaca8a11e (patch)
tree02d2756fd70810e72998007b9ffa732f294060c8 /drivers/net/wireless/ath/ath10k/txrx.c
parentath10k: suppress 'failed to process fft' warning messages (diff)
downloadlinux-dev-005fb161310f72070ad5f4352d6b81ffaca8a11e.tar.xz
linux-dev-005fb161310f72070ad5f4352d6b81ffaca8a11e.zip
ath10k: Improve performance by reducing tx_lock contention
During tx completion, tx_lock is held for longer than required, preventing efficient refill of htt->pending_tx. Refactor the code so that only MSDU related operations are protected by the lock. Improves downstream performance on a dual-core ARM Freescale LS1024A (f.k.a. Mindspeed Comcerto 2000) AP with a 3x3 client from 495 to 580 Mbps. Other CPU bound multicore systems may also benefit. Signed-off-by: Denton Gentry <dgentry@google.com> Signed-off-by: Avery Pennarun <apenwarr@google.com> [mfaltesek@google.com: removed conflicting code for tracking msdu_ids.] Signed-off-by: Marty Faltesek <mfaltesek@google.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/txrx.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 6cf289158840..e4a9c4c8d0cb 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -53,8 +53,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
struct ath10k_skb_cb *skb_cb;
struct sk_buff *msdu;
- lockdep_assert_held(&htt->tx_lock);
-
ath10k_dbg(ar, ATH10K_DBG_HTT,
"htt tx completion msdu_id %u discard %d no_ack %d success %d\n",
tx_done->msdu_id, !!tx_done->discard,
@@ -66,12 +64,19 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
return;
}
+ spin_lock_bh(&htt->tx_lock);
msdu = idr_find(&htt->pending_tx, tx_done->msdu_id);
if (!msdu) {
ath10k_warn(ar, "received tx completion for invalid msdu_id: %d\n",
tx_done->msdu_id);
+ spin_unlock_bh(&htt->tx_lock);
return;
}
+ ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
+ __ath10k_htt_tx_dec_pending(htt);
+ if (htt->num_pending_tx == 0)
+ wake_up(&htt->empty_tx_wq);
+ spin_unlock_bh(&htt->tx_lock);
skb_cb = ATH10K_SKB_CB(msdu);
@@ -90,7 +95,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
if (tx_done->discard) {
ieee80211_free_txskb(htt->ar->hw, msdu);
- goto exit;
+ return;
}
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -104,12 +109,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
ieee80211_tx_status(htt->ar->hw, msdu);
/* we do not own the msdu anymore */
-
-exit:
- ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
- __ath10k_htt_tx_dec_pending(htt);
- if (htt->num_pending_tx == 0)
- wake_up(&htt->empty_tx_wq);
}
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,