migration/next for 20170316

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABCAAGBQJYyksfAAoJEPSH7xhYctcjC2EP/RitHPcaOhaP54TR0SJOgsVa
 eVZ2kqXsy641hL85eVVlXV/lNfCko7nACieGEk/Xo6mZoM3r+ta6gafraUR3fzSJ
 HVCeI9S2UDFO9lc4L3cOSNPJ7+UHae0SfeRikyB/zmltDRda7QIh3SOQ2wTkSoEE
 UoRmnAGkjXVplaktpaqgrPrh/W/SDH+++lDB46yH6XddMAaVfddoMqG84g6qmhHN
 3nwsxzW5VD1dLjdeiDZ5ksSaV0RgJQbsQKOu7+9bmjnIVHH5jdA7usg/AZnarCKl
 obIMuWz5hxt6uUX98fV6rt9mfBeIyTDi6kP9k16aGqJfWWNSG4g9XwYr2v87R8Io
 P3Mvjq4WXKnKw/nYgTI48kzmNMgj0FXXYRX90RTSCz1moaAWgDxM0Qgmxe1JwLmP
 hZXYCmVkXdc6se2N/IAjqXLPw9eJYfPozZTY4CAn1FhCN3gqi8pbaVw3X2tvgdMp
 VVEBrMzfyTpTsZobndUklIHa6HllCGg5OpZS7WSmKSOy3e+wOFP8KbdBAd6Ir0mQ
 QL7t0MCS8TZH7+h2Hh84DFcZvhcGFyHcLsOK6+caq9EMwZFnMELp5niUiZ5oI0XH
 PeWbaaKPt7ra40/Y4JUfkaHuerchO89KiORVooCDc1Ntx2I0LpGCStXJde8MF8qb
 b117+BQeS/S20S8n5btz
 =hzT9
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170316' 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>
This commit is contained in:
Peter Maydell 2017-03-16 15:32:07 +00:00
commit c5e737e5fb
10 changed files with 49 additions and 13 deletions

5
exec.c
View file

@ -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)
{

View file

@ -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);

View file

@ -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);
@ -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;
@ -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++;

View file

@ -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;

View file

@ -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;
@ -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;
@ -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;

View file

@ -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
@ -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.

View file

@ -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;
@ -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;
@ -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 */

View file

@ -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) {

View file

@ -109,7 +109,7 @@ 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;
@ -117,7 +117,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
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);
@ -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;
@ -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);

View file

@ -1059,6 +1059,8 @@
# 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
@ -1066,6 +1068,8 @@
# 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)