[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3 of 4] xl: add support for vif rate limiting
On Tue, 20 Mar 2012, Mathieu Gagnà wrote: > The `rate` parameter specifies the rate at which the outgoing traffic > will be limited to. This defaults to unlimited. > > The `rate` keyword supports an optional time window parameter for specifying > the granularity of credit replenishment. It determines the frequency at which > the vif transmission credit is replenished. The default window is 50ms. > > For example: > > 'rate=10Mb/s' > 'rate=250KB/s' > 'rate=1MB/s@20ms' > > Signed-off-by: Mathieu Gagnà <mgagne@xxxxxxxx> > > diff --git a/docs/misc/xl-network-configuration.markdown > b/docs/misc/xl-network-configuration.markdown > --- a/docs/misc/xl-network-configuration.markdown > +++ b/docs/misc/xl-network-configuration.markdown > @@ -122,5 +122,21 @@ Specifies the backend domain which this > defaults to domain 0. Specifying another domain requires setting up a > driver domain which is outside the scope of this document. > > +### rate > + > +Specifies the rate at which the outgoing traffic will be limited to. This > +defaults to unlimited. > + > +The `rate` keyword supports an optional time window parameter for specifying > +the granularity of credit replenishment. It determines the frequency at which > +the vif transmission credit is replenished. The default window is 50ms. > + > +For example: > + > + 'rate=10Mb/s' > + 'rate=250KB/s' > + 'rate=1MB/s@20ms' > + > + > [oui]: http://en.wikipedia.org/wiki/Organizationally_Unique_Identifier > [net]: http://wiki.xen.org/wiki/HostConfiguration/Networking > diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile > --- a/tools/libxl/Makefile > +++ b/tools/libxl/Makefile > @@ -57,7 +57,7 @@ LIBXL_OBJS += _libxl_types.o libxl_flask > AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h _libxl_list.h > AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c > LIBXLU_OBJS = libxlu_cfg_y.o libxlu_cfg_l.o libxlu_cfg.o \ > - libxlu_disk_l.o libxlu_disk.o > + libxlu_disk_l.o libxlu_disk.o libxlu_vif.o > $(LIBXLU_OBJS): CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h > > CLIENTS = xl testidl > diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c > --- a/tools/libxl/libxl.c > +++ b/tools/libxl/libxl.c > @@ -1834,6 +1834,13 @@ int libxl_device_nic_add(libxl_ctx *ctx, > flexarray_append(back, libxl__strdup(gc, nic->ip)); > } > > + if (nic->rate_interval_usecs > 0) { > + flexarray_append(back, "rate"); > + flexarray_append(back, libxl__sprintf(gc, "%u,%u", > + nic->rate_bytes_per_interval, > + nic->rate_interval_usecs)); > + } > + > flexarray_append(back, "bridge"); > flexarray_append(back, libxl__strdup(gc, nic->bridge)); > flexarray_append(back, "handle"); > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl > --- a/tools/libxl/libxl_types.idl > +++ b/tools/libxl/libxl_types.idl > @@ -341,6 +341,8 @@ libxl_device_nic = Struct("device_nic", > ("ifname", string), > ("script", string), > ("nictype", libxl_nic_type), > + ("rate_bytes_per_interval", uint32), > + ("rate_interval_usecs", uint32), > ]) > > libxl_device_pci = Struct("device_pci", [ > diff --git a/tools/libxl/libxlu_internal.h b/tools/libxl/libxlu_internal.h > --- a/tools/libxl/libxlu_internal.h > +++ b/tools/libxl/libxlu_internal.h > @@ -17,9 +17,11 @@ > #define LIBXLU_INTERNAL_H > > #include <stdio.h> > +#include <stdlib.h> > #include <errno.h> > #include <string.h> > #include <assert.h> > +#include <regex.h> > > #define XLU_ConfigList XLU_ConfigSetting > > diff --git a/tools/libxl/libxlu_vif.c b/tools/libxl/libxlu_vif.c > new file mode 100644 > --- /dev/null > +++ b/tools/libxl/libxlu_vif.c > @@ -0,0 +1,91 @@ > +#include "libxl_osdeps.h" /* must come before any other headers */ > +#include "libxlu_internal.h" > + > +static const char *vif_bytes_per_sec_re = "^([0-9]+)([GMK]?)([Bb])/s$"; > +static const char *vif_internal_usec_re = "^([0-9]+)([mu]?)s?$"; > + > +static void vif_parse_rate_bytes_per_sec(const char *bytes, uint32_t > *bytes_per_sec) > +{ > + regex_t rec; > + uint64_t tmp_bytes_per_sec = 0; > + > + regcomp(&rec, vif_bytes_per_sec_re, REG_EXTENDED); > + if (regexec(&rec, bytes, 0, NULL, 0) == 0) { > + const char *p = bytes; > + tmp_bytes_per_sec = strtoul(p, (char**)&p, 0); > + if (*p == 'G' || *p == '\0') > + tmp_bytes_per_sec *= 1000 * 1000 * 1000; > + else if (*p == 'M') > + tmp_bytes_per_sec *= 1000 * 1000; > + else if (*p == 'K') > + tmp_bytes_per_sec *= 1000; > + if (*p == 'b' || *(p+1) == 'b') > + tmp_bytes_per_sec /= 8; > + } > + regfree(&rec); > + > + if (tmp_bytes_per_sec > UINT32_MAX || tmp_bytes_per_sec == 0) > + tmp_bytes_per_sec = UINT32_MAX; > + *bytes_per_sec = tmp_bytes_per_sec; > +} > + > +static void vif_parse_rate_interval_usecs(const char *interval, > + uint32_t *interval_usecs) > +{ > + regex_t rec; > + uint64_t tmp_interval_usecs = 0; > + > + regcomp(&rec, vif_internal_usec_re, REG_EXTENDED); > + if (regexec(&rec, interval, 0, NULL, 0) == 0) { > + const char *p = interval; > + tmp_interval_usecs = strtoul(p, (char**)&p, 10); > + if (*p == 's' || *p == '\0') > + tmp_interval_usecs *= 1000 * 1000; > + else if (*p == 'm') > + tmp_interval_usecs *= 1000; > + } > + regfree(&rec); > + > + if (tmp_interval_usecs > UINT32_MAX || tmp_interval_usecs == 0) > + tmp_interval_usecs = UINT32_MAX; > + *interval_usecs = tmp_interval_usecs; > +} > + > +void xlu_vif_parse_rate(const char *rate, uint32_t *bytes_per_interval, > + uint32_t *interval_usecs) > +{ > + uint32_t bytes_per_sec = 0; > + uint64_t tmp_bytes_per_interval = 0; > + char *tmprate, *ratetok; > + > + tmprate = strdup(rate); > + > + ratetok = strtok(tmprate, "@"); > + vif_parse_rate_bytes_per_sec(ratetok, &bytes_per_sec); > + > + ratetok = strtok(NULL, "@"); > + if (ratetok != NULL) > + vif_parse_rate_interval_usecs(ratetok, interval_usecs); > + else > + *interval_usecs = 50000; /* Default to 50ms */ > + > + free(tmprate); > + > + tmp_bytes_per_interval = > + (((uint64_t) bytes_per_sec * (uint64_t) *interval_usecs) / 1000000L); > + > + /* overflow checking: default to unlimited rate */ > + if ((tmp_bytes_per_interval == 0) || (tmp_bytes_per_interval > > UINT32_MAX)) { > + tmp_bytes_per_interval = UINT32_MAX; > + *interval_usecs = 0; > + } > + *bytes_per_interval = tmp_bytes_per_interval; > +} wouldn't it make sense to just use a uint64_t for rate_bytes_per_interval and rate_interval_usecs? _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |