ath10k: prevent txrx running for too long
authorMichal Kazior <michal.kazior@tieto.com>
Wed, 13 Jan 2016 13:52:52 +0000 (14:52 +0100)
committerKalle Valo <kvalo@qca.qualcomm.com>
Thu, 21 Jan 2016 11:50:29 +0000 (13:50 +0200)
On multicore systems it was possible for the txrx
tasklet to keep on running for long periods of
time on a single CPU due to tx completion
processing. Another CPU could feed the running
tasklet for an indefinite amount of time.

The tasklet is now guaranteed to run a finite
amount of time and is limited by HTT CE Rx ring
depth.

This improves behavior when RPS is used on target
system and might improve TCP handling as well.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/htt_rx.c

index 91afa3a..3079434 100644 (file)
@@ -2156,10 +2156,18 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr)
 {
        struct ath10k_htt *htt = (struct ath10k_htt *)ptr;
        struct ath10k *ar = htt->ar;
+       struct sk_buff_head tx_q;
        struct htt_resp *resp;
        struct sk_buff *skb;
+       unsigned long flags;
 
-       while ((skb = skb_dequeue(&htt->tx_compl_q))) {
+       __skb_queue_head_init(&tx_q);
+
+       spin_lock_irqsave(&htt->tx_compl_q.lock, flags);
+       skb_queue_splice_init(&htt->tx_compl_q, &tx_q);
+       spin_unlock_irqrestore(&htt->tx_compl_q.lock, flags);
+
+       while ((skb = __skb_dequeue(&tx_q))) {
                ath10k_htt_rx_frm_tx_compl(htt->ar, skb);
                dev_kfree_skb_any(skb);
        }