All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nivedita Singhvi <niv@us.ibm.com>
To: xen-devel <xen-devel@lists.xensource.com>
Subject: [Fwd: [Xen-changelog] Plumb network vif credit-based rate limiting thorugh xenbus]
Date: Fri, 31 Mar 2006 09:13:14 -0800	[thread overview]
Message-ID: <442D632A.7040002@us.ibm.com> (raw)

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

                 reply	other threads:[~2006-03-31 17:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=442D632A.7040002@us.ibm.com \
    --to=niv@us.ibm.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.