Migration pull 2021-05-13

Fix of the 2021-05-11 version, with a fix to build on the armhf
 cross.
 
 The largest change in this set is David's changes for ram block size
 changing; then there's a pile of other cleanups and fixes.
 
 Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEERfXHG0oMt/uXep+pBRYzHrxb/ecFAmCdY4YACgkQBRYzHrxb
 /eek0RAAsZhgu4uMQ7dJr9wm6adR0wc8iTc1MVCvHj7WFFsHhS3CLIvJ+JA+B20P
 y4pa57Im2FIKG7h1xbVs9NQHZEfM+TBPKcugHipGP/bsEVKjLhHqhrqEPbGZwuCx
 24Vx97mmKxVWb4ppv+6HCixlj0zdQwdqgAZY0Dgdfo0mJtBrHQtBXmD2uN3JLnW4
 WtsELqr1BORbyKXu+R71EF2qwON5fANO9fxL56Xvg8klwCECi5ntKdoDBq5lS5oc
 TWt/M7yvp1kWukclZvbGDFTH9+/ld1W4iE5CaKpX+5Z57Fu8cOzzsNEvJt7G7Yer
 ceRe7Yf2X+3EJsmllbjmFfsld7v+KzytURCCTX4HaVIiUQV3ARx95fltsEt4Qhyv
 7tGgksC1YFT2GxXxR6vi4eHn8Jpi3yb0vTlWndh5qc5KdBDH8x8Mew+uH72b/0f0
 7zg7Qjs5qck5gSBYrLYDLb2BgPq+2vHgt1E6BHADvN5HB9OgV9Ls0sG56pvoRpK/
 0s8XuT+R8ETlSbG7jHnXghuQpbupObu5n8AlG1go3wO73GIoJ49nR4Dp0ZyT08bJ
 LJopNUnlRdshxxofzQTNgy/8p7k+HiO616bjJ6UuOXTOC10p4kVyIS8hHnYCUyuh
 iPlBjDgSk0v1s5o1eCUmEMh3yfNCGvyePEPyJM6XiGPTZb/yYyI=
 =RJvy
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20210513a' into staging

Migration pull 2021-05-13

Fix of the 2021-05-11 version, with a fix to build on the armhf
cross.

The largest change in this set is David's changes for ram block size
changing; then there's a pile of other cleanups and fixes.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

# gpg: Signature made Thu 13 May 2021 18:36:06 BST
# gpg:                using RSA key 45F5C71B4A0CB7FB977A9FA90516331EBC5BFDE7
# gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" [full]
# Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A  9FA9 0516 331E BC5B FDE7

* remotes/dgilbert/tags/pull-migration-20210513a:
  tests/migration: introduce multifd into guestperf
  tests/qtest/migration-test: Use g_autofree to avoid leaks on error paths
  tests/migration-test: Fix "true" vs true
  migration/ram: Use offset_in_ramblock() in range checks
  migration/multifd: Print used_length of memory block
  migration/ram: Handle RAM block resizes during postcopy
  migration/ram: Simplify host page handling in ram_load_postcopy()
  migration/ram: Discard RAM when growing RAM blocks after ram_postcopy_incoming_init()
  exec: Relax range check in ram_block_discard_range()
  migration/ram: Handle RAM block resizes during precopy
  numa: Make all callbacks of ram block notifiers optional
  numa: Teach ram block notifiers about resizeable ram blocks
  util: vfio-helpers: Factor out and fix processing of existing ram blocks
  migration: Drop redundant query-migrate result @blocked
  migration/ram: Optimize ram_save_host_page()
  migration/ram: Reduce unnecessary rate limiting
  migrate/ram: remove "ram_bulk_stage" and "fpo_enabled"

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-05-14 12:03:46 +01:00
commit 96662996ed
25 changed files with 367 additions and 250 deletions

View file

@ -57,6 +57,7 @@ const char *qemu_ram_get_idstr(RAMBlock *rb);
void *qemu_ram_get_host_addr(RAMBlock *rb);
ram_addr_t qemu_ram_get_offset(RAMBlock *rb);
ram_addr_t qemu_ram_get_used_length(RAMBlock *rb);
ram_addr_t qemu_ram_get_max_length(RAMBlock *rb);
bool qemu_ram_is_shared(RAMBlock *rb);
bool qemu_ram_is_uf_zeroable(RAMBlock *rb);
void qemu_ram_set_uf_zeroable(RAMBlock *rb);

View file

@ -131,7 +131,7 @@ typedef struct IOMMUTLBEvent {
#define RAM_SHARED (1 << 1)
/* Only a portion of RAM (used_length) is actually used, and migrated.
* This used_length size can change across reboots.
* Resizing RAM while migrating can result in the migration being canceled.
*/
#define RAM_RESIZEABLE (1 << 2)
@ -955,7 +955,9 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
* RAM. Accesses into the region will
* modify memory directly. Only an initial
* portion of this RAM is actually used.
* The used size can change across reboots.
* Changing the size while migrating
* can result in the migration being
* canceled.
*
* @mr: the #MemoryRegion to be initialized.
* @owner: the object that tracks the region's reference count
@ -1586,8 +1588,8 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
/* memory_region_ram_resize: Resize a RAM region.
*
* Only legal before guest might have detected the memory size: e.g. on
* incoming migration, or right after reset.
* Resizing RAM while migrating can result in the migration being canceled.
* Care has to be taken if the guest might have already detected the memory.
*
* @mr: a memory region created with @memory_region_init_resizeable_ram.
* @newsize: the new size the region

View file

@ -59,6 +59,16 @@ struct RAMBlock {
*/
unsigned long *clear_bmap;
uint8_t clear_bmap_shift;
/*
* RAM block length that corresponds to the used_length on the migration
* source (after RAM block sizes were synchronized). Especially, after
* starting to run the guest, used_length and postcopy_length can differ.
* Used to register/unregister uffd handlers and as the size of the received
* bitmap. Receiving any page beyond this length will bail out, as it
* could not have been valid on the source.
*/
ram_addr_t postcopy_length;
};
#endif
#endif

View file

@ -65,15 +65,20 @@ void qemu_mutex_lock_ramlist(void);
void qemu_mutex_unlock_ramlist(void);
struct RAMBlockNotifier {
void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size);
void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size);
void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size,
size_t max_size);
void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size,
size_t max_size);
void (*ram_block_resized)(RAMBlockNotifier *n, void *host, size_t old_size,
size_t new_size);
QLIST_ENTRY(RAMBlockNotifier) next;
};
void ram_block_notifier_add(RAMBlockNotifier *n);
void ram_block_notifier_remove(RAMBlockNotifier *n);
void ram_block_notify_add(void *host, size_t size);
void ram_block_notify_remove(void *host, size_t size);
void ram_block_notify_add(void *host, size_t size, size_t max_size);
void ram_block_notify_remove(void *host, size_t size, size_t max_size);
void ram_block_notify_resize(void *host, size_t old_size, size_t new_size);
void ram_block_dump(Monitor *mon);