qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 23/42] migration: yay, buffering is gone


From: Wenchao Xia
Subject: Re: [Qemu-devel] [PATCH 23/42] migration: yay, buffering is gone
Date: Wed, 06 Mar 2013 09:34:02 +0800
User-agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20130215 Thunderbird/17.0.3

Hi, Paolo
  Do you think static buffer in qemu_file should be also removed?

> Buffering was needed because blocking writes could take a long time
> and starve other threads seeking to grab the big QEMU mutex.
> 
> Now that all writes (except within _complete callbacks) are done
> outside the big QEMU mutex, we do not need buffering at all.
> 
> Reviewed-by: Orit Wasserman <address@hidden>
> Reviewed-by: Juan Quintela <address@hidden>
> Signed-off-by: Paolo Bonzini <address@hidden>
> ---
>   include/migration/migration.h |  3 --
>   migration.c                   | 79 
> ++++++++++++-------------------------------
>   savevm.c                      |  1 +
>   3 files changed, 22 insertions(+), 61 deletions(-)
> 
> diff --git a/include/migration/migration.h b/include/migration/migration.h
> index ed20bed..cec8643 100644
> --- a/include/migration/migration.h
> +++ b/include/migration/migration.h
> @@ -34,9 +34,6 @@ struct MigrationState
>       int64_t bandwidth_limit;
>       size_t bytes_xfer;
>       size_t xfer_limit;
> -    uint8_t *buffer;
> -    size_t buffer_size;
> -    size_t buffer_capacity;
>       QemuThread thread;
>       QEMUBH *cleanup_bh;
> 
> diff --git a/migration.c b/migration.c
> index e64c92d..4c8d576 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -514,73 +514,41 @@ int64_t migrate_xbzrle_cache_size(void)
> 
>   /* migration thread support */
> 
> -
> -static void buffered_flush(MigrationState *s)
> -{
> -    size_t offset = 0;
> -    ssize_t ret = 0;
> -
> -    DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size);
> -
> -    if (qemu_file_get_error(s->file)) {
> -        s->buffer_size = 0;
> -        return;
> -    }
> -    qemu_fflush(s->file);
> -
> -    while (s->bytes_xfer < s->xfer_limit && offset < s->buffer_size) {
> -        size_t to_send = MIN(s->buffer_size - offset, s->xfer_limit - 
> s->bytes_xfer);
> -        ret = migrate_fd_put_buffer(s, s->buffer + offset, to_send);
> -        if (ret <= 0) {
> -            DPRINTF("error flushing data, %zd\n", ret);
> -            break;
> -        } else {
> -            DPRINTF("flushed %zd byte(s)\n", ret);
> -            offset += ret;
> -            s->bytes_xfer += ret;
> -        }
> -    }
> -
> -    DPRINTF("flushed %zu of %zu byte(s)\n", offset, s->buffer_size);
> -    memmove(s->buffer, s->buffer + offset, s->buffer_size - offset);
> -    s->buffer_size -= offset;
> -
> -    if (ret < 0) {
> -        qemu_file_set_error(s->file, ret);
> -    }
> -}
> -
>   static int buffered_put_buffer(void *opaque, const uint8_t *buf,
>                                  int64_t pos, int size)
>   {
>       MigrationState *s = opaque;
> -    ssize_t error;
> +    ssize_t ret;
> +    size_t sent;
> 
>       DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos);
> 
> -    error = qemu_file_get_error(s->file);
> -    if (error) {
> -        DPRINTF("flush when error, bailing: %s\n", strerror(-error));
> -        return error;
> +    ret = qemu_file_get_error(s->file);
> +    if (ret) {
> +        DPRINTF("flush when error, bailing: %s\n", strerror(-ret));
> +        return ret;
>       }
> 
>       if (size <= 0) {
>           return size;
>       }
> 
> -    if (size > (s->buffer_capacity - s->buffer_size)) {
> -        DPRINTF("increasing buffer capacity from %zu by %zu\n",
> -                s->buffer_capacity, size + 1024);
> -
> -        s->buffer_capacity += size + 1024;
> -
> -        s->buffer = g_realloc(s->buffer, s->buffer_capacity);
> +    sent = 0;
> +    while (size) {
> +        ret = migrate_fd_put_buffer(s, buf, size);
> +        if (ret <= 0) {
> +            DPRINTF("error flushing data, %zd\n", ret);
> +            return ret;
> +        } else {
> +            DPRINTF("flushed %zd byte(s)\n", ret);
> +            sent += ret;
> +            buf += ret;
> +            size -= ret;
> +            s->bytes_xfer += ret;
> +        }
>       }
> 
> -    memcpy(s->buffer + s->buffer_size, buf, size);
> -    s->buffer_size += size;
> -
> -    return size;
> +    return sent;
>   }
> 
>   static int buffered_close(void *opaque)
> @@ -712,10 +680,9 @@ static void *buffered_file_thread(void *opaque)
>               g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);
>               sleep_time += qemu_get_clock_ms(rt_clock) - current_time;
>           }
> -        buffered_flush(s);
>           if (qemu_file_get_error(s->file)) {
>               migrate_finish_set_state(s, MIG_STATE_ERROR);
> -        } else if (last_round && s->buffer_size == 0) {
> +        } else if (last_round) {
>               migrate_finish_set_state(s, MIG_STATE_COMPLETED);
>           }
>       }
> @@ -735,7 +702,6 @@ static void *buffered_file_thread(void *opaque)
>       qemu_bh_schedule(s->cleanup_bh);
>       qemu_mutex_unlock_iothread();
> 
> -    g_free(s->buffer);
>       return NULL;
>   }
> 
> @@ -754,9 +720,6 @@ void migrate_fd_connect(MigrationState *s)
>       trace_migrate_set_state(MIG_STATE_ACTIVE);
> 
>       s->bytes_xfer = 0;
> -    s->buffer = NULL;
> -    s->buffer_size = 0;
> -    s->buffer_capacity = 0;
>       /* This is a best 1st approximation. ns to ms */
>       s->expected_downtime = max_downtime/1000000;
> 
> diff --git a/savevm.c b/savevm.c
> index 7c7774e..ce10295 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1724,6 +1724,7 @@ void qemu_savevm_state_complete(QEMUFile *f)
>       }
> 
>       qemu_put_byte(f, QEMU_VM_EOF);
> +    qemu_fflush(f);
>   }
> 
>   uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size)
> 


-- 
Best Regards

Wenchao Xia




reply via email to

[Prev in Thread] Current Thread [Next in Thread]