• L
    qemu: initially reserve one open pcie-root-port for hotplug · 70d15c9a
    Laine Stump 提交于
    For machinetypes with a pci-root bus (all legacy PCI), libvirt will
    make a "fake" reservation for one extra slot prior to assigning
    addresses to unaddressed PCI endpoint devices in the domain. This will
    trigger auto-adding of a pci-bridge for the final device to be
    assigned an address *if that device would have otherwise instead been
    the last device on the last available pci-bridge*; thus it assures
    that there will always be at least one slot left open in the domain's
    bus topology for expansion (which is important both for hotplug (since
    a new pci-bridge can't be added while the guest is running) as well as
    for offline additions to the config (since adding a new device might
    otherwise in some cases require re-addressing existing devices, which
    we want to avoid)).
    
    It's important to note that for the above case (legacy PCI), we must
    check for the special case of all slots on all buses being occupied
    *prior to assigning any addresses*, and avoid attempting to reserve
    the extra address in that case, because there is no free address in
    the existing topology, so no place to auto-add a pci-bridge for
    expansion (i.e. it would always fail anyway). Since that condition can
    only be reached by manual intervention, this is acceptable.
    
    For machinetypes with pcie-root (Q35, aarch64 virt), libvirt's
    methodology for automatically expanding the bus topology is different
    - pcie-root-ports are plugged into slots (soon to be functions) of
    pcie-root as needed, and the new endpoint devices are assigned to the
    single slot in each pcie-root-port. This is done so that the devices
    are, by default, hotpluggable (the slots of pcie-root don't support
    hotplug, but the single slot of the pcie-root-port does). Since
    pcie-root-ports can only be plugged into pcie-root, and we don't
    auto-assign endpoint devices to the pcie-root slots, this means
    topology expansion doesn't compete with endpoint devices for slots, so
    we don't need to worry about checking for all "useful" slots being
    free *prior* to assigning addresses to new endpoint devices - as a
    matter of fact, if we attempt to reserve the open slots before the
    used slots, it can lead to errors.
    
    Instead this patch just reserves one slot for a "future potential"
    PCIe device after doing the assignment for actual devices, but only
    if the only PCI controller defined prior to starting address
    assignment was pcie-root, and only if we auto-added at least one PCI
    controller during address assignment. This assures two things:
    
    1) that reserving the open slots will only be done when the domain is
       initially defined, never at any time after, and
    
    2) that if the user understands enough about PCI controllers that they
       are adding them manually, that we don't mess up their plan by
       adding extras - if they know enough to add one pcie-root-port, or
       to manually assign addresses such that no pcie-root-ports are
       needed, they know enough to add extra pcie-root-ports if they want
       them (this could be called the "libguestfs clause", since
       libguestfs needs to be able to create domains with as few
       devices/controllers as possible).
    
    This is set to reserve a single free port for now, but could be
    increased in the future if public sentiment goes in that direction
    (it's easy to increase later, but essentially impossible to decrease)
    70d15c9a
qemuxml2xmltest.c 37.3 KB