Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/amit-migration/tags/for-juan-20…
Browse files Browse the repository at this point in the history
…1509' into staging

Migration queue

# gpg: Signature made Tue 29 Sep 2015 07:13:55 BST using RSA key ID 854083B6
# gpg: Good signature from "Amit Shah <amit@amitshah.net>"
# gpg:                 aka "Amit Shah <amit@kernel.org>"
# gpg:                 aka "Amit Shah <amitshah@gmx.net>"

* remotes/amit-migration/tags/for-juan-201509:
  ram_find_and_save_block: Split out the finding
  Move dirty page search state into separate structure
  migration: Use g_new() & friends where that makes obvious sense
  migration: qemu-file more size_t'ifying
  migration: size_t'ify some of qemu-file
  Init page sizes in qtest
  Split out end of migration code from migration_thread
  migration/ram.c: Use RAMBlock rather than MemoryRegion
  vmstate: Remove redefinition of VMSTATE_UINT32_ARRAY

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Sep 29, 2015
2 parents 6996a00 + b9e6092 commit b2312c6
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 142 deletions.
18 changes: 9 additions & 9 deletions include/migration/qemu-file.h
Expand Up @@ -31,15 +31,15 @@
* The pos argument can be ignored if the file is only being used for
* streaming. The handler should try to write all of the data it can.
*/
typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
int64_t pos, int size);
typedef ssize_t (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
int64_t pos, size_t size);

/* Read a chunk of data from a file at the given position. The pos argument
* can be ignored if the file is only be used for streaming. The number of
* bytes actually read should be returned.
*/
typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf,
int64_t pos, int size);
typedef ssize_t (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf,
int64_t pos, size_t size);

/* Close a file
*
Expand Down Expand Up @@ -126,13 +126,13 @@ int qemu_get_fd(QEMUFile *f);
int qemu_fclose(QEMUFile *f);
int64_t qemu_ftell(QEMUFile *f);
int64_t qemu_ftell_fast(QEMUFile *f);
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size);
void qemu_put_byte(QEMUFile *f, int v);
/*
* put_buffer without copying the buffer.
* The buffer should be available till it is sent asynchronously.
*/
void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size);
void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size);
bool qemu_file_mode_is_not_valid(const char *mode);
bool qemu_file_is_writable(QEMUFile *f);

Expand Down Expand Up @@ -161,8 +161,8 @@ static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
void qemu_put_be16(QEMUFile *f, unsigned int v);
void qemu_put_be32(QEMUFile *f, unsigned int v);
void qemu_put_be64(QEMUFile *f, uint64_t v);
int qemu_peek_buffer(QEMUFile *f, uint8_t **buf, int size, size_t offset);
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset);
size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size);
ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
int level);
int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src);
Expand Down Expand Up @@ -237,7 +237,7 @@ static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
}

// Signed versions for type safety
static inline void qemu_put_sbuffer(QEMUFile *f, const int8_t *buf, int size)
static inline void qemu_put_sbuffer(QEMUFile *f, const int8_t *buf, size_t size)
{
qemu_put_buffer(f, (const uint8_t *)buf, size);
}
Expand Down
3 changes: 0 additions & 3 deletions include/migration/vmstate.h
Expand Up @@ -754,9 +754,6 @@ extern const VMStateInfo vmstate_info_bitmap;
#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)

#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)

#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t)

Expand Down
77 changes: 48 additions & 29 deletions migration/migration.c
Expand Up @@ -86,7 +86,7 @@ MigrationIncomingState *migration_incoming_get_current(void)

MigrationIncomingState *migration_incoming_state_new(QEMUFile* f)
{
mis_current = g_malloc0(sizeof(MigrationIncomingState));
mis_current = g_new0(MigrationIncomingState, 1);
mis_current->file = f;
QLIST_INIT(&mis_current->loadvm_handlers);

Expand Down Expand Up @@ -913,6 +913,50 @@ int64_t migrate_xbzrle_cache_size(void)
return s->xbzrle_cache_size;
}

/**
* migration_completion: Used by migration_thread when there's not much left.
* The caller 'breaks' the loop when this returns.
*
* @s: Current migration state
* @*old_vm_running: Pointer to old_vm_running flag
* @*start_time: Pointer to time to update
*/
static void migration_completion(MigrationState *s, bool *old_vm_running,
int64_t *start_time)
{
int ret;

qemu_mutex_lock_iothread();
*start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
*old_vm_running = runstate_is_running();

ret = global_state_store();
if (!ret) {
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
if (ret >= 0) {
qemu_file_set_rate_limit(s->file, INT64_MAX);
qemu_savevm_state_complete(s->file);
}
}
qemu_mutex_unlock_iothread();

if (ret < 0) {
goto fail;
}

if (qemu_file_get_error(s->file)) {
trace_migration_completion_file_err();
goto fail;
}

migrate_set_state(s, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_COMPLETED);
return;

fail:
migrate_set_state(s, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_FAILED);
}

/* migration thread support */

static void *migration_thread(void *opaque)
Expand Down Expand Up @@ -943,34 +987,9 @@ static void *migration_thread(void *opaque)
if (pending_size && pending_size >= max_size) {
qemu_savevm_state_iterate(s->file);
} else {
int ret;

qemu_mutex_lock_iothread();
start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
old_vm_running = runstate_is_running();

ret = global_state_store();
if (!ret) {
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
if (ret >= 0) {
qemu_file_set_rate_limit(s->file, INT64_MAX);
qemu_savevm_state_complete(s->file);
}
}
qemu_mutex_unlock_iothread();

if (ret < 0) {
migrate_set_state(s, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_FAILED);
break;
}

if (!qemu_file_get_error(s->file)) {
migrate_set_state(s, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_COMPLETED);
break;
}
trace_migration_thread_low_pending(pending_size);
migration_completion(s, &old_vm_running, &start_time);
break;
}
}

Expand Down
9 changes: 5 additions & 4 deletions migration/qemu-file-buf.c
Expand Up @@ -372,7 +372,8 @@ typedef struct QEMUBuffer {
bool qsb_allocated;
} QEMUBuffer;

static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
static ssize_t buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
size_t size)
{
QEMUBuffer *s = opaque;
ssize_t len = qsb_get_length(s->qsb) - pos;
Expand All @@ -387,8 +388,8 @@ static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
return qsb_get_buffer(s->qsb, pos, len, buf);
}

static int buf_put_buffer(void *opaque, const uint8_t *buf,
int64_t pos, int size)
static ssize_t buf_put_buffer(void *opaque, const uint8_t *buf,
int64_t pos, size_t size)
{
QEMUBuffer *s = opaque;

Expand Down Expand Up @@ -439,7 +440,7 @@ QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input)
return NULL;
}

s = g_malloc0(sizeof(QEMUBuffer));
s = g_new0(QEMUBuffer, 1);
s->qsb = input;

if (s->qsb == NULL) {
Expand Down
15 changes: 8 additions & 7 deletions migration/qemu-file-stdio.c
Expand Up @@ -37,11 +37,11 @@ static int stdio_get_fd(void *opaque)
return fileno(s->stdio_file);
}

static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
int size)
static ssize_t stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
size_t size)
{
QEMUFileStdio *s = opaque;
int res;
size_t res;

res = fwrite(buf, 1, size, s->stdio_file);

Expand All @@ -51,11 +51,12 @@ static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
return res;
}

static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
static ssize_t stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
size_t size)
{
QEMUFileStdio *s = opaque;
FILE *fp = s->stdio_file;
int bytes;
ssize_t bytes;

for (;;) {
clearerr(fp);
Expand Down Expand Up @@ -143,7 +144,7 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
return NULL;
}

s = g_malloc0(sizeof(QEMUFileStdio));
s = g_new0(QEMUFileStdio, 1);

s->stdio_file = stdio_file;

Expand Down Expand Up @@ -175,7 +176,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode)
return NULL;
}

s = g_malloc0(sizeof(QEMUFileStdio));
s = g_new0(QEMUFileStdio, 1);

s->stdio_file = fopen(filename, mode);
if (!s->stdio_file) {
Expand Down
10 changes: 6 additions & 4 deletions migration/qemu-file-unix.c
Expand Up @@ -54,7 +54,8 @@ static int socket_get_fd(void *opaque)
return s->fd;
}

static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
static ssize_t socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
size_t size)
{
QEMUFileSocket *s = opaque;
ssize_t len;
Expand Down Expand Up @@ -138,7 +139,8 @@ static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
return total;
}

static int unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
static ssize_t unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
size_t size)
{
QEMUFileSocket *s = opaque;
ssize_t len;
Expand Down Expand Up @@ -192,7 +194,7 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
return NULL;
}

s = g_malloc0(sizeof(QEMUFileSocket));
s = g_new0(QEMUFileSocket, 1);
s->fd = fd;

if (mode[0] == 'r') {
Expand Down Expand Up @@ -226,7 +228,7 @@ QEMUFile *qemu_fopen_socket(int fd, const char *mode)
return NULL;
}

s = g_malloc0(sizeof(QEMUFileSocket));
s = g_new0(QEMUFileSocket, 1);
s->fd = fd;
if (mode[0] == 'w') {
qemu_set_block(s->fd);
Expand Down
24 changes: 12 additions & 12 deletions migration/qemu-file.c
Expand Up @@ -60,7 +60,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
{
QEMUFile *f;

f = g_malloc0(sizeof(QEMUFile));
f = g_new0(QEMUFile, 1);

f->opaque = opaque;
f->ops = ops;
Expand Down Expand Up @@ -270,7 +270,7 @@ int qemu_fclose(QEMUFile *f)
return ret;
}

static void add_to_iovec(QEMUFile *f, const uint8_t *buf, int size)
static void add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size)
{
/* check for adjacent buffer and coalesce them */
if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base +
Expand All @@ -286,7 +286,7 @@ static void add_to_iovec(QEMUFile *f, const uint8_t *buf, int size)
}
}

void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size)
void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size)
{
if (!f->ops->writev_buffer) {
qemu_put_buffer(f, buf, size);
Expand All @@ -301,9 +301,9 @@ void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size)
add_to_iovec(f, buf, size);
}

void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
{
int l;
size_t l;

if (f->last_error) {
return;
Expand Down Expand Up @@ -363,10 +363,10 @@ void qemu_file_skip(QEMUFile *f, int size)
* return as many as it managed to read (assuming blocking fd's which
* all current QEMUFile are)
*/
int qemu_peek_buffer(QEMUFile *f, uint8_t **buf, int size, size_t offset)
size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset)
{
int pending;
int index;
ssize_t pending;
size_t index;

assert(!qemu_file_is_writable(f));
assert(offset < IO_BUF_SIZE);
Expand Down Expand Up @@ -411,13 +411,13 @@ int qemu_peek_buffer(QEMUFile *f, uint8_t **buf, int size, size_t offset)
* return as many as it managed to read (assuming blocking fd's which
* all current QEMUFile are)
*/
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
{
int pending = size;
int done = 0;
size_t pending = size;
size_t done = 0;

while (pending > 0) {
int res;
size_t res;
uint8_t *src;

res = qemu_peek_buffer(f, &src, MIN(pending, IO_BUF_SIZE), 0);
Expand Down

0 comments on commit b2312c6

Please sign in to comment.