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] Add a /proc interface for setting rx-buffer allocation p

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Add a /proc interface for setting rx-buffer allocation policy in
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Tue, 03 May 2005 10:54:00 +0000
Delivery-date: Tue, 03 May 2005 11:03:26 +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 Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1844, 2005/05/03 11:54:00+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Add a /proc interface for setting rx-buffer allocation policy in
        the netfront driver.
        e.g., 'echo 256 >/proc/xen/net/eth0/rxbuf_min' will avoid unnecessary
        packet drops by always allocating the maximum possible number of
        buffers at all times, at the expense of extra memory usage when the
        interface is idle.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 netfront.c |  185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 177 insertions(+), 8 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c 
b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c   2005-05-03 
07:03:53 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c   2005-05-03 
07:03:53 -04:00
@@ -39,6 +39,7 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/proc_fs.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
@@ -85,6 +86,16 @@
 static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1];
 static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
 
+#ifdef CONFIG_PROC_FS
+static int xennet_proc_init(void);
+static int xennet_proc_addif(struct net_device *dev);
+static void xennet_proc_delif(struct net_device *dev);
+#else
+#define xennet_proc_init()   (0)
+#define xennet_proc_addif(d) (0)
+#define xennet_proc_delif(d) ((void)0)
+#endif
+
 static struct list_head dev_list;
 
 struct net_private
@@ -120,7 +131,7 @@
     /* Receive-ring batched refills. */
 #define RX_MIN_TARGET 8
 #define RX_MAX_TARGET NETIF_RX_RING_SIZE
-    int rx_target;
+    int rx_min_target, rx_max_target, rx_target;
     struct sk_buff_head rx_batch;
 
     /*
@@ -419,8 +430,8 @@
 
     /* 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) > RX_MAX_TARGET))
-        np->rx_target = RX_MAX_TARGET;
+         ((np->rx_target *= 2) > np->rx_max_target))
+        np->rx_target = np->rx_max_target;
 }
 
 
@@ -651,8 +662,8 @@
     /* If we get a callback with very few responses, reduce fill target. */
     /* NB. Note exponential increase, linear decrease. */
     if (((np->rx->req_prod - np->rx->resp_prod) > ((3*np->rx_target) / 4)) &&
-         (--np->rx_target < RX_MIN_TARGET))
-        np->rx_target = RX_MIN_TARGET;
+         (--np->rx_target < np->rx_min_target))
+        np->rx_target = np->rx_min_target;
 
     network_alloc_rx_buffers(dev);
 
@@ -943,7 +954,9 @@
     spin_lock_init(&np->rx_lock);
 
     skb_queue_head_init(&np->rx_batch);
-    np->rx_target = RX_MIN_TARGET;
+    np->rx_target     = RX_MIN_TARGET;
+    np->rx_min_target = RX_MIN_TARGET;
+    np->rx_max_target = RX_MAX_TARGET;
 
     /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
     for (i = 0; i <= NETIF_TX_RING_SIZE; i++)
@@ -962,11 +975,17 @@
         printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
         goto exit;
     }
+
+    if ((err = xennet_proc_addif(dev)) != 0) {
+        unregister_netdev(dev);
+        goto exit;
+    }
+
     np->dev = dev;
     list_add(&np->list, &dev_list);
 
   exit:
-    if ((err != 0) && (dev != NULL ))
+    if ((err != 0) && (dev != NULL))
         kfree(dev);
     else if (val != NULL)
         *val = dev;
@@ -1248,6 +1267,9 @@
     if (xen_start_info.flags & SIF_INITDOMAIN)
         return 0;
 
+    if ((err = xennet_proc_init()) != 0)
+        return err;
+
     IPRINTK("Initialising virtual ethernet driver.\n");
     INIT_LIST_HEAD(&dev_list);
     (void)register_inetaddr_notifier(&notifier_inetdev);
@@ -1305,6 +1327,153 @@
     }
 }
 
+#ifdef CONFIG_PROC_FS
 
-module_init(netif_init);
+#define TARGET_MIN 0UL
+#define TARGET_MAX 1UL
+#define TARGET_CUR 2UL
+
+static int xennet_proc_read(
+    char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+    struct net_device *dev = (struct net_device *)((unsigned long)data & ~3UL);
+    struct net_private *np = netdev_priv(dev);
+    int len = 0, which_target = (int)data & 3;
+    
+    switch (which_target)
+    {
+    case TARGET_MIN:
+        len = sprintf(page, "%d\n", np->rx_min_target);
+        break;
+    case TARGET_MAX:
+        len = sprintf(page, "%d\n", np->rx_max_target);
+        break;
+    case TARGET_CUR:
+        len = sprintf(page, "%d\n", np->rx_target);
+        break;
+    }
+
+    *eof = 1;
+    return len;
+}
+
+static int xennet_proc_write(
+    struct file *file, const char __user *buffer,
+    unsigned long count, void *data)
+{
+    struct net_device *dev = (struct net_device *)((unsigned long)data & ~3UL);
+    struct net_private *np = netdev_priv(dev);
+    int which_target = (int)data & 3;
+    char string[64];
+    long target;
+
+    if (!capable(CAP_SYS_ADMIN))
+        return -EPERM;
+
+    if (count <= 1)
+        return -EBADMSG; /* runt */
+    if (count > sizeof(string))
+        return -EFBIG;   /* too long */
+
+    if (copy_from_user(string, buffer, count))
+        return -EFAULT;
+    string[sizeof(string)-1] = '\0';
+
+    target = simple_strtol(string, NULL, 10);
+    if (target < RX_MIN_TARGET)
+        target = RX_MIN_TARGET;
+    if (target > RX_MAX_TARGET)
+        target = RX_MAX_TARGET;
+
+    spin_lock(&np->rx_lock);
+
+    switch (which_target)
+    {
+    case TARGET_MIN:
+        if (target > np->rx_max_target)
+            np->rx_max_target = target;
+        np->rx_min_target = target;
+        if (target > np->rx_target)
+            np->rx_target = target;
+        break;
+    case TARGET_MAX:
+        if (target < np->rx_min_target)
+            np->rx_min_target = target;
+        np->rx_max_target = target;
+        if (target < np->rx_target)
+            np->rx_target = target;
+        break;
+    case TARGET_CUR:
+        break;
+    }
 
+    network_alloc_rx_buffers(dev);
+
+    spin_unlock(&np->rx_lock);
+
+    return count;
+}
+
+static int xennet_proc_init(void)
+{
+    if (proc_mkdir("xen/net", NULL) == NULL)
+        return -ENOMEM;
+    return 0;
+}
+
+static int xennet_proc_addif(struct net_device *dev)
+{
+    struct proc_dir_entry *dir, *min, *max, *cur;
+    char name[30];
+
+    sprintf(name, "xen/net/%s", dev->name);
+
+    dir = proc_mkdir(name, NULL);
+    if (!dir)
+        goto nomem;
+
+    min = create_proc_entry("rxbuf_min", 0644, dir);
+    max = create_proc_entry("rxbuf_max", 0644, dir);
+    cur = create_proc_entry("rxbuf_cur", 0444, dir);
+    if (!min || !max || !cur)
+        goto nomem;
+
+    min->read_proc  = xennet_proc_read;
+    min->write_proc = xennet_proc_write;
+    min->data       = (void *)((unsigned long)dev | TARGET_MIN);
+
+    max->read_proc  = xennet_proc_read;
+    max->write_proc = xennet_proc_write;
+    max->data       = (void *)((unsigned long)dev | TARGET_MAX);
+
+    cur->read_proc  = xennet_proc_read;
+    cur->write_proc = xennet_proc_write;
+    cur->data       = (void *)((unsigned long)dev | TARGET_CUR);
+
+    return 0;
+
+ nomem:
+    xennet_proc_delif(dev);
+    return -ENOMEM;
+}
+
+static void xennet_proc_delif(struct net_device *dev)
+{
+    char name[30];
+
+    sprintf(name, "xen/net/%s/rxbuf_min", dev->name);
+    remove_proc_entry(name, NULL);
+
+    sprintf(name, "xen/net/%s/rxbuf_max", dev->name);
+    remove_proc_entry(name, NULL);
+
+    sprintf(name, "xen/net/%s/rxbuf_cur", dev->name);
+    remove_proc_entry(name, NULL);
+
+    sprintf(name, "xen/net/%s", dev->name);
+    remove_proc_entry(name, NULL);
+}

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

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