[libvirt] [PATCH 22/22] qemu: implement backend of <driver group='auto'/>

Laine Stump laine at laine.org
Mon Jun 24 09:55:11 UTC 2013


This connects the new <driver> group attribute into qemu in two places:

1) when a hostdev is allocated from a libvirt network, the setting of
   groupMgmt is transferred from the network definition into the new
   HostdevDef.

2) When the virPCIDeviceList of all hostdevs for the domain is
created, each device's attach_group bool is set according to the value
of groupMgmt in the HostdevDef. This is where virPCIDeviceDetach (and
later virPCIDeviceReAttach) will find it.

The effect of setting group='auto':

If there are multiple devices in the same iommu group as the device
you wish to assign to a guest using VFIO, you have two choices:

a) Manually (with "virsh nodedev-detach --driver vfio" or by other
   means) detach each device in the group from the host and bind them
   all to either the vfio-pci driver or the pci-stub driver. Then
   define the <hostdev> (or <interface type='hostdev'>) in the guest
   config *without* "managed='yes'" - libvirt will expect that the
   device (and any other devices in the same group) will already be
   detached from the host and attached to a different driver
   appropriate for assigning to the guest.

b) If you wish to use <hostdev managed='yes'>, then add "group='auto'"
   to the device's <driver> element:

    <driver name='vfio' group='auto'/>

   When it is time to assign the device to the guest, libvirt will
   check through the group list, and any device in the group not
   already bound to vfio-pci, pci-stub, or pcieport, will be detached
   from the host and bound to vfio-pci.

Option (1) provides finer grained control over what driver is used for
each device in a group, while option (2) is simpler.

Note that if you actually want to assign all the devices in the group
to a single guest, you can specify "group='auto'" for all of them, and
libvirt will pay attention to which devices were already detached (and
not attempt to re-detach them, which is just a waste of time), and
also will not attempt to re-attach any of the devices in the group to
the host until *all* of them have been detached from the guest and are
free (and at that time all of them will be re-attached to the host at
the same time).
---
 src/network/bridge_driver.c | 22 ++++++++++++++++++++++
 src/qemu/qemu_hostdev.c     |  8 ++++++++
 2 files changed, 30 insertions(+)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index f7c2470..fbe0098 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -3945,6 +3945,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
     } else if (netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
 
         virDomainHostdevSubsysPciBackendType backend;
+        virDomainHostdevSubsysPciGroupMgmtType groupMgmt;
 
         if (!iface->data.network.actual
             && (VIR_ALLOC(iface->data.network.actual) < 0)) {
@@ -4001,6 +4002,27 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
         iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.backend
             = backend;
 
+        switch (netdef->forward.driverGroupMgmt)
+        {
+        case VIR_NETWORK_FORWARD_DRIVER_GROUP_MGMT_DEFAULT:
+            groupMgmt = VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_DEFAULT;
+            break;
+        case VIR_NETWORK_FORWARD_DRIVER_GROUP_MGMT_MANUAL:
+            groupMgmt = VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_MANUAL;
+            break;
+        case VIR_NETWORK_FORWARD_DRIVER_GROUP_MGMT_AUTO:
+            groupMgmt = VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_AUTO;
+            break;
+        default:
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unrecognized driver group management value %d "
+                             " in network '%s'"),
+                           netdef->forward.driverGroupMgmt, netdef->name);
+            goto error;
+        }
+        iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.groupMgmt
+            = groupMgmt;
+
         /* merge virtualports from interface, network, and portgroup to
          * arrive at actual virtualport to use
          */
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 1abad59..2b0221d 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -74,6 +74,10 @@ qemuGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs)
                 virObjectUnref(list);
                 return NULL;
             }
+            if (hostdev->source.subsys.u.pci.groupMgmt
+                == VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_AUTO) {
+                virPCIDeviceSetAttachGroup(dev, true);
+            }
         } else {
             if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) {
                 virObjectUnref(list);
@@ -167,6 +171,10 @@ int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver,
             == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
             if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0)
                 goto cleanup;
+            if (hostdev->source.subsys.u.pci.groupMgmt
+                == VIR_DOMAIN_HOSTDEV_PCI_GROUP_MGMT_AUTO) {
+                virPCIDeviceSetAttachGroup(dev, true);
+            }
         } else {
             if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0)
                 goto cleanup;
-- 
1.7.11.7




More information about the libvir-list mailing list