Restoring a PCI device's config space remaps its BARs, updates the bridge windows when it is a bridge, and toggles the bus master region. Each of those ends a memory transaction of its own, and a transaction commit re-renders the flatviews it touches, at a cost which grows with the number of memory regions in the machine.
So a machine with a rich PCIe topology pays that render many times over while an incoming migration stream is read, once or more per device, even though nothing between the steps looks at an address space. Both patches wrap an existing sequence in a single transaction. There is no new API and no behaviour a guest can observe: each transaction opens and closes inside the function that starts it, so nothing sees an intermediate state which was not already reachable. pci_bridge_update_mappings() has worked this way for the bridge windows for a long time; the first patch just makes pci_update_mappings() consistent with it. Measured on a Windows Server 2022 guest with 64 vCPUs and 65 pcie-root-ports, the non-iterable part of an incoming migration drops by about a third. The saving scales with the number of PCI devices, so it is small for a plain machine and large for the topologies which hurt today. Note that pci_update_mappings() is also reached from the runtime config write path, not only from migration. Several BAR moves in one config write now share a rebuild instead of taking one each, which is the same win in miniature and equally invisible to the guest. CC: Michael S. Tsirkin <[email protected]> Signed-off-by: Denis V. Lunev <[email protected]> Denis V. Lunev (2): pci: batch BAR remapping into one memory transaction pci: load a device's config inside one memory transaction hw/pci/pci.c | 8 ++++++++ 1 file changed, 8 insertions(+) -- 2.53.0
