WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] If netfront fails to allocate a receive skbuff, push all

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] If netfront fails to allocate a receive skbuff, push all pending
From: Xen patchbot -2.0-testing <patchbot-2.0-testing@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 28 Dec 2005 12:00:09 +0000
Delivery-date: Wed, 28 Dec 2005 12:04:20 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 3e0f4fe2281080cda9205e49de0d5f77f0d9d87f
# Parent  013eab60cb78455fb602d99866e0cba8846bc244
If netfront fails to allocate a receive skbuff, push all pending
skbuffs out onto the shared ring. If there are no skbuffs to push,
schedule a timer to try again later. This will avoid interface
lockups in low-memory conditions.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 013eab60cb78 -r 3e0f4fe22810 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Dec 27 
10:18:42 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Dec 28 
11:57:18 2005
@@ -135,6 +135,8 @@
     int rx_min_target, rx_max_target, rx_target;
     struct sk_buff_head rx_batch;
 
+    struct timer_list rx_refill_timer;
+
     /*
      * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
      * array is an index into a chain of free entries.
@@ -347,6 +349,13 @@
 }
 
 
+static void rx_refill_timeout(unsigned long data)
+{
+    struct net_device *dev = (struct net_device *)data;
+    netif_rx_schedule(dev);
+}
+
+
 static void network_alloc_rx_buffers(struct net_device *dev)
 {
     unsigned short id;
@@ -366,8 +375,14 @@
      */
     batch_target = np->rx_target - (req_prod - np->rx_resp_cons);
     for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
-        if (unlikely((skb = alloc_xen_skb(dev->mtu + RX_HEADROOM)) == NULL))
-            break;
+        if (unlikely((skb = alloc_xen_skb(dev->mtu + RX_HEADROOM)) == NULL)) {
+            /* Any skbuffs queued for refill? Force them out. */
+            if (i != 0)
+                goto refill;
+            /* Could not allocate any skbuffs. Try again later. */
+            mod_timer(&np->rx_refill_timer, jiffies + (HZ/10));
+            return;
+        }
         __skb_queue_tail(&np->rx_batch, skb);
     }
 
@@ -375,6 +390,12 @@
     if (i < (np->rx_target/2))
         return;
 
+    /* Adjust our floating fill target if we risked running out of buffers. */
+    if (((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) &&
+         ((np->rx_target *= 2) > np->rx_max_target))
+        np->rx_target = np->rx_max_target;
+
+ refill:
     for (i = 0; ; i++) {
         if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
             break;
@@ -428,11 +449,6 @@
 
     /* Above is a suitable barrier to ensure backend will see requests. */
     np->rx->req_prod = req_prod + i;
-
-    /* Adjust our floating fill target if we risked running out of buffers. */
-    if (((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) &&
-         ((np->rx_target *= 2) > np->rx_max_target))
-        np->rx_target = np->rx_max_target;
 }
 
 
@@ -967,6 +983,10 @@
     np->rx_target     = RX_MIN_TARGET;
     np->rx_min_target = RX_MIN_TARGET;
     np->rx_max_target = RX_MAX_TARGET;
+ 
+    init_timer(&np->rx_refill_timer);
+    np->rx_refill_timer.data = (unsigned long)dev;
+    np->rx_refill_timer.function = rx_refill_timeout;
 
     /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
     for (i = 0; i <= NETIF_TX_RING_SIZE; i++)
@@ -1300,6 +1320,7 @@
     /* Avoid having tx/rx stuff happen until we're ready. */
     free_irq(np->irq, np->dev);
     unbind_evtchn_from_irq(np->evtchn);
+    del_timer_sync(&np->rx_refill_timer);
 }
 
 static void vif_resume(struct net_private *np)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>