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


Reply via email to