Commit df60cb2e authored by Dong Yang's avatar Dong Yang Committed by Anup Patel
Browse files

KVM: riscv: Support enabling dirty log gradually in small chunks



There is already support of enabling dirty log gradually in small chunks
for x86 in commit 3c9bd400 ("KVM: x86: enable dirty log gradually in
small chunks") and c862626e ("KVM: arm64: Support enabling dirty log
gradually in small chunks"). This adds support for riscv.

x86 and arm64 writes protect both huge pages and normal pages now, so
riscv protect also protects both huge pages and normal pages.

On a nested virtualization setup (RISC-V KVM running inside a QEMU VM
on an [Intel® Core™ i5-12500H] host), I did some tests with a 2G Linux
VM using different backing page sizes. The time taken for
memory_global_dirty_log_start in the L2 QEMU is listed below:

Page Size      Before    After Optimization
  4K            4490.23ms         31.94ms
  2M             48.97ms          45.46ms
  1G             28.40ms          30.93ms

Signed-off-by: default avatarQuan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: default avatarDong Yang <dayss1224@gmail.com>
Reviewed-by: default avatarAnup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20251103062825.9084-1-dayss1224@gmail.com


Signed-off-by: default avatarAnup Patel <anup@brainfault.org>
parent a2483d5d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8028,7 +8028,7 @@ will be initialized to 1 when created. This also improves performance because
dirty logging can be enabled gradually in small chunks on the first call
to KVM_CLEAR_DIRTY_LOG.  KVM_DIRTY_LOG_INITIALLY_SET depends on
KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (it is also only available on
x86 and arm64 for now).
x86, arm64 and riscv for now).

KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 was previously available under the name
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT, but the implementation had bugs that make
+3 −0
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@
					 BIT(IRQ_VS_TIMER) | \
					 BIT(IRQ_VS_EXT))

#define KVM_DIRTY_LOG_MANUAL_CAPS	(KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
					 KVM_DIRTY_LOG_INITIALLY_SET)

struct kvm_vm_stat {
	struct kvm_vm_stat_generic generic;
};
+4 −1
Original line number Diff line number Diff line
@@ -161,9 +161,12 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
	 * allocated dirty_bitmap[], dirty pages will be tracked while
	 * the memory slot is write protected.
	 */
	if (change != KVM_MR_DELETE && new->flags & KVM_MEM_LOG_DIRTY_PAGES)
	if (change != KVM_MR_DELETE && new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
		if (kvm_dirty_log_manual_protect_and_init_set(kvm))
			return;
		mmu_wp_memory_region(kvm, new->id);
	}
}

int kvm_arch_prepare_memory_region(struct kvm *kvm,
				const struct kvm_memory_slot *old,