History

KVM: x86: enable dirty log gradually in small chunks

It could take kvm->mmu_lock for an extended period of time when enabling dirty log for the first time. The main cost is to clear all the D-bits of last level SPTEs. This situation can benefit from manual dirty log protect as well, which can reduce the mmu_lock time taken. The sequence is like this: 1. Initialize all the bits of the dirty bitmap to 1 when enabling dirty log for the first time 2. Only write protect the huge pages 3. KVM_GET_DIRTY_LOG returns the dirty bitmap info 4. KVM_CLEAR_DIRTY_LOG will clear D-bit for each of the leaf level SPTEs gradually in small chunks Under the Intel(R) Xeon(R) Gold 6152 CPU @ 2.10GHz environment, I did some tests with a 128G windows VM and counted the time taken of memory_global_dirty_log_start, here is the numbers: VM Size Before After optimization 128G 460ms 10ms

Jay Zhou committed 6 years ago

Commit 3c9bd401 parent 0be44358 files · +73 −20Browse files

Showing the changes to include/linux (1 of 8 files). Show all

Unified · Split

include/linux/kvm_host.h+10−1
@@ -360,6 +360,10 @@ static inline unsigned long *kvm_second_dirty_bitmap(struct kvm_memory_slot *mem · 359 unmodified lines
360360 return memslot->dirty_bitmap + len / sizeof(*memslot->dirty_bitmap);
361361 }
362362
363+#ifndef KVM_DIRTY_LOG_MANUAL_CAPS
364+#define KVM_DIRTY_LOG_MANUAL_CAPS KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE
365+#endif
366+
363367 struct kvm_s390_adapter_int {
364368 u64 ind_addr;
365369 u64 summary_addr;
@@ -493,7 +497,7 @@ struct kvm { · 127 unmodified lines
493497 #endif
494498 long tlbs_dirty;
495499 struct list_head devices;
496− bool manual_dirty_log_protect;
500+ u64 manual_dirty_log_protect;
497501 struct dentry *debugfs_dentry;
498502 struct kvm_stat_data **debugfs_stat_data;
499503 struct srcu_struct srcu;
@@ -527,6 +531,11 @@ struct kvm { · 27 unmodified lines
527531 #define vcpu_err(vcpu, fmt, ...) \
528532 kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
529533
534+static inline bool kvm_dirty_log_manual_protect_and_init_set(struct kvm *kvm)
535+{
536+ return !!(kvm->manual_dirty_log_protect & KVM_DIRTY_LOG_INITIALLY_SET);
537+}
538+
530539 static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx)
531540 {
532541 return srcu_dereference_check(kvm->buses[idx], &kvm->srcu,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t