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

Commit d95d1081 authored by Jing Huang's avatar Jing Huang Committed by David S. Miller
Browse files

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: default avatarJing Huang <huangj@brocade.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 01b54b14
Loading
Loading
Loading
Loading
+3 −70
Original line number Original line Diff line number Diff line
@@ -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)
+0 −1
Original line number Original line Diff line number Diff line
@@ -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 */