[libvirt] [PATCH 2/3] conf, docs: Add support for coalesce setting(s)

Michal Privoznik mprivozn at redhat.com
Mon Apr 10 12:21:50 UTC 2017


On 04/07/2017 06:04 PM, Martin Kletzander wrote:
> We are currently parsing only rx_max_coalesced_frames because that's
> the only value that makes sense for us.  The tun device just added
> support for this one and the others are only supported by hardware
> devices which we don't need to worry about as the only way we'd pass
> those to the domain is using <hostdev/> or <interface type='hostdev'/>.
> And in those cases the guest can modify the settings itself.
>
> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
> ---
>  docs/formatdomain.html.in                          | 24 ++++++
>  docs/schemas/domaincommon.rng                      |  3 +
>  docs/schemas/networkcommon.rng                     | 17 ++++
>  src/conf/domain_conf.c                             |  9 +++
>  src/conf/domain_conf.h                             |  2 +
>  src/conf/networkcommon_conf.c                      | 91 ++++++++++++++++++++++
>  src/conf/networkcommon_conf.h                      |  9 +++
>  src/libvirt_private.syms                           |  2 +
>  src/qemu/qemu_domain.c                             | 31 ++++++++
>  .../qemuxml2argvdata/qemuxml2argv-net-coalesce.xml | 64 +++++++++++++++
>  .../qemuxml2xmlout-net-coalesce.xml                | 69 ++++++++++++++++
>  tests/qemuxml2xmltest.c                            |  1 +
>  12 files changed, 322 insertions(+)
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-coalesce.xml
>  create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-net-coalesce.xml
>
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index b1e38f00e423..ea64b7fd1193 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -5405,6 +5405,30 @@ qemu-kvm -net nic,model=? /dev/null
>        <span class="since">Since 3.1.0</span>
>      </p>
>
> +    <h5><a name="coalesce">Coalesce settings</a></h5>
> +<pre>
> +...
> +<devices>
> +  <interface type='network'>
> +    <source network='default'/>
> +    <target dev='vnet0'/>
> +    <b><coalesce>
> +      <rx_max_coalesced_frames>5</rx_max_coalesced_frames>
> +    </coalesce></b>
> +  </interface>
> +</devices>
> +...</pre>
> +
> +    <p>
> +      This element provides means of setting coalesce settings for some
> +      interface devices (currently only type <code>network</code>
> +      and <code>bridge</code>.  Currently there is just one sub-element
> +      named <code>rx_max_coalesced_frames</code> which accepts a non-negative
> +      integer that specifies the maximum number of packets that will be received
> +      before an interrupt.
> +      <span class="since">Since 3.3.0</span>
> +    </p>
> +
>      <h5><a name="ipconfig">IP configuration</a></h5>
>  <pre>
>  ...
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index edc225fe50c5..b703515fb897 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -2509,6 +2509,9 @@
>          <ref name="mtu"/>
>        </optional>
>        <optional>
> +        <ref name="coalesce"/>
> +      </optional>
> +      <optional>
>          <element name="target">
>            <attribute name="dev">
>              <ref name="deviceName"/>
> diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
> index 26995556d48d..27e78d13e4a6 100644
> --- a/docs/schemas/networkcommon.rng
> +++ b/docs/schemas/networkcommon.rng
> @@ -275,4 +275,21 @@
>        </attribute>
>      </element>
>    </define>
> +
> +  <define name="coalesce">
> +    <element name="coalesce">
> +      <interleave>
> +        <!--
> +            Other parameters can just be added here the same way the
> +            following one is.
> +            -->
> +        <optional>
> +          <element name="rx_max_coalesced_frames">
> +            <ref name="unsignedInt"/>
> +          </element>
> +        </optional>
> +      </interleave>
> +    </element>
> +  </define>
> +

Not sure what's happening here (one has to love libxml2 error 
reporting), but when I try to add the following to my domain XML I get a 
schema error:

       <coalesce>
         <rx_max_coalesced_frames>7</rx_max_coalesced_frames>
       </coalesce>

virsh # edit fedora
error: XML document failed to validate against schema: Unable to 
validate doc against 
/home/zippy/work/libvirt/libvirt.git/docs/schemas/domain.rng
Extra element devices in interleave
Element domain failed to validate content


BTW: is there a reason why this element is defined in networkcommon.rng?

And a side note, frankly I'm not a big fan of 
<elements_with_underscore_in_their_name/> but I guess this is the best 
we can do - everybody touching this setting is already familiar with 
that from

>  </grammar>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 80baa090a7f8..3cc17b5fd228 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -10251,6 +10251,13 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
>          goto error;
>      }
>
> +    node = virXPathNode("./coalesce", ctxt);
> +    if (node) {
> +        def->coalesce = virNetDevCoalesceParseXML(node, ctxt);
> +        if (!def->coalesce)
> +            goto error;
> +    }
> +
>   cleanup:
>      ctxt->node = oldnode;
>      VIR_FREE(macaddr);
> @@ -22144,6 +22151,8 @@ virDomainNetDefFormat(virBufferPtr buf,
>      if (def->mtu)
>          virBufferAsprintf(buf, "<mtu size='%u'/>\n", def->mtu);
>
> +    virNetDevCoalesceFormatXML(buf, def->coalesce);
> +
>      if (virDomainDeviceInfoFormat(buf, &def->info,
>                                    flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT
>                                    | VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM) < 0)
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 26c0e6b88759..6c3de9cc2cd4 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -41,6 +41,7 @@
>  # include "numa_conf.h"
>  # include "virnetdevmacvlan.h"
>  # include "virsysinfo.h"
> +# include "virnetdev.h"
>  # include "virnetdevip.h"
>  # include "virnetdevvportprofile.h"
>  # include "virnetdevbandwidth.h"
> @@ -1036,6 +1037,7 @@ struct _virDomainNetDef {
>      int trustGuestRxFilters; /* enum virTristateBool */
>      int linkstate;
>      unsigned int mtu;
> +    virNetDevCoalescePtr coalesce;
>  };
>
>  /* Used for prefix of ifname of any network name generated dynamically
> diff --git a/src/conf/networkcommon_conf.c b/src/conf/networkcommon_conf.c
> index 29e978bbdfe5..e0756da6c9ec 100644
> --- a/src/conf/networkcommon_conf.c
> +++ b/src/conf/networkcommon_conf.c
> @@ -328,3 +328,94 @@ virNetDevIPRouteFormat(virBufferPtr buf,
>   cleanup:
>      return result;
>  }
> +
> +virNetDevCoalescePtr
> +virNetDevCoalesceParseXML(xmlNodePtr node,
> +                          xmlXPathContextPtr ctxt)
> +{
> +    virNetDevCoalescePtr ret = NULL;
> +    xmlNodePtr save = NULL;
> +    char *str = NULL;
> +    unsigned long long tmp = 0;
> +
> +    save = ctxt->node;
> +    ctxt->node = node;
> +
> +#define GET_COALESCE_PARAM(name)                                        \
> +    do {                                                                \
> +        str = virXPathString("string(./" #name ")", ctxt);              \
> +        if (!str)                                                       \
> +            break;                                                      \
> +                                                                        \
> +        if (!ret && VIR_ALLOC(ret) < 0)                                 \
> +            return NULL;                                                \
> +                                                                        \
> +        if (virStrToLong_ullp(str, NULL, 10, &tmp) < 0) {               \
> +            virReportError(VIR_ERR_XML_DETAIL,                          \
> +                           _("cannot parse value '%s' for parameter '%s'"), \
> +                           str, #name);                                 \
> +            VIR_FREE(str);                                              \
> +            goto error;                                                 \
> +        }                                                               \
> +        VIR_FREE(str);                                                  \
> +                                                                        \
> +        if (tmp > UINT32_MAX) {                                         \
> +            virReportError(VIR_ERR_OVERFLOW,                            \
> +                           _("value '%llu' is too big for " #name       \
> +                             ", maximum is '%lu'"),                     \
> +                           tmp, (unsigned long) UINT32_MAX);            \
> +            goto error;                                                 \
> +        }                                                               \
> +                                                                        \
> +        ret->name = tmp;                                                \
> +    } while (0)
> +
> +    /* Just add more parameters if needed */
> +
> +    GET_COALESCE_PARAM(rx_max_coalesced_frames);
> +
> +#undef GET_COALESCE_PARAM
> +
> + cleanup:
> +    ctxt->node = save;
> +    return ret;
> +
> + error:
> +    VIR_FREE(ret);
> +    goto cleanup;
> +}
> +
> +void
> +virNetDevCoalesceFormatXML(virBufferPtr buf,
> +                           virNetDevCoalescePtr coalesce)
> +{
> +    virBuffer childrenBuf = VIR_BUFFER_INITIALIZER;
> +    int indent = virBufferGetIndent(buf, false);
> +
> +    if (!coalesce)
> +        return;
> +
> +    virBufferAdjustIndent(&childrenBuf, indent + 2);
> +
> +#define SET_COALESCE_PARAM(name)                                \
> +    do {                                                        \
> +        if (coalesce->name) {                                   \
> +            virBufferAsprintf(&childrenBuf,                     \
> +                              /* TODO: turn %u into something 32-bit compatible */ \
> +                              "<" #name ">%u</" #name ">\n",    \
> +                              coalesce->name);                  \
> +        }                                                       \
> +    } while (0)
> +
> +    /* Just add more parameters if needed */
> +
> +    SET_COALESCE_PARAM(rx_max_coalesced_frames);
> +
> +#undef SET_COALESCE_PARAM
> +
> +    if (virBufferUse(&childrenBuf)) {
> +        virBufferAddLit(buf, "<coalesce>\n");
> +        virBufferAddBuffer(buf, &childrenBuf);
> +        virBufferAddLit(buf, "</coalesce>\n");
> +    }
> +}
> diff --git a/src/conf/networkcommon_conf.h b/src/conf/networkcommon_conf.h
> index 70e46793f67b..a842e2075292 100644
> --- a/src/conf/networkcommon_conf.h
> +++ b/src/conf/networkcommon_conf.h
> @@ -32,6 +32,7 @@
>  # include "virbuffer.h"
>  # include "virsocketaddr.h"
>  # include "virnetdevip.h"
> +# include "virnetdev.h"
>
>  virNetDevIPRoutePtr
>  virNetDevIPRouteCreate(const char *networkName,
> @@ -52,4 +53,12 @@ int
>  virNetDevIPRouteFormat(virBufferPtr buf,
>                         const virNetDevIPRoute *def);
>
> +virNetDevCoalescePtr
> +virNetDevCoalesceParseXML(xmlNodePtr node,
> +                          xmlXPathContextPtr ctxt);
> +
> +void
> +virNetDevCoalesceFormatXML(virBufferPtr buf,
> +                           virNetDevCoalescePtr coalesce);
> +
>  #endif /* __NETWORKCOMMON_CONF_H__ */
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 7ba9b7d98d86..7712e3d0a7f2 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -685,6 +685,8 @@ virNetworkEventStateRegisterID;
>
>
>  # conf/networkcommon_conf.h
> +virNetDevCoalesceFormatXML;
> +virNetDevCoalesceParseXML;
>  virNetDevIPRouteCreate;
>  virNetDevIPRouteFormat;
>  virNetDevIPRouteParseXML;
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index a3bb7dbc9a25..ac7193c9743f 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -2953,6 +2953,30 @@ qemuDomainDefValidate(const virDomainDef *def,
>  }
>
>
> +static bool
> +qemuDomainNetSupportsCoalesce(virDomainNetType type)
> +{
> +    switch (type) {
> +    case VIR_DOMAIN_NET_TYPE_NETWORK:
> +    case VIR_DOMAIN_NET_TYPE_BRIDGE:
> +        return true;

Maybe I'm running old kernel, but I get ENOSUPP for type network.

> +    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
> +    case VIR_DOMAIN_NET_TYPE_ETHERNET:
> +    case VIR_DOMAIN_NET_TYPE_DIRECT:
> +    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
> +    case VIR_DOMAIN_NET_TYPE_USER:
> +    case VIR_DOMAIN_NET_TYPE_SERVER:
> +    case VIR_DOMAIN_NET_TYPE_CLIENT:
> +    case VIR_DOMAIN_NET_TYPE_MCAST:
> +    case VIR_DOMAIN_NET_TYPE_INTERNAL:
> +    case VIR_DOMAIN_NET_TYPE_UDP:
> +    case VIR_DOMAIN_NET_TYPE_LAST:
> +        break;
> +    }
> +    return false;
> +}
> +
> +

Michal




More information about the libvir-list mailing list