[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] Mini-OS: netfront: Fix rx ring starvation in network_rx



Hi,

following is a patch against vanilla Mini-OS in upstream xen.git for a
problem we have found in the netfront driver. When subjected to load
network receive would freeze due to the rx ring running out of free
request slots.

With this patch a httpd running on rumprun-xen [1] survives all the load I
can throw at it.

Note that I have only compile-tested this patch against the upstream
Mini-OS. It also does not address the -DHAVE_LIBC codepath as I don't know
how to test that or if anyone is using that code?

Further, I would like to clean this function up; the code is an impossible
to follow mess. What I'd like to arrive at is at [2], however this also
needs(?) to address the -DHAVE_LIBC codepath.

Martin

[1] http://repo.rumpkernel.org/rumprun-xen and
https://github.com/mato/rump-mathopd
[2] https://gist.github.com/mato/512eb70f39565b030f73

----

In network_rx() we must push the same amount of requests back onto the
ring in the second loop that we consumed in the first loop. Otherwise
the ring will eventually starve itself of free request slots and no
packets will be delivered.

Signed-off-by: Martin Lucina <martin@xxxxxxxxxx>
---
 extras/mini-os/netfront.c |   17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/extras/mini-os/netfront.c b/extras/mini-os/netfront.c
index 44c3995..33afc9c 100644
--- a/extras/mini-os/netfront.c
+++ b/extras/mini-os/netfront.c
@@ -99,14 +99,14 @@ void network_rx(struct netfront_dev *dev)
     struct netif_rx_response *rx;
     int nr_consumed, some, more, i, notify;
 
-
+    nr_consumed = 0;
 moretodo:
     rp = dev->rx.sring->rsp_prod;
     rmb(); /* Ensure we see queued responses up to 'rp'. */
     cons = dev->rx.rsp_cons;
 
-    for (nr_consumed = 0, some = 0;
-         (cons != rp) && !some;
+    for (some = 0;
+         (cons != rp);
          nr_consumed++, cons++)
     {
         struct net_buffer* buf;
@@ -115,17 +115,8 @@ moretodo:
 
         rx = RING_GET_RESPONSE(&dev->rx, cons);
 
-        if (rx->flags & NETRXF_extra_info)
-        {
-            printk("+++++++++++++++++++++ we have extras!\n");
-            continue;
-        }
-
-
-        if (rx->status == NETIF_RSP_NULL) continue;
-
         id = rx->id;
-        BUG_ON(id >= NET_TX_RING_SIZE);
+        BUG_ON(id >= NET_RX_RING_SIZE);
 
         buf = &dev->rx_buffers[id];
         page = (unsigned char*)buf->page;
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.