mirror of
https://github.com/qemu/qemu.git
synced 2024-11-26 21:23:33 +08:00
V2 migration+virtiofs fixes pull 2021-04-07
A seg fix in virtiofsd, a bunch of fixes for background snapshots, and a migration test fix. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> v2 Fix for !linux build -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEERfXHG0oMt/uXep+pBRYzHrxb/ecFAmBt8YkACgkQBRYzHrxb /efHNBAAismdo7L9iU8hUpvIuFbdLzREoYH3vqbZT6K1zjbmabpqbmMkcPQvj9Oo St9uSdq+6oOMrMi3r0oDpkb2F2csbIdPLQ7a2Y3hZTbzsUJXmI6eoYuSLUNRkvP1 57MoUienK5TsATGFFPd3MuAvwHVOIBZGgg8aeYkC5RiltlQx42IQ4SEtc7yXSrnp TbjS45kd5I13crH4RxNG4X2/cG8McVYCSzEUMPBqbvNFiw2dJTOWr2kzza0jh4tP 0VsgjeqPIoYa4n7LZEs7BgSiXcFcOPbUXvZ/ho7wHOLckhKlbdhJgklBUOom5aqO RZcN1XyPdzcKoxpch3T5d0h/YdEXEQSS7zdLBJDx4bUfb1ZhjEq0RhXqdYJ9YFEG dZTtxaxzW4u8UhPom4Eu0/HNyaqvjyqGrTxCpnS5fHH6pJKtdVhH7WfdEyYHj4lp PkEoKuTPZClk7Fjdsc329vHtIv0+rrWxBWtzFmrPgj13Xy8CkOOmKlYO2BhwI5zb j76s+y3IGNas4pJqhksNBE8AaODZ2IB8hq5dnqb9EsX4gtbOwhXYlA6aZY0EokiS VPbQ76emdE79A/vjArBkfiHsDzUkNe+sBSmreHBxzij/mmaXMP4mcVGew5dNfCFm TQrG9C1oH445yopZIXukcOOZofS3met90m6bbZO0DfAX+wXAAQM= =FKJ4 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20210407b' into staging V2 migration+virtiofs fixes pull 2021-04-07 A seg fix in virtiofsd, a bunch of fixes for background snapshots, and a migration test fix. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> v2 Fix for !linux build # gpg: Signature made Wed 07 Apr 2021 18:53:13 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-20210407b: tests/migration: fix parameter of auto-converge migration migration: Rename 'bs' to 'block' in background snapshot code migration: Pre-fault memory before starting background snasphot migration: Inhibit virtio-balloon for the duration of background snapshot migration: Fix missing qemu_fflush() on buffer file in bg_migration_thread virtiofsd: Fix security.capability comparison Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d8724020dd
@ -66,8 +66,12 @@ static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp,
|
||||
|
||||
static bool virtio_balloon_inhibited(void)
|
||||
{
|
||||
/* Postcopy cannot deal with concurrent discards, so it's special. */
|
||||
return ram_block_discard_is_disabled() || migration_in_incoming_postcopy();
|
||||
/*
|
||||
* Postcopy cannot deal with concurrent discards,
|
||||
* so it's special, as well as background snapshots.
|
||||
*/
|
||||
return ram_block_discard_is_disabled() || migration_in_incoming_postcopy() ||
|
||||
migration_in_bg_snapshot();
|
||||
}
|
||||
|
||||
static void balloon_inflate_page(VirtIOBalloon *balloon,
|
||||
|
@ -70,6 +70,8 @@ bool migration_in_postcopy_after_devices(MigrationState *);
|
||||
void migration_global_dump(Monitor *mon);
|
||||
/* True if incomming migration entered POSTCOPY_INCOMING_DISCARD */
|
||||
bool migration_in_incoming_postcopy(void);
|
||||
/* True if background snapshot is active */
|
||||
bool migration_in_bg_snapshot(void);
|
||||
|
||||
/* migration/block-dirty-bitmap.c */
|
||||
void dirty_bitmap_mig_init(void);
|
||||
|
@ -1976,6 +1976,14 @@ bool migration_in_incoming_postcopy(void)
|
||||
return ps >= POSTCOPY_INCOMING_DISCARD && ps < POSTCOPY_INCOMING_END;
|
||||
}
|
||||
|
||||
bool migration_in_bg_snapshot(void)
|
||||
{
|
||||
MigrationState *s = migrate_get_current();
|
||||
|
||||
return migrate_background_snapshot() &&
|
||||
migration_is_setup_or_active(s->state);
|
||||
}
|
||||
|
||||
bool migration_is_idle(void)
|
||||
{
|
||||
MigrationState *s = current_migration;
|
||||
@ -3812,13 +3820,21 @@ static void *bg_migration_thread(void *opaque)
|
||||
* with vCPUs running and, finally, write stashed non-RAM part of
|
||||
* the vmstate from the buffer to the migration stream.
|
||||
*/
|
||||
s->bioc = qio_channel_buffer_new(128 * 1024);
|
||||
s->bioc = qio_channel_buffer_new(512 * 1024);
|
||||
qio_channel_set_name(QIO_CHANNEL(s->bioc), "vmstate-buffer");
|
||||
fb = qemu_fopen_channel_output(QIO_CHANNEL(s->bioc));
|
||||
object_unref(OBJECT(s->bioc));
|
||||
|
||||
update_iteration_initial_status(s);
|
||||
|
||||
/*
|
||||
* Prepare for tracking memory writes with UFFD-WP - populate
|
||||
* RAM pages before protecting.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
ram_write_tracking_prepare();
|
||||
#endif
|
||||
|
||||
qemu_savevm_state_header(s->to_dst_file);
|
||||
qemu_savevm_state_setup(s->to_dst_file);
|
||||
|
||||
@ -3866,6 +3882,12 @@ static void *bg_migration_thread(void *opaque)
|
||||
if (qemu_savevm_state_complete_precopy_non_iterable(fb, false, false)) {
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
* Since we are going to get non-iterable state data directly
|
||||
* from s->bioc->data, explicit flush is needed here.
|
||||
*/
|
||||
qemu_fflush(fb);
|
||||
|
||||
/* Now initialize UFFD context and start tracking RAM writes */
|
||||
if (ram_write_tracking_start()) {
|
||||
goto fail;
|
||||
|
119
migration/ram.c
119
migration/ram.c
@ -1455,7 +1455,7 @@ static RAMBlock *poll_fault_page(RAMState *rs, ram_addr_t *offset)
|
||||
{
|
||||
struct uffd_msg uffd_msg;
|
||||
void *page_address;
|
||||
RAMBlock *bs;
|
||||
RAMBlock *block;
|
||||
int res;
|
||||
|
||||
if (!migrate_background_snapshot()) {
|
||||
@ -1468,9 +1468,9 @@ static RAMBlock *poll_fault_page(RAMState *rs, ram_addr_t *offset)
|
||||
}
|
||||
|
||||
page_address = (void *)(uintptr_t) uffd_msg.arg.pagefault.address;
|
||||
bs = qemu_ram_block_from_host(page_address, false, offset);
|
||||
assert(bs && (bs->flags & RAM_UF_WRITEPROTECT) != 0);
|
||||
return bs;
|
||||
block = qemu_ram_block_from_host(page_address, false, offset);
|
||||
assert(block && (block->flags & RAM_UF_WRITEPROTECT) != 0);
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1526,7 +1526,7 @@ bool ram_write_tracking_compatible(void)
|
||||
{
|
||||
const uint64_t uffd_ioctls_mask = BIT(_UFFDIO_WRITEPROTECT);
|
||||
int uffd_fd;
|
||||
RAMBlock *bs;
|
||||
RAMBlock *block;
|
||||
bool ret = false;
|
||||
|
||||
/* Open UFFD file descriptor */
|
||||
@ -1537,15 +1537,15 @@ bool ram_write_tracking_compatible(void)
|
||||
|
||||
RCU_READ_LOCK_GUARD();
|
||||
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(bs) {
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||
uint64_t uffd_ioctls;
|
||||
|
||||
/* Nothing to do with read-only and MMIO-writable regions */
|
||||
if (bs->mr->readonly || bs->mr->rom_device) {
|
||||
if (block->mr->readonly || block->mr->rom_device) {
|
||||
continue;
|
||||
}
|
||||
/* Try to register block memory via UFFD-IO to track writes */
|
||||
if (uffd_register_memory(uffd_fd, bs->host, bs->max_length,
|
||||
if (uffd_register_memory(uffd_fd, block->host, block->max_length,
|
||||
UFFDIO_REGISTER_MODE_WP, &uffd_ioctls)) {
|
||||
goto out;
|
||||
}
|
||||
@ -1560,6 +1560,55 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ram_block_populate_pages: populate memory in the RAM block by reading
|
||||
* an integer from the beginning of each page.
|
||||
*
|
||||
* Since it's solely used for userfault_fd WP feature, here we just
|
||||
* hardcode page size to qemu_real_host_page_size.
|
||||
*
|
||||
* @block: RAM block to populate
|
||||
*/
|
||||
static void ram_block_populate_pages(RAMBlock *block)
|
||||
{
|
||||
char *ptr = (char *) block->host;
|
||||
|
||||
for (ram_addr_t offset = 0; offset < block->used_length;
|
||||
offset += qemu_real_host_page_size) {
|
||||
char tmp = *(ptr + offset);
|
||||
|
||||
/* Don't optimize the read out */
|
||||
asm volatile("" : "+r" (tmp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ram_write_tracking_prepare: prepare for UFFD-WP memory tracking
|
||||
*/
|
||||
void ram_write_tracking_prepare(void)
|
||||
{
|
||||
RAMBlock *block;
|
||||
|
||||
RCU_READ_LOCK_GUARD();
|
||||
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||
/* Nothing to do with read-only and MMIO-writable regions */
|
||||
if (block->mr->readonly || block->mr->rom_device) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate pages of the RAM block before enabling userfault_fd
|
||||
* write protection.
|
||||
*
|
||||
* This stage is required since ioctl(UFFDIO_WRITEPROTECT) with
|
||||
* UFFDIO_WRITEPROTECT_MODE_WP mode setting would silently skip
|
||||
* pages with pte_none() entries in page table.
|
||||
*/
|
||||
ram_block_populate_pages(block);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ram_write_tracking_start: start UFFD-WP memory tracking
|
||||
*
|
||||
@ -1569,7 +1618,7 @@ int ram_write_tracking_start(void)
|
||||
{
|
||||
int uffd_fd;
|
||||
RAMState *rs = ram_state;
|
||||
RAMBlock *bs;
|
||||
RAMBlock *block;
|
||||
|
||||
/* Open UFFD file descriptor */
|
||||
uffd_fd = uffd_create_fd(UFFD_FEATURE_PAGEFAULT_FLAG_WP, true);
|
||||
@ -1580,27 +1629,27 @@ int ram_write_tracking_start(void)
|
||||
|
||||
RCU_READ_LOCK_GUARD();
|
||||
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(bs) {
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||
/* Nothing to do with read-only and MMIO-writable regions */
|
||||
if (bs->mr->readonly || bs->mr->rom_device) {
|
||||
if (block->mr->readonly || block->mr->rom_device) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Register block memory with UFFD to track writes */
|
||||
if (uffd_register_memory(rs->uffdio_fd, bs->host,
|
||||
bs->max_length, UFFDIO_REGISTER_MODE_WP, NULL)) {
|
||||
if (uffd_register_memory(rs->uffdio_fd, block->host,
|
||||
block->max_length, UFFDIO_REGISTER_MODE_WP, NULL)) {
|
||||
goto fail;
|
||||
}
|
||||
/* Apply UFFD write protection to the block memory range */
|
||||
if (uffd_change_protection(rs->uffdio_fd, bs->host,
|
||||
bs->max_length, true, false)) {
|
||||
if (uffd_change_protection(rs->uffdio_fd, block->host,
|
||||
block->max_length, true, false)) {
|
||||
goto fail;
|
||||
}
|
||||
bs->flags |= RAM_UF_WRITEPROTECT;
|
||||
memory_region_ref(bs->mr);
|
||||
block->flags |= RAM_UF_WRITEPROTECT;
|
||||
memory_region_ref(block->mr);
|
||||
|
||||
trace_ram_write_tracking_ramblock_start(bs->idstr, bs->page_size,
|
||||
bs->host, bs->max_length);
|
||||
trace_ram_write_tracking_ramblock_start(block->idstr, block->page_size,
|
||||
block->host, block->max_length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1608,19 +1657,20 @@ int ram_write_tracking_start(void)
|
||||
fail:
|
||||
error_report("ram_write_tracking_start() failed: restoring initial memory state");
|
||||
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(bs) {
|
||||
if ((bs->flags & RAM_UF_WRITEPROTECT) == 0) {
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||
if ((block->flags & RAM_UF_WRITEPROTECT) == 0) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* In case some memory block failed to be write-protected
|
||||
* remove protection and unregister all succeeded RAM blocks
|
||||
*/
|
||||
uffd_change_protection(rs->uffdio_fd, bs->host, bs->max_length, false, false);
|
||||
uffd_unregister_memory(rs->uffdio_fd, bs->host, bs->max_length);
|
||||
uffd_change_protection(rs->uffdio_fd, block->host, block->max_length,
|
||||
false, false);
|
||||
uffd_unregister_memory(rs->uffdio_fd, block->host, block->max_length);
|
||||
/* Cleanup flags and remove reference */
|
||||
bs->flags &= ~RAM_UF_WRITEPROTECT;
|
||||
memory_region_unref(bs->mr);
|
||||
block->flags &= ~RAM_UF_WRITEPROTECT;
|
||||
memory_region_unref(block->mr);
|
||||
}
|
||||
|
||||
uffd_close_fd(uffd_fd);
|
||||
@ -1634,24 +1684,25 @@ fail:
|
||||
void ram_write_tracking_stop(void)
|
||||
{
|
||||
RAMState *rs = ram_state;
|
||||
RAMBlock *bs;
|
||||
RAMBlock *block;
|
||||
|
||||
RCU_READ_LOCK_GUARD();
|
||||
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(bs) {
|
||||
if ((bs->flags & RAM_UF_WRITEPROTECT) == 0) {
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||
if ((block->flags & RAM_UF_WRITEPROTECT) == 0) {
|
||||
continue;
|
||||
}
|
||||
/* Remove protection and unregister all affected RAM blocks */
|
||||
uffd_change_protection(rs->uffdio_fd, bs->host, bs->max_length, false, false);
|
||||
uffd_unregister_memory(rs->uffdio_fd, bs->host, bs->max_length);
|
||||
uffd_change_protection(rs->uffdio_fd, block->host, block->max_length,
|
||||
false, false);
|
||||
uffd_unregister_memory(rs->uffdio_fd, block->host, block->max_length);
|
||||
|
||||
trace_ram_write_tracking_ramblock_stop(bs->idstr, bs->page_size,
|
||||
bs->host, bs->max_length);
|
||||
trace_ram_write_tracking_ramblock_stop(block->idstr, block->page_size,
|
||||
block->host, block->max_length);
|
||||
|
||||
/* Cleanup flags and remove reference */
|
||||
bs->flags &= ~RAM_UF_WRITEPROTECT;
|
||||
memory_region_unref(bs->mr);
|
||||
block->flags &= ~RAM_UF_WRITEPROTECT;
|
||||
memory_region_unref(block->mr);
|
||||
}
|
||||
|
||||
/* Finally close UFFD file descriptor */
|
||||
|
@ -82,6 +82,7 @@ void colo_incoming_start_dirty_log(void);
|
||||
/* Background snapshot */
|
||||
bool ram_write_tracking_available(void);
|
||||
bool ram_write_tracking_compatible(void);
|
||||
void ram_write_tracking_prepare(void);
|
||||
int ram_write_tracking_start(void);
|
||||
void ram_write_tracking_stop(void);
|
||||
|
||||
|
@ -102,7 +102,7 @@ class Engine(object):
|
||||
info.get("downtime", 0),
|
||||
info.get("expected-downtime", 0),
|
||||
info.get("setup-time", 0),
|
||||
info.get("x-cpu-throttle-percentage", 0),
|
||||
info.get("cpu-throttle-percentage", 0),
|
||||
)
|
||||
|
||||
def _migrate(self, hardware, scenario, src, dst, connect_uri):
|
||||
@ -135,7 +135,7 @@ class Engine(object):
|
||||
"state": True }
|
||||
])
|
||||
resp = src.command("migrate-set-parameters",
|
||||
x_cpu_throttle_increment=scenario._auto_converge_step)
|
||||
cpu_throttle_increment=scenario._auto_converge_step)
|
||||
|
||||
if scenario._post_copy:
|
||||
resp = src.command("migrate-set-capabilities",
|
||||
|
@ -2636,7 +2636,8 @@ static void parse_xattrmap(struct lo_data *lo)
|
||||
strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(lo->xattr_security_capability, "security.capability")) {
|
||||
if (!lo->xattr_security_capability ||
|
||||
!strcmp(lo->xattr_security_capability, "security.capability")) {
|
||||
/* 1-1 mapping, don't need to do anything */
|
||||
free(lo->xattr_security_capability);
|
||||
lo->xattr_security_capability = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user