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

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



# 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


 


Rackspace

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