Nivedita Singhvi
2006-Mar-31 17:13 UTC
[Xen-devel] [Fwd: [Xen-changelog] Plumb network vif credit-based rate limiting thorugh xenbus]
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@lists.xensource.com> Reply-To: xen-devel@lists.xensource.com To: xen-changelog@lists.xensource.com # HG changeset patch # User kaf24@firebug.cl.cam.ac.uk # 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@gmail.com> Signed-off-by: Keir Fraser <keir@xensource.com> 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@lists.xensource.com http://lists.xensource.com/xen-changelog _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel