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
Showing the changes to include/uapi/linux (1 of 8 files). Show all
Unified · Split
| @@ -1628,4 +1628,7 @@ struct kvm_hyperv_eventfd { · 1627 unmodified lines | ||
| 1628 | 1628 | #define KVM_HYPERV_CONN_ID_MASK 0x00ffffff |
| 1629 | 1629 | #define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0) |
| 1630 | 1630 | |
| 1631 | +#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0) | |
| 1632 | +#define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1) | |
| 1633 | + | |
| 1631 | 1634 | #endif /* __LINUX_KVM_H */ |