]> xenbits.xensource.com Git - people/pauldu/mini-os.git/commitdiff
Mini-OS: netfront: Fix rx ring starvation in network_rx
authorMartin Lucina <martin@lucina.net>
Thu, 4 Dec 2014 13:33:53 +0000 (14:33 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Tue, 13 Jan 2015 10:40:28 +0000 (10:40 +0000)
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.

Further, we make the HAVE_LIBC codepath clearer to follow by removing
the "some" variable from the for loop initialisation and conditions.

Signed-off-by: Martin Lucina <martin@lucina.net>
Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
netfront.c

index 44c39959e6351324af69888b73863c764a69b03c..42bb1034587906ef83f1c5f391db80e544abcf30 100644 (file)
@@ -96,42 +96,35 @@ static inline int xennet_rxidx(RING_IDX idx)
 void network_rx(struct netfront_dev *dev)
 {
     RING_IDX rp,cons,req_prod;
-    struct netif_rx_response *rx;
-    int nr_consumed, some, more, i, notify;
-
+    int nr_consumed, more, i, notify;
+#ifdef HAVE_LIBC
+    int some;
+#endif
 
+    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;
-         nr_consumed++, cons++)
+#ifdef HAVE_LIBC
+    some = 0;
+#endif
+    for (cons = dev->rx.rsp_cons; cons != rp; nr_consumed++, cons++)
     {
         struct net_buffer* buf;
         unsigned char* page;
         int id;
 
-        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;
+        struct netif_rx_response *rx = RING_GET_RESPONSE(&dev->rx, cons);
 
         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;
         gnttab_end_access(buf->gref);
 
-        if(rx->status>0)
+        if (rx->status > NETIF_RSP_NULL)
         {
 #ifdef HAVE_LIBC
            if (dev->netif_rx == NETIF_SELECT_RX) {
@@ -142,6 +135,7 @@ moretodo:
                memcpy(dev->data, page+rx->offset, len);
                dev->rlen = len;
                some = 1;
+                break;
            } else
 #endif
                dev->netif_rx(page+rx->offset,rx->status);
@@ -150,7 +144,11 @@ moretodo:
     dev->rx.rsp_cons=cons;
 
     RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx,more);
+#ifdef HAVE_LIBC
     if(more && !some) goto moretodo;
+#else
+    if(more) goto moretodo;
+#endif
 
     req_prod = dev->rx.req_prod_pvt;