All of lore.kernel.org
 help / color / mirror / Atom feed
From: Orit Wasserman <owasserm@redhat.com>
To: Juan Quintela <quintela@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 07/12] savevm: split save_live_setup from save_live_state
Date: Sun, 01 Jul 2012 15:14:53 +0300	[thread overview]
Message-ID: <4FF03F3D.1050501@redhat.com> (raw)
In-Reply-To: <5a3139cd92ad66e5028ad0120e4de63c1a089d65.1340910651.git.quintela@redhat.com>

On 06/28/2012 10:22 PM, Juan Quintela wrote:
> This patch splits stage 1 to its own function for both save_live
> users, ram and block.  It is just a copy of the function, removing the
> parts of the other stages.  Optimizations would came later.
> 
> Signed-off-by: Juan Quintela <quintela@redhat.com>
> ---
>  arch_init.c       |   86 +++++++++++++++++++++++++++++++++++++++--------------
>  block-migration.c |   35 +++++++++++++++++-----
>  savevm.c          |    4 +--
>  vmstate.h         |    1 +
>  4 files changed, 95 insertions(+), 31 deletions(-)
> 
> diff --git a/arch_init.c b/arch_init.c
> index 36e19b0..b296e17 100644
> --- a/arch_init.c
> +++ b/arch_init.c
> @@ -303,44 +303,85 @@ static void ram_migration_cancel(void *opaque)
> 
>  #define MAX_WAIT 50 /* ms, half buffered_file limit */
> 
> -static int ram_save_live(QEMUFile *f, int stage, void *opaque)
> +static int ram_save_setup(QEMUFile *f, void *opaque)
>  {
>      ram_addr_t addr;
> -    uint64_t bytes_transferred_last;
> +    RAMBlock *block;
>      double bwidth = 0;
>      int ret;
>      int i;
> 
>      memory_global_sync_dirty_bitmap(get_system_memory());
> 
> -    if (stage == 1) {
> -        RAMBlock *block;
> -        bytes_transferred = 0;
> -        last_block = NULL;
> -        last_offset = 0;
> -        sort_ram_list();
> -
> -        /* Make sure all dirty bits are set */
> -        QLIST_FOREACH(block, &ram_list.blocks, next) {
> -            for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
> -                if (!memory_region_get_dirty(block->mr, addr, TARGET_PAGE_SIZE,
> -                                             DIRTY_MEMORY_MIGRATION)) {
> -                    memory_region_set_dirty(block->mr, addr, TARGET_PAGE_SIZE);
> -                }
> +    bytes_transferred = 0;
> +    last_block = NULL;
> +    last_offset = 0;
> +    sort_ram_list();
> +
> +    /* Make sure all dirty bits are set */
> +    QLIST_FOREACH(block, &ram_list.blocks, next) {
> +        for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
> +            if (!memory_region_get_dirty(block->mr, addr, TARGET_PAGE_SIZE,
> +                                         DIRTY_MEMORY_MIGRATION)) {
> +                memory_region_set_dirty(block->mr, addr, TARGET_PAGE_SIZE);
>              }
>          }
> +    }
> 
> -        memory_global_dirty_log_start();
> +    memory_global_dirty_log_start();
> +
> +    qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
> +
> +    QLIST_FOREACH(block, &ram_list.blocks, next) {
> +        qemu_put_byte(f, strlen(block->idstr));
> +        qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
> +        qemu_put_be64(f, block->length);
> +    }
> +
> +    bwidth = qemu_get_clock_ns(rt_clock);
> 
> -        qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
> +    i = 0;
> +    while ((ret = qemu_file_rate_limit(f)) == 0) {
> +        int bytes_sent;
> 
> -        QLIST_FOREACH(block, &ram_list.blocks, next) {
> -            qemu_put_byte(f, strlen(block->idstr));
> -            qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
> -            qemu_put_be64(f, block->length);
> +        bytes_sent = ram_save_block(f);
> +        bytes_transferred += bytes_sent;
> +        if (bytes_sent == 0) { /* no more blocks */
> +            break;
>          }
> +        /* we want to check in the 1st loop, just in case it was the 1st time
> +           and we had to sync the dirty bitmap.
> +           qemu_get_clock_ns() is a bit expensive, so we only check each some
> +           iterations
> +        */
> +        if ((i & 63) == 0) {
> +            uint64_t t1 = (qemu_get_clock_ns(rt_clock) - bwidth) / 1000000;
> +            if (t1 > MAX_WAIT) {
> +                DPRINTF("big wait: %ld milliseconds, %d iterations\n", t1, i);
> +                break;
> +            }
> +        }
> +        i++;
>      }
> 
> +    if (ret < 0) {
> +        return ret;
> +    }
> +
> +    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
> +
> +    return 0;
> +}
> +
> +static int ram_save_live(QEMUFile *f, int stage, void *opaque)
> +{
> +    uint64_t bytes_transferred_last;
> +    double bwidth = 0;
> +    int ret;
> +    int i;
> +
> +    memory_global_sync_dirty_bitmap(get_system_memory());
> +
>      bytes_transferred_last = bytes_transferred;
>      bwidth = qemu_get_clock_ns(rt_clock);
> 
> @@ -534,6 +575,7 @@ done:
>  }
> 
>  SaveVMHandlers savevm_ram_handlers = {
> +    .save_live_setup = ram_save_setup,
>      .save_live_state = ram_save_live,
>      .load_state = ram_load,
>      .cancel = ram_migration_cancel,
> diff --git a/block-migration.c b/block-migration.c
> index 6d37dc1..fc3d1f4 100644
> --- a/block-migration.c
> +++ b/block-migration.c
> @@ -541,20 +541,40 @@ static void block_migration_cancel(void *opaque)
>      blk_mig_cleanup();
>  }
> 
> -static int block_save_live(QEMUFile *f, int stage, void *opaque)
> +static int block_save_setup(QEMUFile *f, void *opaque)
>  {
>      int ret;
> 
> -    DPRINTF("Enter save live stage %d submitted %d transferred %d\n",
> -            stage, block_mig_state.submitted, block_mig_state.transferred);
> +    DPRINTF("Enter save live setup submitted %d transferred %d\n",
> +            block_mig_state.submitted, block_mig_state.transferred);
> 
> -    if (stage == 1) {
> -        init_blk_migration(f);
> +    init_blk_migration(f);
> +
> +    /* start track dirty blocks */
> +    set_dirty_tracking(1);
> +
> +    flush_blks(f);
> 
> -        /* start track dirty blocks */
> -        set_dirty_tracking(1);
> +    ret = qemu_file_get_error(f);
> +    if (ret) {
> +        blk_mig_cleanup();
> +        return ret;
>      }
> 
> +    blk_mig_reset_dirty_cursor();
> +
> +    qemu_put_be64(f, BLK_MIG_FLAG_EOS);
> +
> +    return 0;
> +}
> +
> +static int block_save_live(QEMUFile *f, int stage, void *opaque)
> +{
> +    int ret;
> +
> +    DPRINTF("Enter save live stage %d submitted %d transferred %d\n",
> +            stage, block_mig_state.submitted, block_mig_state.transferred);
> +
>      flush_blks(f);
> 
>      ret = qemu_file_get_error(f);
> @@ -710,6 +730,7 @@ static bool block_is_active(void *opaque)
> 
>  SaveVMHandlers savevm_block_handlers = {
>      .set_params = block_set_params,
> +    .save_live_setup = block_save_setup,
>      .save_live_state = block_save_live,
>      .load_state = block_load,
>      .cancel = block_migration_cancel,
> diff --git a/savevm.c b/savevm.c
> index afa0c9e..0b80a94 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1573,7 +1573,7 @@ int qemu_savevm_state_begin(QEMUFile *f,
>      QTAILQ_FOREACH(se, &savevm_handlers, entry) {
>          int len;
> 
> -        if (!se->ops || !se->ops->save_live_state) {
> +        if (!se->ops || !se->ops->save_live_setup) {
>              continue;
>          }
>          if (se->ops && se->ops->is_active) {
> @@ -1593,7 +1593,7 @@ int qemu_savevm_state_begin(QEMUFile *f,
>          qemu_put_be32(f, se->instance_id);
>          qemu_put_be32(f, se->version_id);
> 
> -        ret = se->ops->save_live_state(f, QEMU_VM_SECTION_START, se->opaque);
> +        ret = se->ops->save_live_setup(f, se->opaque);
>          if (ret < 0) {
>              qemu_savevm_state_cancel(f);
>              return ret;
> diff --git a/vmstate.h b/vmstate.h
> index 96651a5..049f2b7 100644
> --- a/vmstate.h
> +++ b/vmstate.h
> @@ -32,6 +32,7 @@ typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
>  typedef struct SaveVMHandlers {
>      void (*set_params)(const MigrationParams *params, void * opaque);
>      SaveStateHandler *save_state;
> +    int (*save_live_setup)(QEMUFile *f, void *opaque);
>      int (*save_live_state)(QEMUFile *f, int stage, void *opaque);
>      void (*cancel)(void *opaque);
>      LoadStateHandler *load_state;
> 

Reviewed-by: Orit Wasserman <owasserm@redhat.com>

  parent reply	other threads:[~2012-07-01 12:14 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1340910651.git.quintela@redhat.com>
     [not found] ` <39651e275488caec46861cb5b11ba1c7961a429c.1340910651.git.quintela@redhat.com>
2012-07-01  8:05   ` [Qemu-devel] [PATCH 01/12] savevm: Use a struct to pass all handlers Orit Wasserman
     [not found]   ` <4FEF3843.1000907@weilnetz.de>
2012-07-01 10:16     ` [Qemu-devel] Bad mail header? Juan Quintela
2012-07-01 10:56       ` Peter Maydell
2012-07-13  7:26         ` Juan Quintela
     [not found] ` <620debbcb9bc99dc6db54d87a8683efbc00c2b66.1340910651.git.quintela@redhat.com>
2012-07-01  8:19   ` [Qemu-devel] [PATCH 02/12] savevm: Live migration handlers register the struct directly Orit Wasserman
2012-07-01 10:20     ` Juan Quintela
2012-07-01 11:24       ` Orit Wasserman
2012-07-11 17:01         ` Juan Quintela
2012-07-11 17:28           ` Orit Wasserman
     [not found] ` <704b60a0d2b32fbf6bf229b115082c2b929a4731.1340910651.git.quintela@redhat.com>
2012-07-01  9:40   ` [Qemu-devel] [PATCH 03/12] savevm: remove SaveSetParamsHandler Orit Wasserman
     [not found] ` <509b501d09f18212b4165ee116ddef4ceba59097.1340910651.git.quintela@redhat.com>
2012-07-01  9:40   ` [Qemu-devel] [PATCH 04/12] savevm: remove SaveLiveStateHandler Orit Wasserman
     [not found] ` <3dad4b557fac0c11eb6fdb06121859d16247e4f0.1340910651.git.quintela@redhat.com>
2012-07-01  9:47   ` [Qemu-devel] [PATCH 05/12] savevm: Refactor cancel operation in its own operation Orit Wasserman
     [not found] ` <1e9e8749f384425d04c74bc76fc502621e226352.1340910651.git.quintela@redhat.com>
     [not found]   ` <4FEF7C5F.5010700@gmail.com>
2012-07-01 10:44     ` [Qemu-devel] [PATCH 06/12] savevm: introduce is_active method Juan Quintela
     [not found] ` <5a3139cd92ad66e5028ad0120e4de63c1a089d65.1340910651.git.quintela@redhat.com>
2012-07-01 12:14   ` Orit Wasserman [this message]
     [not found] ` <cd73a246dbbb7a688e0000204f5af2040afe6578.1340910651.git.quintela@redhat.com>
2012-07-01 12:17   ` [Qemu-devel] [PATCH 11/12] ram: iterate phase Igor Mitsyanko
2012-07-03 10:48     ` Juan Quintela
     [not found] ` <d1e17271bb9fdc52dbd0b591e471b096aca2e721.1340910651.git.quintela@redhat.com>
2012-07-02 11:57   ` [Qemu-devel] [PATCH 08/12] savevm: split save_live into stage2 and stage3 Orit Wasserman
     [not found] ` <07c8945d9b633bc509ebec0ff6646834ec974ccb.1340910651.git.quintela@redhat.com>
2012-07-02 12:00   ` [Qemu-devel] [PATCH 09/12] ram: save_live_setup() don't need to sent pages Orit Wasserman
     [not found] ` <be6bed86c792fb6f237f016aadfb3fcbda746f15.1340910651.git.quintela@redhat.com>
2012-07-02 12:00   ` [Qemu-devel] [PATCH 10/12] ram: save_live_complete() only do one loop Orit Wasserman
     [not found] ` <ab1ca756b1cfe67df94f7c6674ea86f6d7232a2f.1340910651.git.quintela@redhat.com>
2012-07-02 12:05   ` [Qemu-devel] [PATCH 12/12] ram: save_live_setup() we don't need to synchronize the dirty bitmap Orit Wasserman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4FF03F3D.1050501@redhat.com \
    --to=owasserm@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.