[libvirt] [PATCH v3 4/6] nodedev: Introduce the mdev capability to a PCI parent device

Pavel Hrdina phrdina at redhat.com
Tue May 9 13:24:55 UTC 2017


On Wed, Apr 26, 2017 at 04:55:31PM +0200, Erik Skultety wrote:
> The parent device needs to report the generic stuff about the supported
> mediated devices types, like device API, available instances, type name,
> etc. Therefore this patch introduces a new nested capability element of
> type 'mdev_types' with the resulting XML of the following format:
> 
> <device>
> ...
>   <capability type='pci'>
>   ...
>     <capability type='mdev_types'>
>       <type id='vendor_supplied_id'>
>         <name>optional_vendor_supplied_codename</name>
>         <deviceAPI>vfio-pci</deviceAPI>
>         <availableInstances>NUM</availableInstances>
>       </type>
>       ...
>       <type>
>       ...

It's a commit message so it doesn't matter but I would indent the
place-holder dots :).

>       </type>
>     </capability>
>   </capability>
> ...
> </device>
> 
> Signed-off-by: Erik Skultety <eskultet at redhat.com>
> ---
>  docs/schemas/nodedev.rng                           |  26 +++++
>  src/conf/node_device_conf.c                        | 104 ++++++++++++++++++
>  src/conf/node_device_conf.h                        |  15 +++
>  src/conf/virnodedeviceobj.c                        |   7 ++
>  src/libvirt_private.syms                           |   1 +
>  src/node_device/node_device_udev.c                 | 119 +++++++++++++++++++++
>  .../pci_0000_02_10_7_mdev_types.xml                |  32 ++++++
>  tests/nodedevxml2xmltest.c                         |   1 +
>  8 files changed, 305 insertions(+)
>  create mode 100644 tests/nodedevschemadata/pci_0000_02_10_7_mdev_types.xml
> 
> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
> index 0f90a73c8..e0a2c5032 100644
> --- a/docs/schemas/nodedev.rng
> +++ b/docs/schemas/nodedev.rng
> @@ -205,6 +205,32 @@
>      </optional>
>  
>      <optional>
> +      <element name='capability'>
> +        <attribute name='type'>
> +          <value>mdev_types</value>
> +        </attribute>
> +        <oneOrMore>
> +          <element name='type'>
> +            <attribute name='id'>
> +              <data type='string'/>
> +            </attribute>
> +            <optional>
> +              <element name='name'><text/></element>
> +            </optional>
> +            <element name='deviceAPI'>
> +              <choice>
> +                <value>vfio-pci</value>
> +              </choice>
> +            </element>
> +            <element name='availableInstances'>
> +              <ref name='unsignedInt'/>
> +            </element>
> +          </element>
> +        </oneOrMore>
> +      </element>
> +   </optional>
> +
> +    <optional>
>        <element name='iommuGroup'>
>          <attribute name='number'>
>            <ref name='unsignedInt'/>
> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
> index 24cb6d66f..b3012821a 100644
> --- a/src/conf/node_device_conf.c
> +++ b/src/conf/node_device_conf.c
> @@ -88,6 +88,26 @@ virNodeDevCapsDefParseString(const char *xpath,
>  }
>  
>  
> +static void
> +virNodeDevCapMdevTypeClear(virNodeDevCapMdevTypePtr type)
> +{
> +    VIR_FREE(type->id);
> +    VIR_FREE(type->name);
> +    VIR_FREE(type->device_api);
> +}

There is no need for the extra Clear function since it's static
and used only by the Free function.

> +
> +
> +void
> +virNodeDevCapMdevTypeFree(virNodeDevCapMdevTypePtr type)
> +{
> +    if (!type)
> +        return;
> +
> +    virNodeDevCapMdevTypeClear(type);
> +    VIR_FREE(type);
> +}
> +
> +
>  void
>  virNodeDeviceDefFree(virNodeDeviceDefPtr def)
>  {
> @@ -265,6 +285,27 @@ virNodeDeviceCapPCIDefFormat(virBufferPtr buf,
>          virBufferAsprintf(buf, "<capability type='%s'/>\n",
>                            virPCIHeaderTypeToString(data->pci_dev.hdrType));
>      }
> +    if (data->pci_dev.flags & VIR_NODE_DEV_CAP_FLAG_PCI_MDEV) {
> +        virBufferAddLit(buf, "<capability type='mdev_types'>\n");
> +        virBufferAdjustIndent(buf, 2);
> +        for (i = 0; i < data->pci_dev.nmdev_types; i++) {
> +            virNodeDevCapMdevTypePtr type = data->pci_dev.mdev_types[i];
> +            virBufferEscapeString(buf, "<type id='%s'>\n", type->id);
> +            virBufferAdjustIndent(buf, 2);
> +            if (type->name)
> +                virBufferAsprintf(buf, "<name>%s</name>\n",
> +                                  type->name);
> +            virBufferAsprintf(buf, "<deviceAPI>%s</deviceAPI>\n",
> +                              type->device_api);

We should use virBufferEscapeString for <name> and <deviceAPI> as well,
the data stored in these variables are loaded from sysfs.

> +            virBufferAsprintf(buf,
> +                              "<availableInstances>%u</availableInstances>\n",
> +                              type->available_instances);
> +            virBufferAdjustIndent(buf, -2);
> +            virBufferAddLit(buf, "</type>\n");
> +        }
> +        virBufferAdjustIndent(buf, -2);
> +        virBufferAddLit(buf, "</capability>\n");
> +    }
>      if (data->pci_dev.nIommuGroupDevices) {
>          virBufferAsprintf(buf, "<iommuGroup number='%d'>\n",
>                            data->pci_dev.iommuGroupNumber);
> @@ -1365,6 +1406,63 @@ virNodeDevPCICapSRIOVVirtualParseXML(xmlXPathContextPtr ctxt,
>  
>  
>  static int
> +virNodeDevPCICapMdevTypesParseXML(xmlXPathContextPtr ctxt,
> +                                  virNodeDevCapPCIDevPtr pci_dev)
> +{
> +    int ret = -1;
> +    xmlNodePtr orignode = NULL;
> +    xmlNodePtr *nodes = NULL;
> +    int nmdev_types = virXPathNodeSet("./type", ctxt, &nodes);
> +    virNodeDevCapMdevTypePtr type = NULL;
> +    size_t i;
> +
> +    orignode = ctxt->node;
> +    for (i = 0; i < nmdev_types; i++) {
> +        ctxt->node = nodes[i];
> +
> +        if (VIR_ALLOC(type) < 0)
> +            goto cleanup;
> +
> +        if (!(type->id = virXPathString("string(./@id[1])", ctxt))) {
> +            virReportError(VIR_ERR_XML_ERROR, "%s",
> +                           _("missing 'id' attribute for mediated device's "
> +                             "<type> element"));
> +            goto cleanup;
> +        }
> +
> +        if (!(type->device_api = virXPathString("string(./deviceAPI[1])", ctxt))) {
> +            virReportError(VIR_ERR_XML_ERROR,
> +                           _("missing device API for mediated device type '%s'"),
> +                           type->id);
> +            goto cleanup;
> +        }
> +
> +        if (virXPathUInt("number(./availableInstances)", ctxt,
> +                         &type->available_instances) < 0) {
> +            virReportError(VIR_ERR_XML_ERROR,
> +                           _("missing number of available instances for "
> +                             "mediated device type '%s'"),
> +                           type->id);
> +            goto cleanup;
> +        }
> +
> +        type->name = virXPathString("string(./name)", ctxt);
> +
> +        if (VIR_APPEND_ELEMENT(pci_dev->mdev_types,
> +                               pci_dev->nmdev_types, type) < 0)
> +            goto cleanup;
> +    }
> +
> +    pci_dev->flags |= VIR_NODE_DEV_CAP_FLAG_PCI_MDEV;
> +    ret = 0;
> + cleanup:
> +    virNodeDevCapMdevTypeFree(type);
> +    ctxt->node = orignode;
> +    return ret;
> +}
> +
> +
> +static int
>  virNodeDevPCICapabilityParseXML(xmlXPathContextPtr ctxt,
>                                  xmlNodePtr node,
>                                  virNodeDevCapPCIDevPtr pci_dev)
> @@ -1386,6 +1484,9 @@ virNodeDevPCICapabilityParseXML(xmlXPathContextPtr ctxt,
>      } else if (STREQ(type, "virt_functions") &&
>                 virNodeDevPCICapSRIOVVirtualParseXML(ctxt, pci_dev) < 0) {
>          goto cleanup;
> +    } if (STREQ(type, "mdev_types") &&

s/if/else if/

> +          virNodeDevPCICapMdevTypesParseXML(ctxt, pci_dev)) {

there should be " < 0 " comparison.

> +          goto cleanup;
>      } else {
>          int hdrType = virPCIHeaderTypeFromString(type);
>  

Pavel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20170509/9209fc42/attachment-0001.sig>


More information about the libvir-list mailing list