[RFC] Bug on AT91 macb driver rx with high network traffic

Message ID assp.06594bc968.509BCD1F.8020902@sadel.it
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

matteo.fortini@sadel.it Nov. 8, 2012, 3:17 p.m.
We are testing the robustness of the driver with UDP packets of 
increasing length, up to the maximum allowed.

We have an UDP echo server listening on an port on the AT91 board, and 
we send to it increasing length UDP packets, waiting for the echo reply 
before sending the next one.
When packets get larghish, in the >40000 bytes range, we see that the 
server is not receiving packets anymore, so the client does not receive 
the reply and the test stops. Pinging the interface once resumes the 
test, meaning that the packet has been actually received, but the driver 
is waiting for an interrupt that is not coming.

We traced this down to slow/missing IRQ response, and we fixed it as in 
the following patch, which calls napi_reschedule() before leaving the 
polling loop if the loop condition is still valid at the end of the 
polling loop, as other net drivers appear to do.

We don't know if this is the perfectly right way to do it, and we'd like 
your opinion on this before submitting a proper patch.

I added the udp_server.c and udp_client.c softwares which may be useful.

Thank you in advance,
Matteo Fortini

sure we
                  * get notified when new packets arrive.



 From 2d8895022a0668f6a3c1112f15ebe471db1a471e Mon Sep 17 00:00:00 2001
From: Matteo Fortini <matteo.fortini@sadel.it>
Date: Thu, 8 Nov 2012 16:12:10 +0100
Subject: [PATCH] AT91 macb: Fix lost rx packets on high rx traffic

  drivers/net/ethernet/cadence/macb.c |    8 ++++++++
  1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/cadence/macb.c 
index 033064b..348a20f 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -522,8 +522,16 @@  static int macb_poll(struct napi_struct *napi, int 

         work_done = macb_rx(bp, budget);
         if (work_done < budget) {
+               u32 addr;

+               addr = bp->rx_ring[bp->rx_tail].addr;
+               if ((addr & MACB_BIT(RX_USED))) {
+                       netdev_warn(bp->dev, "poll: reschedule");
+                       napi_reschedule(napi);
+               }
                  * We've done what we can to clean the buffers. Make