diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 23fa01b2cf0ae9c1aee7287db54d3d2afb0762b0..642c2bca98453a42985d2586f70584e8e1d94e8f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -283,7 +283,6 @@ virNodeDeviceAssignDef; pciGetDevice; pciFreeDevice; pciDettachDevice; -pciDeviceEquals; pciReAttachDevice; pciResetDevice; diff --git a/src/pci.c b/src/pci.c index 619853b2afa60537d7d665ed10b0bd0cdde6cc1e..74f7ef071fe9fee1c7bd8c52859b52e16024f6e4 100644 --- a/src/pci.c +++ b/src/pci.c @@ -225,11 +225,7 @@ pciWrite32(pciDevice *dev, unsigned pos, uint32_t val) pciWrite(dev, pos, &buf[0], sizeof(buf)); } -typedef int (*pciIterPredicate)(virConnectPtr, - virDomainObjPtr, - pciDevice *, - pciResetCheckFunc, - pciDevice *); +typedef int (*pciIterPredicate)(pciDevice *, pciDevice *); /* Iterate over available PCI devices calling @predicate * to compare each one to @dev. @@ -238,10 +234,8 @@ typedef int (*pciIterPredicate)(virConnectPtr, */ static int pciIterDevices(virConnectPtr conn, - virDomainObjPtr vm, pciIterPredicate predicate, pciDevice *dev, - pciResetCheckFunc check, pciDevice **matched) { DIR *dir; @@ -260,7 +254,7 @@ pciIterDevices(virConnectPtr conn, while ((entry = readdir(dir))) { unsigned domain, bus, slot, function; - pciDevice *check_dev; + pciDevice *try; /* Ignore '.' and '..' */ if (entry->d_name[0] == '.') @@ -272,18 +266,18 @@ pciIterDevices(virConnectPtr conn, continue; } - check_dev = pciGetDevice(conn, domain, bus, slot, function); - if (!check_dev) { + try = pciGetDevice(conn, domain, bus, slot, function); + if (!try) { ret = -1; break; } - if (predicate(conn, vm, dev, check, check_dev)) { - VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, check_dev->name); - *matched = check_dev; + if (predicate(try, dev)) { + VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, try->name); + *matched = try; break; } - pciFreeDevice(conn, check_dev); + pciFreeDevice(conn, try); } closedir(dir); return ret; @@ -385,73 +379,63 @@ pciDetectPowerManagementReset(pciDevice *dev) return 0; } -/* Check any devices other than the one supplied on the same domain/bus */ +/* Any devices other than the one supplied on the same domain/bus ? */ static int -pciCheckSharesBus(virConnectPtr conn, - virDomainObjPtr vm, - pciDevice *dev, - pciResetCheckFunc check, - pciDevice *check_dev) +pciSharesBus(pciDevice *a, pciDevice *b) { - if (check_dev->domain != dev->domain || check_dev->bus != dev->bus) - return 0; - if (check_dev->slot == dev->slot && check_dev->function == dev->function) - return 0; - if (check(conn, vm, check_dev)) - return 0; - return 1; + return + a->domain == b->domain && + a->bus == b->bus && + (a->slot != b->slot || + a->function != b->function); } -static pciDevice * -pciBusCheckOtherDevices(virConnectPtr conn, - virDomainObjPtr vm, - pciDevice *dev, - pciResetCheckFunc check) +static int +pciBusContainsOtherDevices(virConnectPtr conn, pciDevice *dev) { - pciDevice *conflict = NULL; - pciIterDevices(conn, vm, pciCheckSharesBus, dev, check, &conflict); - return conflict; + pciDevice *matched = NULL; + if (pciIterDevices(conn, pciSharesBus, dev, &matched) < 0) + return 1; + if (!matched) + return 0; + pciFreeDevice(conn, matched); + return 1; } -/* Is @check_dev the parent of @dev ? */ +/* Is @a the parent of @b ? */ static int -pciIsParent(virConnectPtr conn ATTRIBUTE_UNUSED, - virDomainObjPtr vm ATTRIBUTE_UNUSED, - pciDevice *dev, - pciResetCheckFunc check ATTRIBUTE_UNUSED, - pciDevice *check_dev) +pciIsParent(pciDevice *a, pciDevice *b) { uint16_t device_class; uint8_t header_type, secondary, subordinate; - if (check_dev->domain != dev->domain) + if (a->domain != b->domain) return 0; /* Is it a bridge? */ - device_class = pciRead16(check_dev, PCI_CLASS_DEVICE); + device_class = pciRead16(a, PCI_CLASS_DEVICE); if (device_class != PCI_CLASS_BRIDGE_PCI) return 0; /* Is it a plane? */ - header_type = pciRead8(check_dev, PCI_HEADER_TYPE); + header_type = pciRead8(a, PCI_HEADER_TYPE); if ((header_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE) return 0; - secondary = pciRead8(check_dev, PCI_SECONDARY_BUS); - subordinate = pciRead8(check_dev, PCI_SUBORDINATE_BUS); + secondary = pciRead8(a, PCI_SECONDARY_BUS); + subordinate = pciRead8(a, PCI_SUBORDINATE_BUS); - VIR_DEBUG("%s %s: found parent device %s\n", - dev->id, dev->name, check_dev->name); + VIR_DEBUG("%s %s: found parent device %s\n", b->id, b->name, a->name); /* No, it's superman! */ - return (dev->bus >= secondary && dev->bus <= subordinate); + return (b->bus >= secondary && b->bus <= subordinate); } static pciDevice * pciGetParentDevice(virConnectPtr conn, pciDevice *dev) { pciDevice *parent = NULL; - pciIterDevices(conn, NULL, pciIsParent, dev, NULL, &parent); + pciIterDevices(conn, pciIsParent, dev, &parent); return parent; } @@ -459,12 +443,9 @@ pciGetParentDevice(virConnectPtr conn, pciDevice *dev) * devices behind a bus. */ static int -pciTrySecondaryBusReset(virConnectPtr conn, - virDomainObjPtr vm, - pciDevice *dev, - pciResetCheckFunc check) +pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev) { - pciDevice *parent, *conflict; + pciDevice *parent; uint8_t config_space[PCI_CONF_LEN]; uint16_t ctl; int ret = -1; @@ -474,11 +455,10 @@ pciTrySecondaryBusReset(virConnectPtr conn, * In future, we could allow it so long as those devices * are not in use by the host or other guests. */ - if ((conflict = pciBusCheckOtherDevices(conn, vm, dev, check))) { + if (pciBusContainsOtherDevices(conn, dev)) { pciReportError(conn, VIR_ERR_NO_SUPPORT, - _("Unable to reset %s using bus reset as this would cause %s to be reset"), - dev->name, conflict->name); - pciFreeDevice(conn, conflict); + _("Other devices on bus with %s, not doing bus reset"), + dev->name); return -1; } @@ -592,24 +572,13 @@ pciInitDevice(virConnectPtr conn, pciDevice *dev) } int -pciResetDevice(virConnectPtr conn, - virDomainObjPtr vm, - pciDevice *dev, - pciResetCheckFunc check) +pciResetDevice(virConnectPtr conn, pciDevice *dev) { int ret = -1; if (!dev->initted && pciInitDevice(conn, dev) < 0) return -1; - /* Check that the device isn't owned by a running VM */ - if (!check(conn, vm, dev)) { - pciReportError(conn, VIR_ERR_NO_SUPPORT, - _("Unable to reset PCI device %s: device is in use"), - dev->name); - return -1; - } - /* KVM will perform FLR when starting and stopping * a guest, so there is no need for us to do it here. */ @@ -625,7 +594,7 @@ pciResetDevice(virConnectPtr conn, /* Bus reset is not an option with the root bus */ if (ret < 0 && dev->bus != 0) - ret = pciTrySecondaryBusReset(conn, vm, dev, check); + ret = pciTrySecondaryBusReset(conn, dev); if (ret < 0) { virErrorPtr err = virGetLastError(); @@ -926,18 +895,3 @@ pciFreeDevice(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev) close(dev->fd); VIR_FREE(dev); } - -int -pciDeviceEquals(virConnectPtr conn ATTRIBUTE_UNUSED, - pciDevice *dev, - unsigned domain, - unsigned bus, - unsigned slot, - unsigned function) -{ - return - dev->domain == domain && - dev->bus == bus && - dev->slot == slot && - dev->function == function; -} diff --git a/src/pci.h b/src/pci.h index d5e680cba74c632a90ea275c315e262e60ce6519..47882efb4d21f8d48a2e160ef69fbd2867229a5f 100644 --- a/src/pci.h +++ b/src/pci.h @@ -24,7 +24,6 @@ #include #include "internal.h" -#include "domain_conf.h" typedef struct _pciDevice pciDevice; @@ -39,24 +38,7 @@ int pciDettachDevice (virConnectPtr conn, pciDevice *dev); int pciReAttachDevice (virConnectPtr conn, pciDevice *dev); - -/* pciResetDevice() may cause other devices to be reset; - * The check function is called for each other device to - * be reset and by returning zero may cause the reset to - * fail if it is not safe to reset the supplied device. - */ -typedef int (*pciResetCheckFunc)(virConnectPtr, virDomainObjPtr, pciDevice *); - -int pciResetDevice(virConnectPtr conn, - virDomainObjPtr vm, - pciDevice *dev, - pciResetCheckFunc check); - -int pciDeviceEquals(virConnectPtr conn, - pciDevice *dev, - unsigned domain, - unsigned bus, - unsigned slot, - unsigned function); +int pciResetDevice (virConnectPtr conn, + pciDevice *dev); #endif /* __VIR_PCI_H__ */ diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 6476644ba6fbec0159f7747a09a48057c4305c19..a638c10c706368f9f268cb71043fe3cbb684d475 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -1329,52 +1329,8 @@ static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { return -1; } -static int -qemuCheckPciHostDevice(virConnectPtr conn, - virDomainObjPtr owner_vm, - pciDevice *dev) -{ - struct qemud_driver *driver = conn->privateData; - int ret = 1, i; - - for (i = 0; i < driver->domains.count && ret; i++) { - virDomainObjPtr vm = driver->domains.objs[i]; - - if (vm == owner_vm) - continue; - - virDomainObjLock(vm); - - if (virDomainIsActive(vm)) { - int j; - - for (j = 0; j < vm->def->nhostdevs && ret; j++) { - virDomainHostdevDefPtr hostdev = vm->def->hostdevs[j]; - - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) - continue; - if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) - continue; - - if (pciDeviceEquals(conn, dev, - hostdev->source.subsys.u.pci.domain, - hostdev->source.subsys.u.pci.bus, - hostdev->source.subsys.u.pci.slot, - hostdev->source.subsys.u.pci.function)) - ret = 0; - } - } - - virDomainObjUnlock(vm); - } - - return ret; -} - -static int -qemuPrepareHostDevices(virConnectPtr conn, virDomainObjPtr vm) -{ - virDomainDefPtr def = vm->def; +static int qemuPrepareHostDevices(virConnectPtr conn, + virDomainDefPtr def) { int i; /* We have to use 2 loops here. *All* devices must @@ -1432,7 +1388,7 @@ qemuPrepareHostDevices(virConnectPtr conn, virDomainObjPtr vm) if (!dev) goto error; - if (pciResetDevice(conn, vm, dev, qemuCheckPciHostDevice) < 0) { + if (pciResetDevice(conn, dev) < 0) { pciFreeDevice(conn, dev); goto error; } @@ -1447,9 +1403,8 @@ error: } static void -qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainObjPtr vm) +qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def) { - virDomainDefPtr def = vm->def; int i; /* Again 2 loops; reset all the devices before re-attach */ @@ -1476,7 +1431,7 @@ qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainObjPtr vm) continue; } - if (pciResetDevice(conn, vm, dev, qemuCheckPciHostDevice) < 0) { + if (pciResetDevice(conn, dev) < 0) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to reset PCI device: %s\n"), err ? err->message : ""); @@ -2046,7 +2001,7 @@ static int qemudStartVMDaemon(virConnectPtr conn, if (qemuSetupCgroup(conn, driver, vm) < 0) goto cleanup; - if (qemuPrepareHostDevices(conn, vm) < 0) + if (qemuPrepareHostDevices(conn, vm->def) < 0) goto cleanup; if (VIR_ALLOC(vm->monitor_chr) < 0) { @@ -2228,7 +2183,7 @@ static void qemudShutdownVMDaemon(virConnectPtr conn, VIR_WARN("Failed to restore all device ownership for %s", vm->def->name); - qemuDomainReAttachHostDevices(conn, vm); + qemuDomainReAttachHostDevices(conn, vm->def); retry: if ((ret = qemuRemoveCgroup(conn, driver, vm)) < 0) { @@ -5371,7 +5326,7 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr conn, return -1; if (pciDettachDevice(conn, pci) < 0 || - pciResetDevice(conn, vm, pci, qemuCheckPciHostDevice) < 0) { + pciResetDevice(conn, pci) < 0) { pciFreeDevice(conn, pci); return -1; } @@ -7158,7 +7113,6 @@ out: static int qemudNodeDeviceReset (virNodeDevicePtr dev) { - struct qemud_driver *driver = dev->conn->privateData; pciDevice *pci; unsigned domain, bus, slot, function; int ret = -1; @@ -7170,14 +7124,11 @@ qemudNodeDeviceReset (virNodeDevicePtr dev) if (!pci) return -1; - qemuDriverLock(driver); - - if (pciResetDevice(dev->conn, NULL, pci, qemuCheckPciHostDevice) < 0) + if (pciResetDevice(dev->conn, pci) < 0) goto out; ret = 0; out: - qemuDriverUnlock(driver); pciFreeDevice(dev->conn, pci); return ret; } diff --git a/src/xen_unified.c b/src/xen_unified.c index dd8f10b161cf808d15b20f7c5dcef6294c3e2e58..f2ffc2512d80eaf9828c273605cf33cf42eb06ba 100644 --- a/src/xen_unified.c +++ b/src/xen_unified.c @@ -1641,7 +1641,7 @@ xenUnifiedNodeDeviceReset (virNodeDevicePtr dev) if (!pci) return -1; - if (pciResetDevice(dev->conn, NULL, pci, NULL) < 0) + if (pciResetDevice(dev->conn, pci) < 0) goto out; ret = 0;