
On 04/23/2013 06:47 AM, Ján Tomko wrote:
Add a "dry run" address allocation to figure out how many bridges will be needed for all the devices without explicit addresses.
Auto-add just enough bridges to put all the devices on, or up to the bridge with the largest specified index. ---
v4: Moved the check for duplicate controller indexes to a separate patch Simplified nbuses and max_idx computation Only does two-pass allocation of PCI addresses if the machine has a PCI bus Does not contain traces of rebasing or spurious whitespace changes Tests auto-adding PCI bridges in xml->argv and xml->xml tests.
@@ -1233,9 +1236,45 @@ static bool qemuPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs ATTRIBUTE_UN QEMU_PCI_ADDRESS_SLOT_LAST); return false; } + if (addr->slot == 0) { + if (addr->bus) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Slot 0 is unusable on PCI bridges")); + } else { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Slot 0 on bus 0 is reserved for the host bridge"));
Indentation is off.
@@ -1326,15 +1368,53 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, qemuDomainObjPrivatePtr priv = NULL;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + int max_idx = -1;
So let's trace what happens if I have XML with no <controller> but I do use 33 PCI devices and have a capable qemu: max_idx starts at -1,
int nbuses = 0; int i; + int rv;
for (i = 0; i < def->ncontrollers; i++) { - if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) - nbuses++; + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { + if (def->controllers[i]->idx > max_idx) + max_idx = def->controllers[i]->idx; + } + }
If no controllers were specified, it is still at -1,
+ + nbuses = max_idx + 1;
so nbuses is now 0,
+ + if (nbuses > 0 && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
therefore we skip this if,
+ virDomainDeviceInfo info; + /* 1st pass to figure out how many PCI bridges we need */ + if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true))) + goto cleanup; + if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0) + goto cleanup; + /* Reserve 1 extra slot for a (potential) bridge */ + if (qemuDomainPCIAddressSetNextAddr(addrs, &info) < 0) + goto cleanup; + + for (i = 1; i < addrs->nbuses; i++) { + if ((rv = virDomainDefMaybeAddController( + def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, + i, VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE)) < 0) + goto cleanup; + /* If we added a new bridge, we will need one more address */ + if (rv > 0 && qemuDomainPCIAddressSetNextAddr(addrs, &info) < 0) + goto cleanup; + } + nbuses = addrs->nbuses; + qemuDomainPCIAddressSetFree(addrs); + addrs = NULL; + + } else if (max_idx > 0) {
we don't error out,
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("PCI bridges are not supported " + "by this QEMU binary")); + goto cleanup; }
but we also didn't auto-instantiate any bridges, even if the capability is supported. Is that a problem? ACK if you can answer my question and fix the minor issues. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org