Re: [PATCH v5 11/15] KVM: arm64: Reserve dirty ring space for the HDBSS buffer

From: Tian Zheng

Date: Fri Nov 06 2026 - 05:36:28 EST




On 11/2/2026 10:54 PM, Leonardo Bras wrote:
On Tue, Sep 29, 2026 at 06:36:51PM +0800, Tian Zheng wrote:
The dirty ring reserves room for CPU-side dirty buffers via
kvm_cpu_dirty_log_size(). Report the HDBSS buffer entry count
through it, so a full buffer flush always fits in the ring.

Pin the HDBSS buffer size to PAGE_SIZE when dirty-ring is enabled,
via kvm_arch_dirty_ring_size_updated(): a larger buffer only
shrinks the soft_limit and forces more frequent userspace drains.

Signed-off-by: Tian Zheng <zhengtian10@xxxxxxxxxx>
---
arch/arm64/kvm/arm.c | 8 ++++++++
arch/arm64/kvm/mmu.c | 8 ++++++++
2 files changed, 16 insertions(+)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 9d7bdece149a..5a7046acb62e 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -215,6 +215,14 @@ static int kvm_arm_default_max_vcpus(void)
return vgic_present ? kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
}

+void kvm_arch_dirty_ring_size_updated(struct kvm *kvm)
+{
+ if (!system_supports_hdbss())
+ return;
+
+ kvm->arch.hdbss_buffer_size = KVM_ARM_HDBSS_DEFAULT_SIZE;
+}
+

On the same subject as a previous patch:
I don't think this is the best approach, on top of adding a new weak
function to take care.

Maybe during the dirty-ring allocation, on vcpu creation, we could take
into account the requested dirty-ring size, and just allocate the HDBSS
buffer taking that into account. That would make it simpler, don't you
agree?

Thanks!
Leo

Hi Leo,

The "set once" guard we're discussing comes from the patch that adds the
ioctl, and it isn't really needed. We discussed this earlier [1]: we can
just initialize hdbss_buffer_size to PAGE_SIZE at VM creation and let
the ring reservation use it directly. **That also means
kvm_arch_dirty_ring_size_updated() can be removed.** Thanks for your suggestion.

As for why PAGE_SIZE is the right value in ring mode: the HDBSS buffer
is flushed on every VM exit, so a larger buffer doesn't reduce the flush
frequency. It only inflates the ring reservation (64 + size/
sizeof(u64)), which shrinks the soft_limit and forces more frequent
exits to userspace for the ring to be drained. Draining the dirty ring
from QEMU is more expensive than draining the HDBSS buffer from the
kernel, so the smallest buffer gives the best performance. In this mode,
a larger buffer provides no benefit to users.

In my tests, I also saw performance degrade when more space is reserved.

[1] https://lore.kernel.org/all/5a096cca-713a-4449-83dc-c763dc06c085@xxxxxxxxxx/

Thanks,
Tian