[libvirt] [PATCH 1/4] networkAllocateActualDevice: Set QoS for bridgeless networks too
Eric Blake
eblake at redhat.com
Fri Jan 24 18:23:42 UTC 2014
On 01/23/2014 06:44 AM, Michal Privoznik wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1055484
>
> Currently, libvirt's XML schema of network allows QoS to be defined for
> every network even though it has no bridge. For instance:
>
> <network>
> <name>vdsm-no-bridge</name>
> <forward mode='passthrough'>
> <interface dev='em1.10'/>
> </forward>
> <bandwidth>
> <inbound average='1000' peak='5000' burst='1024'/>
> <outbound average='1000' burst='1024'/>
> </bandwidth>
> </network>
>
> The bandwidth limitations can be, however, applied even on such
> networks. In fact, they are gonna be applied on the interface that will
s/gonna/going to/
> be connected to the network on a domain startup. This approach, however,
> has one limitation. With bridged networks, there are two points where
> QoS can be set: bridge and domain interface. The lower limit of the two
> is enforced then. For instance, if the interface has 10Mbps average, but
> the network only 1Mbps, there's no way for interface to transmit packets
> faster than the 1Mbps limit. With two points this is enforced by kernel.
> With only one point, we must combine both QoS settings into one which is
> set afterwards. Look at virNetDevBandwidthMinimal() and you'll
> understand immediately what I mean.
>
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
> src/libvirt_private.syms | 1 +
> src/network/bridge_driver.c | 25 +++++++++++-
> src/util/virnetdevbandwidth.c | 88 +++++++++++++++++++++++++++++++++++++++++++
> src/util/virnetdevbandwidth.h | 6 +++
> 4 files changed, 118 insertions(+), 2 deletions(-)
>
>
> - if (bandwidth && virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth,
> - bandwidth) < 0)
> + /* For a bridgeless networks we must take into account any QoS set to them.
s/For a/For/
> +
> +static void
> +virNetDevBandwidthRateMinimal(virNetDevBandwidthRatePtr result,
> + virNetDevBandwidthRatePtr band1,
> + virNetDevBandwidthRatePtr band2)
> +{
> + if (!band1 || !band2) {
> + memcpy(result, band1 ? band1 : band2, sizeof(*result));
Isn't this a NULL deref if both band1 and band2 are NULL? [1]
> + return;
> + }
> +
> + /* We can't do a simple MIN() here, because zero value doesn't mean the
> + * narrowest limit, but and unset value. Hence we need symmetric F(a, b)
s/and/an/
> + * so that:
> + * F(a, 0) = F(0, a) = a; special corner case: F(0, 0) = 0
> + * F(a, b) = MIN(a, b) for a != 0 and b != 0
> + */
> +#define NON_ZERO_MIN(a, b) \
> + ((a) && (b) ? MIN(a, b) : (a) ? (a) : (b))
Nice.
> +virNetDevBandwidthMinimal(virNetDevBandwidthPtr *result,
> + virNetDevBandwidthPtr band1,
> + virNetDevBandwidthPtr band2)
> +{
> + int ret = -1;
> +
> + if (!band1 && !band2) {
> + /* Nothing to compute */
> + *result = NULL;
> + return 0;
> + }
[1] Ahh, nice, you never call the helper function with both sides NULL.
> +
> + if (!band1->in && !band2->in) {
> + /* nada */
> + } else {
This looks odd; I would use deMorgan's law and write it as a one-liner
condition instead of an awkward 3-line if/else:
if (band1->in || band2->in) {
> + if (VIR_ALLOC((*result)->in) < 0)
> + goto cleanup;
> +
> + virNetDevBandwidthRateMinimal((*result)->in, band1->in, band2->in);
> + }
> +
> + if (!band1->out && !band2->out) {
> + /* nada */
> + } else {
and again.
ACK with those fixes.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 604 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140124/ac47850f/attachment-0001.sig>
More information about the libvir-list
mailing list