[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 2/7] prevent hot unplugging multi function PCI device



Hi
   I applied these pacches to libvirt tree

8077d64f964705c1034555abeea38773532b762f

And built a qemu-kvm from the upstream qemu-kvm tree version 0.14. I tested these new binaries on my Redhat Enterprise Linux 6.1 GA.

Now I can have multiple function devices after I changed the VM XML config file manually, please see the 'lspci' output below. Also, I can hotplug one device, but it seems that unplugging it failed.
-------------------------------------------------------------------------------------
[root kvm-rhel-6 qemu]# virsh qemu-monitor-command
kvm-rhel-6.1-multifunction-1 --hmp 'device_add
lsi,id=scsi10,bus=pci.0,addr=0x7.0x00'

VM: **In the VM, 'lspci" can see one line added:

VM: **00:07.0 SCSI storage controller: LSI logic / Symbios Logic 5sc895a

[root kvm-rhel-6 qemu]# virsh qemu-monitor-command
kvm-rhel-6.1-multifunction-1 --hmp 'device_del
lsi,id=scsi10,bus=pci.0,addr=0x7.0x00'
Device 'lsi,id=scsi10,bus=pci.0,addr=0x7.0x00' not found


---------------------------------------------------------------------------------------------------------------
#lspci
 00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev
 02)
 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
 00:01.1 IDE interface: Intel Coporation 82371SB PIIX3 IDE [Natoma/Triton
 II]
 00:01.2 USB Controller: Intel Corporation 82371SB PIIX3 USB Natoma/Triton
 II]
 00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
 00:02.0 VGA compatible controller: Cirrus Logic GD 5446
00:03.0 Ethernet controller: Red Hat, Inc Virtio network device ---> function 0
 00:03.1 Ethernet controller: Red Hat, Inc Virtio network device
 00:03.2 Ethernet controller: Red Hat, Inc Virtio network device
 00:03.3 Ethernet controller: Red Hat, Inc Virtio network device
 00:03.4 Ethernet controller: Red Hat, Inc Virtio network device
 00:03.5 Ethernet controller: Red Hat, Inc Virtio network device
 00:03.6 Ethernet controller: Red Hat, Inc Virtio network device
00:03.7 Ethernet controller: Red Hat, Inc Virtio network device ---> function 7
 00:04.0 Audio device: Intel Corporation 82801FB/FBM/FR/FW/FRW
(ICH6 Family)
 High
 00:05.0 SCSI storage controller: Red Hat, Inc Virtio bloc device
 00:06.0 RAM memory: Red Hat, Inc Virtio memory balloon



Daniel P. Berrange:
On Fri, May 27, 2011 at 06:20:10PM +0800, Wen Congyang wrote:
We do not support to hot unplug multi function PCI device now. If the device is
one function of multi function PCI device, we shoul not allow to hot unplugg
it.
---
  src/qemu/qemu_hotplug.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++
  1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 3cf7d35..e98c677 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1100,6 +1100,30 @@ static inline int qemuFindDisk(virDomainDefPtr def, const char *dst)
      return -1;
  }

+static int qemuComparePCIDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                                virDomainDeviceInfoPtr dev1,
+                                void *opaque)
+{
+    virDomainDeviceInfoPtr dev2 = opaque;
+
+    if (dev1->type !=  VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
+        dev2->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+        return 0;
+
+    if (dev1->addr.pci.slot == dev2->addr.pci.slot&&
+        dev1->addr.pci.function != dev2->addr.pci.function)
+        return -1;
+    return 0;
+}
+
+static bool qemuIsMultiFunctionDevice(virDomainDefPtr def,
+                                      virDomainDeviceInfoPtr dev)
+{
+    if (virDomainDeviceInfoIterate(def, qemuComparePCIDevice, dev)<  0)
+        return true;
+    return false;
+}
+

  int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
                                    virDomainObjPtr vm,
@@ -1121,6 +1145,13 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,

      detach = vm->def->disks[i];

+    if (qemuIsMultiFunctionDevice(vm->def,&detach->info)) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("cannot hot unplug multifunction PCI device: %s"),
+                        dev->data.disk->dst);
+        goto cleanup;
+    }
+
      if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
          if (virCgroupForDomain(driver->cgroup, vm->def->name,&cgroup, 0) != 0) {
              qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1351,6 +1382,13 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
          goto cleanup;
      }

+    if (qemuIsMultiFunctionDevice(vm->def,&detach->info)) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("cannot hot unplug multifunction PCI device: %s"),
+                        dev->data.disk->dst);
+        goto cleanup;
+    }
+
      if (qemuDomainControllerIsBusy(vm, detach)) {
          qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
                          _("device cannot be detached: device is busy"));
@@ -1438,6 +1476,13 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver,
          goto cleanup;
      }

+    if (qemuIsMultiFunctionDevice(vm->def,&detach->info)) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("cannot hot unplug multifunction PCI device :%s"),
+                        dev->data.disk->dst);
+        goto cleanup;
+    }
+
      if ((vlan = qemuDomainNetVLAN(detach))<  0) {
          qemuReportError(VIR_ERR_OPERATION_FAILED,
                          "%s", _("unable to determine original VLAN"));
@@ -1567,6 +1612,13 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
          return -1;
      }

+    if (qemuIsMultiFunctionDevice(vm->def,&detach->info)) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("cannot hot unplug multifunction PCI device: %s"),
+                        dev->data.disk->dst);
+        return -1;
+    }
+
      if (!virDomainDeviceAddressIsValid(&detach->info,
                                         VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
          qemuReportError(VIR_ERR_OPERATION_FAILED,
ACK

Daniel



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]