aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2025-08-14 18:05:53 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2025-08-29 12:48:14 +0200
commit73c520b088878682e2d3b7fa19a6366ec8d39829 (patch)
tree4766e598cc92df2e3f4c565ff3e451e2f215ea04
parent87511341c30d8c9c77178db16491a0ccacc5d64b (diff)
downloadqemu-73c520b088878682e2d3b7fa19a6366ec8d39829.zip
qemu-73c520b088878682e2d3b7fa19a6366ec8d39829.tar.gz
qemu-73c520b088878682e2d3b7fa19a6366ec8d39829.tar.bz2
memory: reintroduce BQL-free fine-grained PIO/MMIO
This patch brings back Jan's idea [1] of BQL-free IO access This will let us make access to ACPI PM/HPET timers cheaper, and prevent BQL contention in case of workload that heavily uses the timers with a lot of vCPUs. 1) 196ea13104f (memory: Add global-locking property to memory regions) ... de7ea885c539 (kvm: Switch to unlocked MMIO) Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Link: https://lore.kernel.org/r/20250814160600.2327672-2-imammedo@redhat.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--include/system/memory.h12
-rw-r--r--system/memory.c15
-rw-r--r--system/physmem.c2
3 files changed, 28 insertions, 1 deletions
diff --git a/include/system/memory.h b/include/system/memory.h
index e2cd6ed..aa85fc2 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -833,6 +833,7 @@ struct MemoryRegion {
bool nonvolatile;
bool rom_device;
bool flush_coalesced_mmio;
+ bool lockless_io;
bool unmergeable;
uint8_t dirty_log_mask;
bool is_iommu;
@@ -2342,6 +2343,17 @@ void memory_region_set_flush_coalesced(MemoryRegion *mr);
void memory_region_clear_flush_coalesced(MemoryRegion *mr);
/**
+ * memory_region_enable_lockless_io: Enable lockless (BQL free) acceess.
+ *
+ * Enable BQL-free access for devices that are well prepared to handle
+ * locking during I/O themselves: either by doing fine grained locking or
+ * by providing lock-free I/O schemes.
+ *
+ * @mr: the memory region to be updated.
+ */
+void memory_region_enable_lockless_io(MemoryRegion *mr);
+
+/**
* memory_region_add_eventfd: Request an eventfd to be triggered when a word
* is written to a location.
*
diff --git a/system/memory.c b/system/memory.c
index 5646547..44701c4 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -2546,6 +2546,21 @@ void memory_region_clear_flush_coalesced(MemoryRegion *mr)
}
}
+void memory_region_enable_lockless_io(MemoryRegion *mr)
+{
+ mr->lockless_io = true;
+ /*
+ * reentrancy_guard has per device scope, that when enabled
+ * will effectively prevent concurrent access to device's IO
+ * MemoryRegion(s) by not calling accessor callback.
+ *
+ * Turn it off for lock-less IO enabled devices, to allow
+ * concurrent IO.
+ * TODO: remove this when reentrancy_guard becomes per transaction.
+ */
+ mr->disable_reentrancy_guard = true;
+}
+
void memory_region_add_eventfd(MemoryRegion *mr,
hwaddr addr,
unsigned size,
diff --git a/system/physmem.c b/system/physmem.c
index e5dd760..f498572 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2900,7 +2900,7 @@ bool prepare_mmio_access(MemoryRegion *mr)
{
bool release_lock = false;
- if (!bql_locked()) {
+ if (!bql_locked() && !mr->lockless_io) {
bql_lock();
release_lock = true;
}