Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/201…
Browse files Browse the repository at this point in the history
…70316' into staging

migration/next for 20170316

# gpg: Signature made Thu 16 Mar 2017 08:21:51 GMT
# gpg:                using RSA key 0xF487EF185872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>"
# gpg:                 aka "Juan Quintela <quintela@trasno.org>"
# Primary key fingerprint: 1899 FF8E DEBF 58CC EE03  4B82 F487 EF18 5872 D723

* remotes/juanquintela/tags/migration/20170316:
  postcopy: Check for shared memory
  RAMBlocks: qemu_ram_is_shared
  vmstate: fix failed iotests case 68 and 91
  migration/block: Avoid invoking blk_drain too frequently
  migration: use "" as the default for tls-creds/hostname
  Change the method to calculate dirty-pages-rate

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Mar 16, 2017
2 parents 094a9a7 + 8679638 commit c5e737e
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 13 deletions.
5 changes: 5 additions & 0 deletions exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,11 @@ const char *qemu_ram_get_idstr(RAMBlock *rb)
return rb->idstr;
}

bool qemu_ram_is_shared(RAMBlock *rb)
{
return rb->flags & RAM_SHARED;
}

/* Called with iothread lock held. */
void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
{
Expand Down
1 change: 1 addition & 0 deletions include/exec/cpu-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
void qemu_ram_set_idstr(RAMBlock *block, const char *name, DeviceState *dev);
void qemu_ram_unset_idstr(RAMBlock *block);
const char *qemu_ram_get_idstr(RAMBlock *rb);
bool qemu_ram_is_shared(RAMBlock *rb);
size_t qemu_ram_pagesize(RAMBlock *block);
size_t qemu_ram_pagesize_largest(void);

Expand Down
5 changes: 4 additions & 1 deletion include/exec/ram_addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start,
static inline
uint64_t cpu_physical_memory_sync_dirty_bitmap(unsigned long *dest,
ram_addr_t start,
ram_addr_t length)
ram_addr_t length,
int64_t *real_dirty_pages)
{
ram_addr_t addr;
unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS);
Expand All @@ -379,6 +380,7 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(unsigned long *dest,
if (src[idx][offset]) {
unsigned long bits = atomic_xchg(&src[idx][offset], 0);
unsigned long new_dirty;
*real_dirty_pages += ctpopl(bits);
new_dirty = ~dest[k];
dest[k] |= bits;
new_dirty &= bits;
Expand All @@ -398,6 +400,7 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(unsigned long *dest,
start + addr,
TARGET_PAGE_SIZE,
DIRTY_MEMORY_MIGRATION)) {
*real_dirty_pages += 1;
long k = (start + addr) >> TARGET_PAGE_BITS;
if (!test_and_set_bit(k, dest)) {
num_dirty++;
Expand Down
3 changes: 3 additions & 0 deletions migration/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,9 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
}

bdrv_reset_dirty_bitmap(bmds->dirty_bitmap, sector, nr_sectors);
sector += nr_sectors;
bmds->cur_dirty = sector;

break;
}
sector += BDRV_SECTORS_PER_DIRTY_CHUNK;
Expand Down
4 changes: 4 additions & 0 deletions migration/migration.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ MigrationState *migrate_get_current(void)

if (!once) {
qemu_mutex_init(&current_migration.src_page_req_mutex);
current_migration.parameters.tls_creds = g_strdup("");
current_migration.parameters.tls_hostname = g_strdup("");
once = true;
}
return &current_migration;
Expand Down Expand Up @@ -458,6 +460,7 @@ void migration_channel_process_incoming(MigrationState *s,
ioc, object_get_typename(OBJECT(ioc)));

if (s->parameters.tls_creds &&
*s->parameters.tls_creds &&
!object_dynamic_cast(OBJECT(ioc),
TYPE_QIO_CHANNEL_TLS)) {
Error *local_err = NULL;
Expand All @@ -480,6 +483,7 @@ void migration_channel_connect(MigrationState *s,
ioc, object_get_typename(OBJECT(ioc)), hostname);

if (s->parameters.tls_creds &&
*s->parameters.tls_creds &&
!object_dynamic_cast(OBJECT(ioc),
TYPE_QIO_CHANNEL_TLS)) {
Error *local_err = NULL;
Expand Down
18 changes: 18 additions & 0 deletions migration/postcopy-ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ static bool ufd_version_check(int ufd)
return true;
}

/* Callback from postcopy_ram_supported_by_host block iterator.
*/
static int test_range_shared(const char *block_name, void *host_addr,
ram_addr_t offset, ram_addr_t length, void *opaque)
{
if (qemu_ram_is_shared(qemu_ram_block_by_name(block_name))) {
error_report("Postcopy on shared RAM (%s) is not yet supported",
block_name);
return 1;
}
return 0;
}

/*
* Note: This has the side effect of munlock'ing all of RAM, that's
* normally fine since if the postcopy succeeds it gets turned back on at the
Expand Down Expand Up @@ -127,6 +140,11 @@ bool postcopy_ram_supported_by_host(void)
goto out;
}

/* We don't support postcopy with shared RAM yet */
if (qemu_ram_foreach_block(test_range_shared, NULL)) {
goto out;
}

/*
* userfault and mlock don't go together; we'll put it back later if
* it was enabled.
Expand Down
12 changes: 5 additions & 7 deletions migration/ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,18 +576,18 @@ static inline bool migration_bitmap_clear_dirty(ram_addr_t addr)
return ret;
}

static int64_t num_dirty_pages_period;
static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length)
{
unsigned long *bitmap;
bitmap = atomic_rcu_read(&migration_bitmap_rcu)->bmap;
migration_dirty_pages +=
cpu_physical_memory_sync_dirty_bitmap(bitmap, start, length);
migration_dirty_pages += cpu_physical_memory_sync_dirty_bitmap(bitmap,
start, length, &num_dirty_pages_period);
}

/* Fix me: there are too many global variables used in migration process. */
static int64_t start_time;
static int64_t bytes_xfer_prev;
static int64_t num_dirty_pages_period;
static uint64_t xbzrle_cache_miss_prev;
static uint64_t iterations_prev;

Expand Down Expand Up @@ -620,7 +620,6 @@ uint64_t ram_pagesize_summary(void)
static void migration_bitmap_sync(void)
{
RAMBlock *block;
uint64_t num_dirty_pages_init = migration_dirty_pages;
MigrationState *s = migrate_get_current();
int64_t end_time;
int64_t bytes_xfer_now;
Expand All @@ -646,9 +645,8 @@ static void migration_bitmap_sync(void)
rcu_read_unlock();
qemu_mutex_unlock(&migration_bitmap_mutex);

trace_migration_bitmap_sync_end(migration_dirty_pages
- num_dirty_pages_init);
num_dirty_pages_period += migration_dirty_pages - num_dirty_pages_init;
trace_migration_bitmap_sync_end(num_dirty_pages_period);

end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);

/* more than 1 second = 1000 millisecons */
Expand Down
2 changes: 1 addition & 1 deletion migration/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void migration_tls_channel_connect(MigrationState *s,
return;
}

if (s->parameters.tls_hostname) {
if (s->parameters.tls_hostname && *s->parameters.tls_hostname) {
hostname = s->parameters.tls_hostname;
}
if (!hostname) {
Expand Down
8 changes: 4 additions & 4 deletions migration/vmstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
vmstate_handle_alloc(first_elem, field, opaque);
if (field->flags & VMS_POINTER) {
first_elem = *(void **)first_elem;
assert(first_elem || !n_elems);
assert(first_elem || !n_elems || !size);
}
for (i = 0; i < n_elems; i++) {
void *curr_elem = first_elem + size * i;

if (field->flags & VMS_ARRAY_OF_POINTER) {
curr_elem = *(void **)curr_elem;
}
if (!curr_elem) {
if (!curr_elem && size) {
/* if null pointer check placeholder and do not follow */
assert(field->flags & VMS_ARRAY_OF_POINTER);
ret = vmstate_info_nullptr.get(f, curr_elem, size, NULL);
Expand Down Expand Up @@ -325,7 +325,7 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
trace_vmstate_save_state_loop(vmsd->name, field->name, n_elems);
if (field->flags & VMS_POINTER) {
first_elem = *(void **)first_elem;
assert(first_elem || !n_elems);
assert(first_elem || !n_elems || !size);
}
for (i = 0; i < n_elems; i++) {
void *curr_elem = first_elem + size * i;
Expand All @@ -336,7 +336,7 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
assert(curr_elem);
curr_elem = *(void **)curr_elem;
}
if (!curr_elem) {
if (!curr_elem && size) {
/* if null pointer write placeholder and do not follow */
assert(field->flags & VMS_ARRAY_OF_POINTER);
vmstate_info_nullptr.put(f, curr_elem, size, NULL, NULL);
Expand Down
4 changes: 4 additions & 0 deletions qapi-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1059,13 +1059,17 @@
# credentials must be for a 'server' endpoint. Setting this
# will enable TLS for all migrations. The default is unset,
# resulting in unsecured migration at the QEMU level. (Since 2.7)
# An empty string means that QEMU will use plain text mode for
# migration, rather than TLS (Since 2.9)
#
# @tls-hostname: hostname of the target host for the migration. This
# is required when using x509 based TLS credentials and the
# migration URI does not already include a hostname. For
# example if using fd: or exec: based migration, the
# hostname must be provided so that the server's x509
# certificate identity can be validated. (Since 2.7)
# An empty string means that QEMU will use the hostname
# associated with the migration URI, if any. (Since 2.9)
#
# @max-bandwidth: to set maximum speed for migration. maximum speed in
# bytes per second. (Since 2.8)
Expand Down

0 comments on commit c5e737e

Please sign in to comment.