Commit fb41f2f588 for qemu.org
commit fb41f2f5886092825c00ce7eea6e97b1a0029667
Author: Denis V. Lunev <den@openvz.org>
Date: Thu Sep 3 20:45:42 2026 +0200
pci: load a device's config inside one memory transaction
Restoring config space remaps the BARs, updates the bridge windows when
the device is a bridge, and toggles the bus master region. Each of those
commits a transaction of its own, so one device costs several flatview
rebuilds where one would do, and the cost of a rebuild grows with the
number of regions in the machine.
Nothing between them touches an address space, so the three can share a
transaction. The saving scales with the number of PCI devices.
CC: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Denis V. Lunev <den@virtuozzo.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260903184542.2629976-3-den@openvz.org>
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 14c78e3c62..0efb4eb4bb 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -840,6 +840,8 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
}
memcpy(s->config, config, size);
+ memory_region_transaction_begin();
+
pci_update_mappings(s);
if (IS_PCI_BRIDGE(s)) {
pci_bridge_update_mappings(PCI_BRIDGE(s));
@@ -848,6 +850,8 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
pci_set_master(s, pci_get_word(s->config + PCI_COMMAND)
& PCI_COMMAND_MASTER);
+ memory_region_transaction_commit();
+
g_free(config);
return 0;
}