mirror of https://gitee.com/openkylin/linux.git
bna: Remove tx tasklet
The scheduling of tasklet and keeping the interrupts enabled makes interrupt reduntant. 20% of the Tx interrupts have nothing left to process or could not process as Tx tasklet was running. Signed-off-by: Jing Huang <huangj@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
01b54b1451
commit
d95d1081c3
|
@ -185,7 +185,6 @@ bnad_free_all_txbufs(struct bnad *bnad,
|
||||||
* bnad_free_txbufs : Frees the Tx bufs on Tx completion
|
* bnad_free_txbufs : Frees the Tx bufs on Tx completion
|
||||||
* Can be called in a) Interrupt context
|
* Can be called in a) Interrupt context
|
||||||
* b) Sending context
|
* b) Sending context
|
||||||
* c) Tasklet context
|
|
||||||
*/
|
*/
|
||||||
static u32
|
static u32
|
||||||
bnad_free_txbufs(struct bnad *bnad,
|
bnad_free_txbufs(struct bnad *bnad,
|
||||||
|
@ -197,13 +196,7 @@ bnad_free_txbufs(struct bnad *bnad,
|
||||||
struct bnad_skb_unmap *unmap_array;
|
struct bnad_skb_unmap *unmap_array;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
/*
|
/* Just return if TX is stopped */
|
||||||
* Just return if TX is stopped. This check is useful
|
|
||||||
* when bnad_free_txbufs() runs out of a tasklet scheduled
|
|
||||||
* before bnad_cb_tx_cleanup() cleared BNAD_TXQ_TX_STARTED bit
|
|
||||||
* but this routine runs actually after the cleanup has been
|
|
||||||
* executed.
|
|
||||||
*/
|
|
||||||
if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
|
if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -242,55 +235,6 @@ bnad_free_txbufs(struct bnad *bnad,
|
||||||
return sent_packets;
|
return sent_packets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tx Free Tasklet function */
|
|
||||||
/* Frees for all the tcb's in all the Tx's */
|
|
||||||
/*
|
|
||||||
* Scheduled from sending context, so that
|
|
||||||
* the fat Tx lock is not held for too long
|
|
||||||
* in the sending context.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
bnad_tx_free_tasklet(unsigned long bnad_ptr)
|
|
||||||
{
|
|
||||||
struct bnad *bnad = (struct bnad *)bnad_ptr;
|
|
||||||
struct bna_tcb *tcb;
|
|
||||||
u32 acked = 0;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < bnad->num_tx; i++) {
|
|
||||||
for (j = 0; j < bnad->num_txq_per_tx; j++) {
|
|
||||||
tcb = bnad->tx_info[i].tcb[j];
|
|
||||||
if (!tcb)
|
|
||||||
continue;
|
|
||||||
if (((u16) (*tcb->hw_consumer_index) !=
|
|
||||||
tcb->consumer_index) &&
|
|
||||||
(!test_and_set_bit(BNAD_TXQ_FREE_SENT,
|
|
||||||
&tcb->flags))) {
|
|
||||||
acked = bnad_free_txbufs(bnad, tcb);
|
|
||||||
if (likely(test_bit(BNAD_TXQ_TX_STARTED,
|
|
||||||
&tcb->flags)))
|
|
||||||
bna_ib_ack(tcb->i_dbell, acked);
|
|
||||||
smp_mb__before_clear_bit();
|
|
||||||
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
|
|
||||||
}
|
|
||||||
if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED,
|
|
||||||
&tcb->flags)))
|
|
||||||
continue;
|
|
||||||
if (netif_queue_stopped(bnad->netdev)) {
|
|
||||||
if (acked && netif_carrier_ok(bnad->netdev) &&
|
|
||||||
BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
|
|
||||||
BNAD_NETIF_WAKE_THRESHOLD) {
|
|
||||||
netif_wake_queue(bnad->netdev);
|
|
||||||
/* TODO */
|
|
||||||
/* Counters for individual TxQs? */
|
|
||||||
BNAD_UPDATE_CTR(bnad,
|
|
||||||
netif_queue_wakeup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
|
bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
|
||||||
{
|
{
|
||||||
|
@ -1789,9 +1733,6 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
|
||||||
bnad_tx_msix_unregister(bnad, tx_info,
|
bnad_tx_msix_unregister(bnad, tx_info,
|
||||||
bnad->num_txq_per_tx);
|
bnad->num_txq_per_tx);
|
||||||
|
|
||||||
if (0 == tx_id)
|
|
||||||
tasklet_kill(&bnad->tx_free_tasklet);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bnad->bna_lock, flags);
|
spin_lock_irqsave(&bnad->bna_lock, flags);
|
||||||
bna_tx_destroy(tx_info->tx);
|
bna_tx_destroy(tx_info->tx);
|
||||||
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
||||||
|
@ -2871,9 +2812,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||||
bna_txq_prod_indx_doorbell(tcb);
|
bna_txq_prod_indx_doorbell(tcb);
|
||||||
smp_mb();
|
smp_mb();
|
||||||
|
|
||||||
if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index)
|
|
||||||
tasklet_schedule(&bnad->tx_free_tasklet);
|
|
||||||
|
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3155,9 +3093,8 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac)
|
||||||
/*
|
/*
|
||||||
* 1. Initialize the bnad structure
|
* 1. Initialize the bnad structure
|
||||||
* 2. Setup netdev pointer in pci_dev
|
* 2. Setup netdev pointer in pci_dev
|
||||||
* 3. Initialze Tx free tasklet
|
* 3. Initialize no. of TxQ & CQs & MSIX vectors
|
||||||
* 4. Initialize no. of TxQ & CQs & MSIX vectors
|
* 4. Initialize work queue.
|
||||||
* 5. Initialize work queue.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
bnad_init(struct bnad *bnad,
|
bnad_init(struct bnad *bnad,
|
||||||
|
@ -3200,9 +3137,6 @@ bnad_init(struct bnad *bnad,
|
||||||
bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO;
|
bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO;
|
||||||
bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO;
|
bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO;
|
||||||
|
|
||||||
tasklet_init(&bnad->tx_free_tasklet, bnad_tx_free_tasklet,
|
|
||||||
(unsigned long)bnad);
|
|
||||||
|
|
||||||
sprintf(bnad->wq_name, "%s_wq_%d", BNAD_NAME, bnad->id);
|
sprintf(bnad->wq_name, "%s_wq_%d", BNAD_NAME, bnad->id);
|
||||||
bnad->work_q = create_singlethread_workqueue(bnad->wq_name);
|
bnad->work_q = create_singlethread_workqueue(bnad->wq_name);
|
||||||
|
|
||||||
|
@ -3345,7 +3279,6 @@ bnad_pci_probe(struct pci_dev *pdev,
|
||||||
/*
|
/*
|
||||||
* Initialize bnad structure
|
* Initialize bnad structure
|
||||||
* Setup relation between pci_dev & netdev
|
* Setup relation between pci_dev & netdev
|
||||||
* Init Tx free tasklet
|
|
||||||
*/
|
*/
|
||||||
err = bnad_init(bnad, pdev, netdev);
|
err = bnad_init(bnad, pdev, netdev);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -320,7 +320,6 @@ struct bnad {
|
||||||
/* Burnt in MAC address */
|
/* Burnt in MAC address */
|
||||||
mac_t perm_addr;
|
mac_t perm_addr;
|
||||||
|
|
||||||
struct tasklet_struct tx_free_tasklet;
|
|
||||||
struct workqueue_struct *work_q;
|
struct workqueue_struct *work_q;
|
||||||
|
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
|
|
Loading…
Reference in New Issue