migration/next for 20170531

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABCAAGBQJZLnZiAAoJEPSH7xhYctcjslkQAOGGLz18kCaebdx7EYdDQs5Z
 tlxqk5tPyz2AuAN7yPCX+2wxlNRzdfqZtQSpEC2nGCfRxLby5OXT4tFGC+dDBsQ5
 kRxc8sbhnwc+uwH8lxgIQ5J3jFANymMYElM4HLoX8Jl0+YBtIpqJKExfAcjVBYjs
 +Kt+9gZNGRy3nXdHcxQESN8YTeRp5AXprs78Q6dJxYtfD1Xlew6xhNrEhUAJDNFD
 8AGB0yWJO0r1ibRL2v3X4vSYlPcIn6rxW9g+A+j33B97ViH5yPt0ZF99hMKgq8S9
 KT4/wXhoTB+UxGbRPSpwI/JevMPQNW07YRlXFNU5Qiqq8eUE0ApoDTef9t0xIVQv
 kPxY+UuPdO96vDi1ASUJaIPjmfvAwVuNseTlBhs+Z7phzKKooQ5UNmTK+4DNsrE4
 ssogd+5dVEY4YxKB8I/6jd6bksxtz1CCk3dT6PIhhpC5M+PVr04ydYhN2ykepnDk
 S49pM3qWgpdB+1juHHv+FzepH+Ku+1Nz7GyK4pCy+2fvBOblvmspw+Eboyp+xJTU
 lsHttFi0a1DfJo++JZWy6+pvS+P7kx+zlF1US5mavgewygaBI8rMxL6lGDLkvJId
 3sJqlFvwE5WjdMQGoJXNXcfRR6Fb6piz7W7oZjGtRkAWRwX7wxhN2YChss8vSUig
 g7DEjUeAb416ija5d+xd
 =uy/8
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170531' into staging

migration/next for 20170531

# gpg: Signature made Wed 31 May 2017 08:53:06 BST
# 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/20170531:
  migration: use dirty_rate_high_cnt more aggressively
  migration: set bytes_xfer_* outside of autoconverge logic
  migration: set dirty_pages_rate before autoconverge logic
  migration: keep bytes_xfer_prev init'd to zero
  migration: Create savevm.h for functions exported from savevm.c

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-06-01 15:01:59 +01:00
commit e5cac10a3b
7 changed files with 80 additions and 63 deletions

View file

@ -97,53 +97,6 @@ int load_vmstate(const char *name, Error **errp);
void qemu_announce_self(void); void qemu_announce_self(void);
/* Subcommands for QEMU_VM_COMMAND */
enum qemu_vm_cmd {
MIG_CMD_INVALID = 0, /* Must be 0 */
MIG_CMD_OPEN_RETURN_PATH, /* Tell the dest to open the Return path */
MIG_CMD_PING, /* Request a PONG on the RP */
MIG_CMD_POSTCOPY_ADVISE, /* Prior to any page transfers, just
warn we might want to do PC */
MIG_CMD_POSTCOPY_LISTEN, /* Start listening for incoming
pages as it's running. */
MIG_CMD_POSTCOPY_RUN, /* Start execution */
MIG_CMD_POSTCOPY_RAM_DISCARD, /* A list of pages to discard that
were previously sent during
precopy but are dirty. */
MIG_CMD_PACKAGED, /* Send a wrapped stream within this stream */
MIG_CMD_MAX
};
#define MAX_VM_CMD_PACKAGED_SIZE (1ul << 24)
bool qemu_savevm_state_blocked(Error **errp);
void qemu_savevm_state_begin(QEMUFile *f);
void qemu_savevm_state_header(QEMUFile *f);
int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy);
void qemu_savevm_state_cleanup(void);
void qemu_savevm_state_complete_postcopy(QEMUFile *f);
void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only);
void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size,
uint64_t *res_non_postcopiable,
uint64_t *res_postcopiable);
void qemu_savevm_command_send(QEMUFile *f, enum qemu_vm_cmd command,
uint16_t len, uint8_t *data);
void qemu_savevm_send_ping(QEMUFile *f, uint32_t value);
void qemu_savevm_send_open_return_path(QEMUFile *f);
int qemu_savevm_send_packaged(QEMUFile *f, const uint8_t *buf, size_t len);
void qemu_savevm_send_postcopy_advise(QEMUFile *f);
void qemu_savevm_send_postcopy_listen(QEMUFile *f);
void qemu_savevm_send_postcopy_run(QEMUFile *f);
void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, const char *name,
uint16_t len,
uint64_t *start_list,
uint64_t *length_list);
int qemu_loadvm_state(QEMUFile *f);
extern int autostart; extern int autostart;
typedef enum { typedef enum {

View file

@ -16,6 +16,7 @@
#include "qemu-file-channel.h" #include "qemu-file-channel.h"
#include "migration/migration.h" #include "migration/migration.h"
#include "migration/qemu-file.h" #include "migration/qemu-file.h"
#include "savevm.h"
#include "migration/colo.h" #include "migration/colo.h"
#include "migration/block.h" #include "migration/block.h"
#include "io/channel-buffer.h" #include "io/channel-buffer.h"

View file

@ -19,6 +19,7 @@
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "migration/blocker.h" #include "migration/blocker.h"
#include "migration/migration.h" #include "migration/migration.h"
#include "savevm.h"
#include "qemu-file-channel.h" #include "qemu-file-channel.h"
#include "migration/qemu-file.h" #include "migration/qemu-file.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"

View file

@ -22,6 +22,7 @@
#include "exec/target_page.h" #include "exec/target_page.h"
#include "migration/migration.h" #include "migration/migration.h"
#include "migration/qemu-file.h" #include "migration/qemu-file.h"
#include "savevm.h"
#include "postcopy-ram.h" #include "postcopy-ram.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/balloon.h" #include "sysemu/balloon.h"

View file

@ -673,10 +673,6 @@ static void migration_bitmap_sync(RAMState *rs)
rs->bitmap_sync_count++; rs->bitmap_sync_count++;
if (!rs->bytes_xfer_prev) {
rs->bytes_xfer_prev = ram_bytes_transferred();
}
if (!rs->time_last_bitmap_sync) { if (!rs->time_last_bitmap_sync) {
rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
} }
@ -698,23 +694,25 @@ static void migration_bitmap_sync(RAMState *rs)
/* more than 1 second = 1000 millisecons */ /* more than 1 second = 1000 millisecons */
if (end_time > rs->time_last_bitmap_sync + 1000) { if (end_time > rs->time_last_bitmap_sync + 1000) {
/* calculate period counters */
rs->dirty_pages_rate = rs->num_dirty_pages_period * 1000
/ (end_time - rs->time_last_bitmap_sync);
bytes_xfer_now = ram_bytes_transferred();
if (migrate_auto_converge()) { if (migrate_auto_converge()) {
/* The following detection logic can be refined later. For now: /* The following detection logic can be refined later. For now:
Check to see if the dirtied bytes is 50% more than the approx. Check to see if the dirtied bytes is 50% more than the approx.
amount of bytes that just got transferred since the last time we amount of bytes that just got transferred since the last time we
were in this routine. If that happens twice, start or increase were in this routine. If that happens twice, start or increase
throttling */ throttling */
bytes_xfer_now = ram_bytes_transferred();
if (rs->dirty_pages_rate && if ((rs->num_dirty_pages_period * TARGET_PAGE_SIZE >
(rs->num_dirty_pages_period * TARGET_PAGE_SIZE >
(bytes_xfer_now - rs->bytes_xfer_prev) / 2) && (bytes_xfer_now - rs->bytes_xfer_prev) / 2) &&
(rs->dirty_rate_high_cnt++ >= 2)) { (++rs->dirty_rate_high_cnt >= 2)) {
trace_migration_throttle(); trace_migration_throttle();
rs->dirty_rate_high_cnt = 0; rs->dirty_rate_high_cnt = 0;
mig_throttle_guest_down(); mig_throttle_guest_down();
} }
rs->bytes_xfer_prev = bytes_xfer_now;
} }
if (migrate_use_xbzrle()) { if (migrate_use_xbzrle()) {
@ -727,10 +725,11 @@ static void migration_bitmap_sync(RAMState *rs)
rs->iterations_prev = rs->iterations; rs->iterations_prev = rs->iterations;
rs->xbzrle_cache_miss_prev = rs->xbzrle_cache_miss; rs->xbzrle_cache_miss_prev = rs->xbzrle_cache_miss;
} }
rs->dirty_pages_rate = rs->num_dirty_pages_period * 1000
/ (end_time - rs->time_last_bitmap_sync); /* reset period counters */
rs->time_last_bitmap_sync = end_time; rs->time_last_bitmap_sync = end_time;
rs->num_dirty_pages_period = 0; rs->num_dirty_pages_period = 0;
rs->bytes_xfer_prev = bytes_xfer_now;
} }
if (migrate_use_events()) { if (migrate_use_events()) {
qapi_event_send_migration_pass(rs->bitmap_sync_count, NULL); qapi_event_send_migration_pass(rs->bitmap_sync_count, NULL);

View file

@ -36,6 +36,7 @@
#include "qemu/timer.h" #include "qemu/timer.h"
#include "migration/migration.h" #include "migration/migration.h"
#include "qemu-file-channel.h" #include "qemu-file-channel.h"
#include "savevm.h"
#include "postcopy-ram.h" #include "postcopy-ram.h"
#include "qapi/qmp/qerror.h" #include "qapi/qmp/qerror.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
@ -63,6 +64,26 @@ const unsigned int postcopy_ram_discard_version = 0;
static bool skip_section_footers; static bool skip_section_footers;
/* Subcommands for QEMU_VM_COMMAND */
enum qemu_vm_cmd {
MIG_CMD_INVALID = 0, /* Must be 0 */
MIG_CMD_OPEN_RETURN_PATH, /* Tell the dest to open the Return path */
MIG_CMD_PING, /* Request a PONG on the RP */
MIG_CMD_POSTCOPY_ADVISE, /* Prior to any page transfers, just
warn we might want to do PC */
MIG_CMD_POSTCOPY_LISTEN, /* Start listening for incoming
pages as it's running. */
MIG_CMD_POSTCOPY_RUN, /* Start execution */
MIG_CMD_POSTCOPY_RAM_DISCARD, /* A list of pages to discard that
were previously sent during
precopy but are dirty. */
MIG_CMD_PACKAGED, /* Send a wrapped stream within this stream */
MIG_CMD_MAX
};
#define MAX_VM_CMD_PACKAGED_SIZE (1ul << 24)
static struct mig_cmd_args { static struct mig_cmd_args {
ssize_t len; /* -1 = variable */ ssize_t len; /* -1 = variable */
const char *name; const char *name;
@ -807,10 +828,10 @@ static void save_section_footer(QEMUFile *f, SaveStateEntry *se)
* @len: Length of associated data * @len: Length of associated data
* @data: Data associated with command. * @data: Data associated with command.
*/ */
void qemu_savevm_command_send(QEMUFile *f, static void qemu_savevm_command_send(QEMUFile *f,
enum qemu_vm_cmd command, enum qemu_vm_cmd command,
uint16_t len, uint16_t len,
uint8_t *data) uint8_t *data)
{ {
trace_savevm_command_send(command, len); trace_savevm_command_send(command, len);
qemu_put_byte(f, QEMU_VM_COMMAND); qemu_put_byte(f, QEMU_VM_COMMAND);

41
migration/savevm.h Normal file
View file

@ -0,0 +1,41 @@
/*
* QEMU save vm functions
*
* Copyright (c) 2003-2008 Fabrice Bellard
* Copyright (c) 2009-2017 Red Hat Inc
*
* Authors:
* Juan Quintela <quintela@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef MIGRATION_SAVEVM_H
#define MIGRATION_SAVEVM_H
bool qemu_savevm_state_blocked(Error **errp);
void qemu_savevm_state_begin(QEMUFile *f);
void qemu_savevm_state_header(QEMUFile *f);
int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy);
void qemu_savevm_state_cleanup(void);
void qemu_savevm_state_complete_postcopy(QEMUFile *f);
void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only);
void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size,
uint64_t *res_non_postcopiable,
uint64_t *res_postcopiable);
void qemu_savevm_send_ping(QEMUFile *f, uint32_t value);
void qemu_savevm_send_open_return_path(QEMUFile *f);
int qemu_savevm_send_packaged(QEMUFile *f, const uint8_t *buf, size_t len);
void qemu_savevm_send_postcopy_advise(QEMUFile *f);
void qemu_savevm_send_postcopy_listen(QEMUFile *f);
void qemu_savevm_send_postcopy_run(QEMUFile *f);
void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, const char *name,
uint16_t len,
uint64_t *start_list,
uint64_t *length_list);
int qemu_loadvm_state(QEMUFile *f);
#endif