[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |