aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wright <chrisw@redhat.com>2010-07-26 18:43:04 +0200
committerDaniel Veillard <veillard@redhat.com>2010-07-26 18:43:04 +0200
commit46bcdb960dd5d725ec568a32d4ef5b9c175c80d3 (patch)
tree3d76dfbf9d58a8516176a270adeac491e32f7f69
parentqemudDomainAttachHostPciDevice refactor to use new helpers (diff)
downloadlibvirt-46bcdb960dd5d725ec568a32d4ef5b9c175c80d3.tar.gz
libvirt-46bcdb960dd5d725ec568a32d4ef5b9c175c80d3.tar.bz2
libvirt-46bcdb960dd5d725ec568a32d4ef5b9c175c80d3.zip
pciResetDevice: use inactive devices to determine safe reset
When doing a PCI secondary bus reset, we must be sure that there are no active devices on the same bus segment. The active device tracking is designed to only track host devices that are active in use by guests. This ignores host devices that are actively in use by the host. So the current logic will reset host devices. Switch this logic around and allow sbus reset when we are assigning all devices behind a bridge to the same guest at guest startup or as a result of a single attach-device command. * src/util/pci.h: change signature of pciResetDevice to add an inactive devices list * src/qemu/qemu_driver.c src/xen/xen_driver.c: use (or not) the new functionality of pciResetDevice() depending on the place of use * src/util/pci.c: implement the interface and logic changes
-rw-r--r--src/qemu/qemu_driver.c8
-rw-r--r--src/util/pci.c20
-rw-r--r--src/util/pci.h3
-rw-r--r--src/xen/xen_driver.c2
4 files changed, 18 insertions, 15 deletions
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 63ddd35fb..45a2cfcaa 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3107,7 +3107,7 @@ qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
* reset them */
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
- if (pciResetDevice(dev, driver->activePciHostdevs) < 0)
+ if (pciResetDevice(dev, driver->activePciHostdevs, pcidevs) < 0)
goto cleanup;
}
@@ -3253,7 +3253,7 @@ qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
- if (pciResetDevice(dev, driver->activePciHostdevs) < 0) {
+ if (pciResetDevice(dev, driver->activePciHostdevs, pcidevs) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to reset PCI device: %s"),
err ? err->message : _("unknown error"));
@@ -8995,7 +8995,7 @@ static int qemudDomainDetachHostPciDevice(struct qemud_driver *driver,
else {
pciDeviceSetManaged(pci, detach->managed);
pciDeviceListDel(driver->activePciHostdevs, pci);
- if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
+ if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0)
ret = -1;
qemudReattachManagedDevice(pci, driver);
pciFreeDevice(pci);
@@ -11620,7 +11620,7 @@ qemudNodeDeviceReset (virNodeDevicePtr dev)
qemuDriverLock(driver);
- if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
+ if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0)
goto out;
ret = 0;
diff --git a/src/util/pci.c b/src/util/pci.c
index 6d0ca24f6..1c10067d9 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -440,11 +440,11 @@ pciDetectPowerManagementReset(pciDevice *dev)
return 0;
}
-/* Any active devices other than the one supplied on the same domain/bus ? */
+/* Any active devices on the same domain/bus ? */
static int
pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data)
{
- pciDeviceList *activeDevs = data;
+ pciDeviceList *inactiveDevs = data;
/* Different domain, different bus, or simply identical device */
if (dev->domain != check->domain ||
@@ -453,7 +453,8 @@ pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data)
dev->function == check->function))
return 0;
- if (activeDevs && !pciDeviceListFind(activeDevs, check))
+ /* same bus, but inactive, i.e. about to be assigned to guest */
+ if (inactiveDevs && pciDeviceListFind(inactiveDevs, check))
return 0;
return 1;
@@ -461,11 +462,11 @@ pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data)
static pciDevice *
pciBusContainsActiveDevices(pciDevice *dev,
- pciDeviceList *activeDevs)
+ pciDeviceList *inactiveDevs)
{
pciDevice *active = NULL;
if (pciIterDevices(pciSharesBusWithActive,
- dev, &active, activeDevs) < 0)
+ dev, &active, inactiveDevs) < 0)
return NULL;
return active;
}
@@ -512,7 +513,7 @@ pciGetParentDevice(pciDevice *dev)
*/
static int
pciTrySecondaryBusReset(pciDevice *dev,
- pciDeviceList *activeDevs)
+ pciDeviceList *inactiveDevs)
{
pciDevice *parent, *conflict;
uint8_t config_space[PCI_CONF_LEN];
@@ -524,7 +525,7 @@ pciTrySecondaryBusReset(pciDevice *dev,
* In future, we could allow it so long as those devices
* are not in use by the host or other guests.
*/
- if ((conflict = pciBusContainsActiveDevices(dev, activeDevs))) {
+ if ((conflict = pciBusContainsActiveDevices(dev, inactiveDevs))) {
pciReportError(VIR_ERR_NO_SUPPORT,
_("Active %s devices on bus with %s, not doing bus reset"),
conflict->name, dev->name);
@@ -642,7 +643,8 @@ pciInitDevice(pciDevice *dev)
int
pciResetDevice(pciDevice *dev,
- pciDeviceList *activeDevs)
+ pciDeviceList *activeDevs,
+ pciDeviceList *inactiveDevs)
{
int ret = -1;
@@ -670,7 +672,7 @@ pciResetDevice(pciDevice *dev,
/* Bus reset is not an option with the root bus */
if (ret < 0 && dev->bus != 0)
- ret = pciTrySecondaryBusReset(dev, activeDevs);
+ ret = pciTrySecondaryBusReset(dev, inactiveDevs);
if (ret < 0) {
virErrorPtr err = virGetLastError();
diff --git a/src/util/pci.h b/src/util/pci.h
index 9aef81f9e..b767930bb 100644
--- a/src/util/pci.h
+++ b/src/util/pci.h
@@ -35,7 +35,8 @@ void pciFreeDevice (pciDevice *dev);
int pciDettachDevice (pciDevice *dev, pciDeviceList *activeDevs);
int pciReAttachDevice (pciDevice *dev, pciDeviceList *activeDevs);
int pciResetDevice (pciDevice *dev,
- pciDeviceList *activeDevs);
+ pciDeviceList *activeDevs,
+ pciDeviceList *inactiveDevs);
void pciDeviceSetManaged(pciDevice *dev,
unsigned managed);
unsigned pciDeviceGetManaged(pciDevice *dev);
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index b55e49453..d121ea4c3 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1892,7 +1892,7 @@ xenUnifiedNodeDeviceReset (virNodeDevicePtr dev)
if (!pci)
return -1;
- if (pciResetDevice(pci, NULL) < 0)
+ if (pciResetDevice(pci, NULL, NULL) < 0)
goto out;
ret = 0;