diff options
author | Igor Mammedov <imammedo@redhat.com> | 2025-08-14 18:05:53 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2025-08-29 12:48:14 +0200 |
commit | 73c520b088878682e2d3b7fa19a6366ec8d39829 (patch) | |
tree | 4766e598cc92df2e3f4c565ff3e451e2f215ea04 | |
parent | 87511341c30d8c9c77178db16491a0ccacc5d64b (diff) | |
download | qemu-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.h | 12 | ||||
-rw-r--r-- | system/memory.c | 15 | ||||
-rw-r--r-- | system/physmem.c | 2 |
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; } |