Skip to content

Commit c862626

Browse files
Keqian ZhuMarc Zyngier
authored andcommitted
KVM: arm64: Support enabling dirty log gradually in small chunks
There is already support of enabling dirty log gradually in small chunks for x86 in commit 3c9bd40 ("KVM: x86: enable dirty log gradually in small chunks"). This adds support for arm64. x86 still writes protect all huge pages when DIRTY_LOG_INITIALLY_ALL_SET is enabled. However, for arm64, both huge pages and normal pages can be write protected gradually by userspace. Under the Huawei Kunpeng 920 2.6GHz platform, I did some tests on 128G Linux VMs with different page size. The memory pressure is 127G in each case. The time taken of memory_global_dirty_log_start in QEMU is listed below: Page Size Before After Optimization 4K 650ms 1.8ms 2M 4ms 1.8ms 1G 2ms 1.8ms Besides the time reduction, the biggest improvement is that we will minimize the performance side effect (because of dissolving huge pages and marking memslots dirty) on guest after enabling dirty log. Signed-off-by: Keqian Zhu <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0529c90 commit c862626

File tree

3 files changed

+14
-3
lines changed

3 files changed

+14
-3
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5777,7 +5777,7 @@ will be initialized to 1 when created. This also improves performance because
57775777
dirty logging can be enabled gradually in small chunks on the first call
57785778
to KVM_CLEAR_DIRTY_LOG. KVM_DIRTY_LOG_INITIALLY_SET depends on
57795779
KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (it is also only available on
5780-
x86 for now).
5780+
x86 and arm64 for now).
57815781

57825782
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 was previously available under the name
57835783
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT, but the implementation had bugs that make

arch/arm64/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
4747
#define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
4848

49+
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
50+
KVM_DIRTY_LOG_INITIALLY_SET)
51+
4952
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
5053

5154
extern unsigned int kvm_sve_max_vl;

arch/arm64/kvm/mmu.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,8 +2277,16 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
22772277
* allocated dirty_bitmap[], dirty pages will be tracked while the
22782278
* memory slot is write protected.
22792279
*/
2280-
if (change != KVM_MR_DELETE && mem->flags & KVM_MEM_LOG_DIRTY_PAGES)
2281-
kvm_mmu_wp_memory_region(kvm, mem->slot);
2280+
if (change != KVM_MR_DELETE && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
2281+
/*
2282+
* If we're with initial-all-set, we don't need to write
2283+
* protect any pages because they're all reported as dirty.
2284+
* Huge pages and normal pages will be write protect gradually.
2285+
*/
2286+
if (!kvm_dirty_log_manual_protect_and_init_set(kvm)) {
2287+
kvm_mmu_wp_memory_region(kvm, mem->slot);
2288+
}
2289+
}
22822290
}
22832291

22842292
int kvm_arch_prepare_memory_region(struct kvm *kvm,

0 commit comments

Comments
 (0)