diff mbox

[v2.6.29,v3,5/5] gianfar: Continue polling until both tx and rx are empty

Message ID 1229550175-15600-5-git-send-email-afleming@freescale.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Andy Fleming Dec. 17, 2008, 9:42 p.m. UTC
gfar_poll would declare polling done once the rx queue was empty,
but the tx queue could still have packets left.

Stolen mostly from the e1000 driver.

Signed-off-by: Andy Fleming <afleming@freescale.com>
---
 drivers/net/gianfar.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

Comments

David Miller Dec. 18, 2008, 12:54 a.m. UTC | #1
From: Andy Fleming <afleming@freescale.com>
Date: Wed, 17 Dec 2008 15:42:55 -0600

> gfar_poll would declare polling done once the rx queue was empty,
> but the tx queue could still have packets left.
> 
> Stolen mostly from the e1000 driver.
> 
> Signed-off-by: Andy Fleming <afleming@freescale.com>

Applied.

But I absolutely do not recommend this polling technique at all.

The best scheme is to first purge your TX ring completely, and do not
apply any quota to this work.  It's relatively cheap and batches well.

Then, you process the RX ring and apply the quota only to the RX ring
work.

This is what every NAPI driver I've written does and it gives the best
results.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andy Fleming Dec. 18, 2008, 2:40 a.m. UTC | #2
On Dec 17, 2008, at 18:55, "David Miller" <davem@davemloft.net> wrote:

> From: Andy Fleming <afleming@freescale.com>
> Date: Wed, 17 Dec 2008 15:42:55 -0600
>
>> gfar_poll would declare polling done once the rx queue was empty,
>> but the tx queue could still have packets left.
>>
>> Stolen mostly from the e1000 driver.
>>
>> Signed-off-by: Andy Fleming <afleming@freescale.com>
>
> Applied.
>
> But I absolutely do not recommend this polling technique at all.
>
> The best scheme is to first purge your TX ring completely, and do not
> apply any quota to this work.  It's relatively cheap and batches well.
>
> Then, you process the RX ring and apply the quota only to the RX ring
> work.
>
> This is what every NAPI driver I've written does and it gives the best
> results.

I agree it seems a bit screwy, but I got a 4-5% performance increase.   
It may just require better tuning of my tx coalescing parameters-I was  
getting 7x the number of tx irqs as rx.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Dec. 18, 2008, 2:44 a.m. UTC | #3
From: "Fleming Andy-AFLEMING" <afleming@freescale.com>
Date: Wed, 17 Dec 2008 20:40:20 -0600

> It may just require better tuning of my tx coalescing parameters-I
> was getting 7x the number of tx irqs as rx.

It's hard to decrease TX irqs, but yes some tuning in that area
might help.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 939e38c..144f941 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1843,7 +1843,8 @@  static int gfar_poll(struct napi_struct *napi, int budget)
 {
 	struct gfar_private *priv = container_of(napi, struct gfar_private, napi);
 	struct net_device *dev = priv->dev;
-	int howmany;
+	int tx_cleaned = 0;
+	int rx_cleaned = 0;
 	unsigned long flags;
 
 	/* Clear IEVENT, so interrupts aren't called again
@@ -1852,13 +1853,16 @@  static int gfar_poll(struct napi_struct *napi, int budget)
 
 	/* If we fail to get the lock, don't bother with the TX BDs */
 	if (spin_trylock_irqsave(&priv->txlock, flags)) {
-		gfar_clean_tx_ring(dev);
+		tx_cleaned = gfar_clean_tx_ring(dev);
 		spin_unlock_irqrestore(&priv->txlock, flags);
 	}
 
-	howmany = gfar_clean_rx_ring(dev, budget);
+	rx_cleaned = gfar_clean_rx_ring(dev, budget);
 
-	if (howmany < budget) {
+	if (tx_cleaned)
+		return budget;
+
+	if (rx_cleaned < budget) {
 		netif_rx_complete(dev, napi);
 
 		/* Clear the halt bit in RSTAT */
@@ -1878,7 +1882,7 @@  static int gfar_poll(struct napi_struct *napi, int budget)
 		}
 	}
 
-	return howmany;
+	return rx_cleaned;
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER