Skip to content

Commit

Permalink
ath10k: implement NAPI support
Browse files Browse the repository at this point in the history
Add NAPI support for rx and tx completion. NAPI poll is scheduled
from interrupt handler. The design is as below

 - on interrupt
     - schedule napi and mask interrupts
 - on poll
   - process all pipes (no actual Tx/Rx)
   - process Rx within budget
   - if quota exceeds budget reschedule napi poll by returning budget
   - process Tx completions and update budget if necessary
   - process Tx fetch indications (pull-push)
   - push any other pending Tx (if possible)
   - before resched or napi completion replenish htt rx ring buffer
   - if work done < budget, complete napi poll and unmask interrupts

This change also get rid of two tasklets (intr_tq and txrx_compl_task).

Measured peak throughput with NAPI on IPQ4019 platform in controlled
environment. No noticeable reduction in throughput is seen and also
observed improvements in CPU usage. Approx. 15% CPU usage got reduced
in UDP uplink case.

DL: AP DUT Tx
UL: AP DUT Rx

IPQ4019 (avg. cpu usage %)

========
                TOT              +NAPI
              ===========      =============
TCP DL       644 Mbps (42%)    645 Mbps (36%)
TCP UL       673 Mbps (30%)    675 Mbps (26%)
UDP DL       682 Mbps (49%)    680 Mbps (49%)
UDP UL       720 Mbps (28%)    717 Mbps (11%)

Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
  • Loading branch information
Rajkumar Manoharan authored and Kalle Valo committed Sep 9, 2016
1 parent c39265f commit 3c97f5d
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 96 deletions.
10 changes: 7 additions & 3 deletions drivers/net/wireless/ath/ath10k/ahb.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,13 +462,13 @@ static void ath10k_ahb_halt_chip(struct ath10k *ar)
static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg)
{
struct ath10k *ar = arg;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);

if (!ath10k_pci_irq_pending(ar))
return IRQ_NONE;

ath10k_pci_disable_and_clear_legacy_irq(ar);
tasklet_schedule(&ar_pci->intr_tq);
ath10k_pci_irq_msi_fw_mask(ar);
napi_schedule(&ar->napi);

return IRQ_HANDLED;
}
Expand Down Expand Up @@ -717,6 +717,9 @@ static void ath10k_ahb_hif_stop(struct ath10k *ar)
synchronize_irq(ar_ahb->irq);

ath10k_pci_flush(ar);

napi_synchronize(&ar->napi);
napi_disable(&ar->napi);
}

static int ath10k_ahb_hif_power_up(struct ath10k *ar)
Expand Down Expand Up @@ -748,6 +751,7 @@ static int ath10k_ahb_hif_power_up(struct ath10k *ar)
ath10k_err(ar, "could not wake up target CPU: %d\n", ret);
goto err_ce_deinit;
}
napi_enable(&ar->napi);

return 0;

Expand Down Expand Up @@ -831,7 +835,7 @@ static int ath10k_ahb_probe(struct platform_device *pdev)
goto err_resource_deinit;
}

ath10k_pci_init_irq_tasklets(ar);
ath10k_pci_init_napi(ar);

ret = ath10k_ahb_request_irq_legacy(ar);
if (ret)
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/ath/ath10k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2322,6 +2322,8 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
INIT_WORK(&ar->register_work, ath10k_core_register_work);
INIT_WORK(&ar->restart_work, ath10k_core_restart);

init_dummy_netdev(&ar->napi_dev);

ret = ath10k_debug_create(ar);
if (ret)
goto err_free_aux_wq;
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/wireless/ath/ath10k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@
#define ATH10K_KEEPALIVE_MAX_IDLE 3895
#define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900

/* NAPI poll budget */
#define ATH10K_NAPI_BUDGET 64
#define ATH10K_NAPI_QUOTA_LIMIT 60

struct ath10k;

enum ath10k_bus {
Expand Down Expand Up @@ -954,6 +958,10 @@ struct ath10k {
struct ath10k_thermal thermal;
struct ath10k_wow wow;

/* NAPI */
struct net_device napi_dev;
struct napi_struct napi;

/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath10k/htt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,6 @@ struct ath10k_htt {

/* This is used to group tx/rx completions separately and process them
* in batches to reduce cache stalls */
struct tasklet_struct txrx_compl_task;
struct sk_buff_head rx_compl_q;
struct sk_buff_head rx_in_ord_compl_q;
struct sk_buff_head tx_fetch_ind_q;
Expand Down Expand Up @@ -1798,5 +1797,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt,
struct sk_buff *msdu);
void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
struct sk_buff *skb);
int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget);

#endif
Loading

0 comments on commit 3c97f5d

Please sign in to comment.