[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 0/6] migration/ram: Optimize for virtio-mem via RamDiscardMana
[PATCH v2 0/6] migration/ram: Optimize for virtio-mem via RamDiscardManager
Wed, 21 Jul 2021 11:27:53 +0200
virtio-mem exposes a dynamic amount of memory within RAMBlocks by
coordinating with the VM. Memory within a RAMBlock can either get
plugged and consequently used by the VM, or unplugged and consequently no
longer used by the VM. Logical unplug is realized by discarding the
physical memory backing for virtual memory ranges, similar to memory
However, important difference to virtio-balloon are:
a) A virtio-mem device only operates on its assigned memory region /
RAMBlock ("device memory")
b) Initially, all device memory is logically unplugged
c) Virtual machines will never accidentally reuse memory that is currently
logically unplugged. The spec defines most accesses to unplugged memory
as "undefined behavior" -- except reading unplugged memory, which is
currently expected to work, but that will change in the future.
d) The (un)plug granularity is in the range of megabytes -- "memory blocks"
e) The state (plugged/unplugged) of a memory block is always known and
Whenever memory blocks within the RAMBlock get (un)plugged, changes are
communicated via the RamDiscardManager to other QEMU subsystems, most
prominently vfio which updates the DMA mapping accordingly. "Unplugging"
corresponds to "discarding" and "plugging" corresponds to "populating".
While migrating (precopy/postcopy) that state of such memory blocks cannot
change. We never ever want to migrate such logically unplugged memory,
because it can result in an unintended memory consumption both, on the
source (when reading memory from some memory backends) and on the
destination (when writing memory). Further, migration time can be heavily
reduced when skipping logically unplugged blocks and we avoid populating
unnecessary page tables in Linux.
Right now, virtio-mem reuses the free page hinting infrastructure during
precopy to exclude all logically unplugged ("discarded") parts from the
migration stream. However, there are some scenarios that are not handled
properly and need fixing. Further, there are some ugly corner cases in
postcopy code and background snapshotting code that similarly have to
handle such special RAMBlocks.
Let's reuse the RamDiscardManager infrastructure to essentially handle
precopy, postcopy and background snapshots cleanly, which means:
a) In precopy code, always clearing all dirty bits from the bitmap that
correspond to discarded range, whenever we update the dirty bitmap. This
results in logically unplugged memory to never get migrated.
b) In postcopy code, placing a zeropage when requested to handle a page
falling into a discarded range -- because the source will never send it.
c) In background snapshot code, never populating discarded ranges, not even
with the shared zeropage, to avoid unintended memory consumption,
especially in the future with hugetlb and shmem.
Detail: When realizing a virtio-mem devices, it will register the RAM
for migration via vmstate_register_ram(). Further, it will
set itself as the RamDiscardManager for the corresponding memory
region of the RAMBlock via memory_region_set_ram_discard_manager().
Last but not least, memory device code will actually map the
memory region into guest physical address space. So migration
code can always properly identify such RAMBlocks.
Tested with precopy/postcopy on shmem, where even reading unpopulated
memory ranges will populate actual memory and not the shared zeropage.
Tested with background snapshots on anonymous memory, because other
backends are not supported yet with upstream Linux.
Idealy, this should all go via the migration tree.
v1 -> v2:
- "migration/ram: Handle RAMBlocks with a RamDiscardManager on the
-- Added a note how it interacts with the clear_bmap and what we might want
to further optimize in the future when synchronizing bitmaps.
Cc: "Michael S. Tsirkin" <email@example.com>
Cc: Paolo Bonzini <firstname.lastname@example.org>
Cc: Juan Quintela <email@example.com>
Cc: "Dr. David Alan Gilbert" <firstname.lastname@example.org>
Cc: Eduardo Habkost <email@example.com>
Cc: Peter Xu <firstname.lastname@example.org>
Cc: Andrey Gruzdev <email@example.com>
Cc: Marek Kedzierski <firstname.lastname@example.org>
Cc: Wei Yang <email@example.com>
Cc: teawater <firstname.lastname@example.org>
Cc: Alex Williamson <email@example.com>
Cc: Pankaj Gupta <firstname.lastname@example.org>
David Hildenbrand (6):
memory: Introduce replay_discarded callback for RamDiscardManager
virtio-mem: Implement replay_discarded RamDiscardManager callback
migration/ram: Handle RAMBlocks with a RamDiscardManager on the
virtio-mem: Drop precopy notifier
migration/postcopy: Handle RAMBlocks with a RamDiscardManager on the
migration/ram: Handle RAMBlocks with a RamDiscardManager on background
hw/virtio/virtio-mem.c | 92 +++++++++++++--------
include/exec/memory.h | 21 +++++
include/hw/virtio/virtio-mem.h | 3 -
migration/postcopy-ram.c | 25 +++++-
migration/ram.c | 147 ++++++++++++++++++++++++++++++---
migration/ram.h | 1 +
softmmu/memory.c | 11 +++
7 files changed, 246 insertions(+), 54 deletions(-)
- [PATCH v2 0/6] migration/ram: Optimize for virtio-mem via RamDiscardManager,
David Hildenbrand <=
- [PATCH v2 2/6] virtio-mem: Implement replay_discarded RamDiscardManager callback, David Hildenbrand, 2021/07/21
- [PATCH v2 1/6] memory: Introduce replay_discarded callback for RamDiscardManager, David Hildenbrand, 2021/07/21
- [PATCH v2 3/6] migration/ram: Handle RAMBlocks with a RamDiscardManager on the migration source, David Hildenbrand, 2021/07/21
- [PATCH v2 4/6] virtio-mem: Drop precopy notifier, David Hildenbrand, 2021/07/21
- [PATCH v2 5/6] migration/postcopy: Handle RAMBlocks with a RamDiscardManager on the destination, David Hildenbrand, 2021/07/21