History

KVM: X86: Implement ring-based dirty memory tracking

This patch is heavily based on previous work from Lei Cao <lei.cao@stratus.com> and Paolo Bonzini <pbonzini@redhat.com>. [1] KVM currently uses large bitmaps to track dirty memory. These bitmaps are copied to userspace when userspace queries KVM for its dirty page information. The use of bitmaps is mostly sufficient for live migration, as large parts of memory are be dirtied from one log-dirty pass to another. However, in a checkpointing system, the number of dirty pages is small and in fact it is often bounded---the VM is paused when it has dirtied a pre-defined number of pages. Traversing a large, sparsely populated bitmap to find set bits is time-consuming, as is copying the bitmap to user-space. A similar issue will be there for live migration when the guest memory is huge while the page dirty procedure is trivial. In that case for each dirty sync we need to pull the whole dirty bitmap to userspace and analyse every bit even if it's mostly zeros. The preferred data structure for above scenarios is a dense list of guest frame numbers (GFN). This patch series stores the dirty list in kernel memory that can be memory mapped into userspace to allow speedy harvesting. This patch enables dirty ring for X86 only. However it should be easily extended to other archs as well. [1] https://patchwork.kernel.org/patch/10471409/

Peter Xu committed 6 years ago

Commit fb04a1e1 parent 28bd72614 files · +662 −3Browse files

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

Unified · Split

include/uapi/linux/kvm.h+53−0
@@ -250,6 +250,7 @@ struct kvm_hyperv_exit { · 249 unmodified lines
250#define KVM_EXIT_ARM_NISV 28250#define KVM_EXIT_ARM_NISV 28
251#define KVM_EXIT_X86_RDMSR 29251#define KVM_EXIT_X86_RDMSR 29
252#define KVM_EXIT_X86_WRMSR 30252#define KVM_EXIT_X86_WRMSR 30
253#define KVM_EXIT_DIRTY_RING_FULL 31
253 254
254/* For KVM_EXIT_INTERNAL_ERROR */255/* For KVM_EXIT_INTERNAL_ERROR */
255/* Emulate instruction failed. */256/* Emulate instruction failed. */
@@ -1054,6 +1055,7 @@ struct kvm_ppc_resize_hpt { · 798 unmodified lines
1054#define KVM_CAP_X86_MSR_FILTER 1891055#define KVM_CAP_X86_MSR_FILTER 189
1055#define KVM_CAP_ENFORCE_PV_FEATURE_CPUID 1901056#define KVM_CAP_ENFORCE_PV_FEATURE_CPUID 190
1056#define KVM_CAP_SYS_HYPERV_CPUID 1911057#define KVM_CAP_SYS_HYPERV_CPUID 191
1058#define KVM_CAP_DIRTY_LOG_RING 192
1057 1059
1058#ifdef KVM_CAP_IRQ_ROUTING1060#ifdef KVM_CAP_IRQ_ROUTING
1059 1061
@@ -1558,6 +1560,9 @@ struct kvm_pv_cmd { · 498 unmodified lines
1558/* Available with KVM_CAP_X86_MSR_FILTER */1560/* Available with KVM_CAP_X86_MSR_FILTER */
1559#define KVM_X86_SET_MSR_FILTER _IOW(KVMIO, 0xc6, struct kvm_msr_filter)1561#define KVM_X86_SET_MSR_FILTER _IOW(KVMIO, 0xc6, struct kvm_msr_filter)
1560 1562
1563/* Available with KVM_CAP_DIRTY_LOG_RING */
1564#define KVM_RESET_DIRTY_RINGS _IO(KVMIO, 0xc7)
1565
1561/* Secure Encrypted Virtualization command */1566/* Secure Encrypted Virtualization command */
1562enum sev_cmd_id {1567enum sev_cmd_id {
1563 /* Guest initialization commands */1568 /* Guest initialization commands */
@@ -1711,4 +1716,52 @@ struct kvm_hyperv_eventfd { · 147 unmodified lines
1711#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0)1716#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0)
1712#define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1)1717#define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1)
1713 1718
1719/*
1720 * Arch needs to define the macro after implementing the dirty ring
1721 * feature. KVM_DIRTY_LOG_PAGE_OFFSET should be defined as the
1722 * starting page offset of the dirty ring structures.
1723 */
1724#ifndef KVM_DIRTY_LOG_PAGE_OFFSET
1725#define KVM_DIRTY_LOG_PAGE_OFFSET 0
1726#endif
1727
1728/*
1729 * KVM dirty GFN flags, defined as:
1730 *
1731 * |---------------+---------------+--------------|
1732 * | bit 1 (reset) | bit 0 (dirty) | Status |
1733 * |---------------+---------------+--------------|
1734 * | 0 | 0 | Invalid GFN |
1735 * | 0 | 1 | Dirty GFN |
1736 * | 1 | X | GFN to reset |
1737 * |---------------+---------------+--------------|
1738 *
1739 * Lifecycle of a dirty GFN goes like:
1740 *
1741 * dirtied harvested reset
1742 * 00 -----------> 01 -------------> 1X -------+
1743 * ^ |
1744 * | |
1745 * +------------------------------------------+
1746 *
1747 * The userspace program is only responsible for the 01->1X state
1748 * conversion after harvesting an entry. Also, it must not skip any
1749 * dirty bits, so that dirty bits are always harvested in sequence.
1750 */
1751#define KVM_DIRTY_GFN_F_DIRTY BIT(0)
1752#define KVM_DIRTY_GFN_F_RESET BIT(1)
1753#define KVM_DIRTY_GFN_F_MASK 0x3
1754
1755/*
1756 * KVM dirty rings should be mapped at KVM_DIRTY_LOG_PAGE_OFFSET of
1757 * per-vcpu mmaped regions as an array of struct kvm_dirty_gfn. The
1758 * size of the gfn buffer is decided by the first argument when
1759 * enabling KVM_CAP_DIRTY_LOG_RING.
1760 */
1761struct kvm_dirty_gfn {
1762 __u32 flags;
1763 __u32 slot;
1764 __u64 offset;
1765};
1766
1714#endif /* __LINUX_KVM_H */1767#endif /* __LINUX_KVM_H */