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

[Xen-devel] [Fwd: [Xen-changelog] Plumb network vif credit-based rate limiting thorugh xenbus]


  • To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: Nivedita Singhvi <niv@xxxxxxxxxx>
  • Date: Fri, 31 Mar 2006 09:13:14 -0800
  • Delivery-date: Fri, 31 Mar 2006 17:15:14 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

Hi Keir,

I don't mean to pick on any one patch, so my apologies
to the authors of the most excellent patch below :)...

However, is this a good time for inclusion of such features?
I thought we were trying to put 3.0.2 out any day now?
We got bit by a few somewhat harmless changes (like moving
the default to -xen), so I was really hoping to see commits
limited to the absolutely necessary bug fixes.

Not sure if Novell has already picked up for their upcoming
rebase for SLES10, but 3.0.2 release stability should be
a goal in it's own right as well, I think.

thanks,
Nivedita

-------- Original Message --------
Subject: [Xen-changelog] Plumb network vif credit-based rate limiting   thorugh 
xenbus
Date: Fri, 31 Mar 2006 17:04:09 +0000
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Reply-To: xen-devel@xxxxxxxxxxxxxxxxxxx
To: xen-changelog@xxxxxxxxxxxxxxxxxxx

# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID dadadf9aeee713bbe2f8dc040a74f7cea2223f41
# Parent  2769a38f0e3e7ab544293833276a5d8cd0875483
Plumb network vif credit-based rate limiting thorugh xenbus
and xend into xm guest config files.

A new vif parameter 'rate' is supported, with an optional time window
paremeter for specifying granularity of credit replenishment. The default
window is 50ms. For example:

 'rate=10Mb/s'  'rate=250KB/s'  'rate=1MB/s@20ms'

From: Chris Clark <christopher.w.clark@xxxxxxxxx>

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

diff -r 2769a38f0e3e -r dadadf9aeee7 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Mar 31 12:51:19 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Mar 31 14:34:52 2006
@@ -97,7 +97,6 @@
 #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)

-void netif_creditlimit(netif_t *netif);
 void netif_disconnect(netif_t *netif);

 netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
diff -r 2769a38f0e3e -r dadadf9aeee7 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Mar 31 
12:51:19 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Mar 31 
14:34:52 2006
@@ -291,25 +291,6 @@
 {
        INIT_WORK(&netif->free_work, free_netif_callback, (void *)netif);
        schedule_work(&netif->free_work);
-}
-
-void netif_creditlimit(netif_t *netif)
-{
-#if 0
-       /* Set the credit limit (reset remaining credit to new limit). */
-       netif->credit_bytes     = creditlimit->credit_bytes;
-       netif->remaining_credit = creditlimit->credit_bytes;
-       netif->credit_usec      = creditlimit->period_usec;
-
-       if (netif->status == CONNECTED) {
-               /*
-                * Schedule work so that any packets waiting under previous
-                * credit limit are dealt with (acts as a replenishment point).
-                */
-               netif->credit_timeout.expires = jiffies;
-               netif_schedule_work(netif);
-       }
-#endif
 }

 void netif_disconnect(netif_t *netif)
diff -r 2769a38f0e3e -r dadadf9aeee7 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Mar 31 12:51:19 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Mar 31 14:34:52 2006
@@ -233,9 +233,44 @@

 static void maybe_connect(struct backend_info *be)
 {
-       if (be->netif != NULL && be->frontend_state == XenbusStateConnected) {
+       if (be->netif && (be->frontend_state == XenbusStateConnected))
                connect(be);
-       }
+}
+
+static void xen_net_read_rate(struct xenbus_device *dev,
+                             unsigned long *bytes, unsigned long *usec)
+{
+       char *s, *e;
+       unsigned long b, u;
+       char *ratestr;
+
+       /* Default to unlimited bandwidth. */
+       *bytes = ~0UL;
+       *usec = 0;
+
+       ratestr = xenbus_read(XBT_NULL, dev->nodename, "rate", NULL);
+       if (IS_ERR(ratestr))
+               return;
+
+       s = ratestr;
+       b = simple_strtoul(s, &e, 10);
+       if ((s == e) || (*e != ','))
+               goto fail;
+
+       s = e + 1;
+       u = simple_strtoul(s, &e, 10);
+       if ((s == e) || (*e != '\0'))
+               goto fail;
+
+       *bytes = b;
+       *usec = u;
+
+       kfree(ratestr);
+       return;
+
+ fail:
+       WPRINTK("Failed to parse network rate limit. Traffic unlimited.\n");
+       kfree(ratestr);
 }


@@ -253,6 +288,10 @@
                xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
                return;
        }
+
+       xen_net_read_rate(dev, &be->netif->credit_bytes,
+                         &be->netif->credit_usec);
+       be->netif->remaining_credit = be->netif->credit_bytes;

        xenbus_switch_state(dev, XenbusStateConnected);
 }
diff -r 2769a38f0e3e -r dadadf9aeee7 tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Fri Mar 31 12:51:19 2006
+++ b/tools/python/xen/xend/server/netif.py     Fri Mar 31 14:34:52 2006
@@ -22,6 +22,7 @@

 import os
 import random
+import re

 from xen.xend import sxp
 from xen.xend import XendRoot
@@ -50,6 +51,86 @@
             random.randint(0x00, 0xff) ]
     return ':'.join(map(lambda x: "%02x" % x, mac))

+rate_re = re.compile("^([0-9]+)([GMK]?)([Bb])/s(@([0-9]+)([mu]?)s)?$")
+
+def parseRate(ratestr):
+    """if parsing fails this will return default of unlimited rate"""
+    bytes_per_interval = 0xffffffffL # 0xffffffff # big default
+    interval_usecs     = 0L          # disabled
+
+    m = rate_re.match(ratestr)
+    if m:
+        bytes_per_sec = long(m.group(1))
+
+        if m.group(2) == 'G':
+            bytes_per_sec *= 1000 * 1000 * 1000
+        elif m.group(2) == 'M':
+            bytes_per_sec *= 1000 * 1000
+        elif m.group(2) == 'K':
+            bytes_per_sec *= 1000
+
+        if m.group(3) == 'b':
+            bytes_per_sec /= 8
+
+        if m.group(5) is None:
+            interval_usecs = 50000L      # 50ms default
+        else:
+            interval_usecs = long(m.group(5))
+            if m.group(6) == '':
+                interval_usecs *= 1000 * 1000
+            elif m.group(6) == 'm':
+                interval_usecs *= 1000
+
+        bytes_per_interval = (bytes_per_sec * interval_usecs) / 1000000L
+
+        # overflow / underflow checking: default to unlimited rate
+        if bytes_per_interval == 0 or bytes_per_interval > 0xffffffffL or \
+           interval_usecs == 0 or interval_usecs > 0xffffffffL:
+            bytes_per_interval = 0xffffffffL
+            interval_usecs     = 0L
+
+    return "%lu,%lu" % (bytes_per_interval, interval_usecs)
+
+
+write_rate_G_re = re.compile('^([0-9]+)000000000(B/s@[0-9]+us)$')
+write_rate_M_re = re.compile('^([0-9]+)000000(B/s@[0-9]+us)$')
+write_rate_K_re = re.compile('^([0-9]+)000(B/s@[0-9]+us)$')
+write_rate_s_re = re.compile('^([0-9]+[GMK]?B/s@[0-9]+)000000us$')
+write_rate_m_re = re.compile('^([0-9]+[GMK]?B/s@[0-9]+)000us$')
+
+def formatRate(rate):
+    (bytes_per_interval, interval_usecs) = map(long, rate.split(','))
+
+    if interval_usecs != 0:
+        bytes_per_second = (bytes_per_interval * 1000 * 1000) / interval_usecs
+    else:
+        bytes_per_second = 0xffffffffL
+
+    ratestr = "%uB/s@%uus" % (bytes_per_second, interval_usecs)
+
+    # look for '000's
+    m = write_rate_G_re.match(ratestr)
+    if m:
+        ratestr = m.group(1) + "G" + m.group(2)
+    else:
+        m = write_rate_M_re.match(ratestr)
+        if m:
+            ratestr = m.group(1) + "M" + m.group(2)
+        else:
+            m = write_rate_K_re.match(ratestr)
+            if m:
+                ratestr = m.group(1) + "K" + m.group(2)
+
+    m = write_rate_s_re.match(ratestr)
+    if m:
+        ratestr = m.group(1) + "s"
+    else:
+        m = write_rate_m_re.match(ratestr)
+        if m:
+            ratestr = m.group(1) + "ms"
+
+    return ratestr
+

 class NetifController(DevController):
     """Network interface controller. Handles all network devices for a domain.
@@ -75,6 +156,7 @@
         bridge  = sxp.child_value(config, 'bridge')
         mac     = sxp.child_value(config, 'mac')
         vifname = sxp.child_value(config, 'vifname')
+        rate    = sxp.child_value(config, 'rate')
         ipaddr  = _get_config_ipaddr(config)

         devid = self.allocateDeviceID()
@@ -98,6 +180,8 @@
             back['bridge'] = bridge
         if vifname:
             back['vifname'] = vifname
+        if rate:
+            back['rate'] = parseRate(rate)

         return (devid, back, front)

@@ -107,8 +191,8 @@

         result = DevController.configuration(self, devid)

-        (script, ip, bridge, mac, typ, vifname) = self.readBackend(
-            devid, 'script', 'ip', 'bridge', 'mac', 'type', 'vifname')
+        (script, ip, bridge, mac, typ, vifname, rate) = self.readBackend(
+            devid, 'script', 'ip', 'bridge', 'mac', 'type', 'vifname', 'rate')

         if script:
             result.append(['script',
@@ -125,5 +209,7 @@
             result.append(['type', typ])
         if vifname:
             result.append(['vifname', vifname])
+        if rate:
+            result.append(['rate', formatRate(rate)])

         return result
diff -r 2769a38f0e3e -r dadadf9aeee7 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Fri Mar 31 12:51:19 2006
+++ b/tools/python/xen/xm/create.py     Fri Mar 31 14:34:52 2006
@@ -552,7 +552,7 @@

         def f(k):
             if k not in ['backend', 'bridge', 'ip', 'mac', 'script', 'type',
-                         'vifname']:
+                         'vifname', 'rate']:
                 err('Invalid vif option: ' + k)

             config_vif.append([k, d[k]])

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

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


 


Rackspace

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