All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: huangy81@chinatelecom.cn
Cc: Eduardo Habkost <ehabkost@redhat.com>,
	Juan Quintela <quintela@redhat.com>,
	qemu-devel@nongnu.org,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	Chuan Zheng <zhengchuan@huawei.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH v3 3/3] migration/dirtyrate: implement dirty-bitmap dirtyrate calculation
Date: Thu, 15 Jul 2021 16:58:54 -0400	[thread overview]
Message-ID: <YPChjjmp2NWwVd8s@t490s> (raw)
In-Reply-To: <1623bf516942494f78b0d33c9dda1297d6660574.1626364220.git.huangy81@chinatelecom.cn>

On Thu, Jul 15, 2021 at 11:51:33PM +0800, huangy81@chinatelecom.cn wrote:
> From: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
> 
> introduce dirty-bitmap mode as the third method of calc-dirty-rate.
> implement dirty-bitmap dirtyrate calculation, which can be used
> to measuring dirtyrate in the absence of dirty-ring.
> 
> introduce "dirty_bitmap:-b" option in hmp calc_dirty_rate to
> indicate dirty bitmap method should be used for calculation.
> 
> Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
> ---
>  hmp-commands.hx        |   9 ++--
>  migration/dirtyrate.c  | 116 +++++++++++++++++++++++++++++++++++++++++++++----
>  migration/trace-events |   1 +
>  qapi/migration.json    |   6 ++-
>  4 files changed, 117 insertions(+), 15 deletions(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index f7fc9d7..605973c 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1738,9 +1738,10 @@ ERST
>  
>      {
>          .name       = "calc_dirty_rate",
> -        .args_type  = "dirty_ring:-r,second:l,sample_pages_per_GB:l?",
> -        .params     = "[-r] second [sample_pages_per_GB]",
> -        .help       = "start a round of guest dirty rate measurement (using -d to"
> -                      "\n\t\t\t specify dirty ring as the method of calculation)",
> +        .args_type  = "dirty_ring:-r,dirty_bitmap:-b,second:l,sample_pages_per_GB:l?",
> +        .params     = "[-r] [-b] second [sample_pages_per_GB]",
> +        .help       = "start a round of guest dirty rate measurement (using -r to"
> +                      "\n\t\t\t specify dirty ring as the method of calculation and"
> +                      "\n\t\t\t -b to specify dirty bitmap as method of calculation)",
>          .cmd        = hmp_calc_dirty_rate,
>      },
> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
> index c465e62..8006a0d 100644
> --- a/migration/dirtyrate.c
> +++ b/migration/dirtyrate.c
> @@ -15,6 +15,7 @@
>  #include "qapi/error.h"
>  #include "cpu.h"
>  #include "exec/ramblock.h"
> +#include "exec/ram_addr.h"
>  #include "qemu/rcu_queue.h"
>  #include "qemu/main-loop.h"
>  #include "qapi/qapi-commands-migration.h"
> @@ -113,6 +114,10 @@ static struct DirtyRateInfo *query_dirty_rate_info(void)
>              }
>              info->vcpu_dirty_rate = head;
>          }
> +
> +        if (dirtyrate_mode == DIRTY_RATE_MEASURE_MODE_DIRTY_BITMAP) {
> +            info->sample_pages = 0;
> +        }
>      }
>  
>      trace_query_dirty_rate_info(DirtyRateStatus_str(CalculatingState));
> @@ -410,6 +415,83 @@ static void dirtyrate_global_dirty_log_stop(void)
>      qemu_mutex_unlock_iothread();
>  }
>  
> +static inline void dirtyrate_dirtypages_clear(void)
> +{
> +    DirtyRateDirtyPages = 0;

I think this is okay; but I think it's easier we keep it increase-only, so we
do things similar to dirty ring - we record the diff before/after.

> +}
> +
> +static inline void dirtyrate_manual_reset_protect(void)
> +{
> +    RAMBlock *block = NULL;
> +
> +    WITH_RCU_READ_LOCK_GUARD() {
> +        RAMBLOCK_FOREACH_MIGRATABLE(block) {
> +            cpu_physical_memory_dirtyrate_reset_protect(block);
> +        }
> +    }
> +}
> +
> +static void do_calculate_dirtyrate_bitmap(void)
> +{
> +    uint64_t memory_size_MB;
> +    int64_t time_s;
> +    uint64_t dirtyrate = 0;
> +
> +    memory_size_MB = (DirtyRateDirtyPages *TARGET_PAGE_SIZE) >> 20;
> +    time_s = DirtyStat.calc_time;
> +
> +    dirtyrate = memory_size_MB / time_s;
> +    DirtyStat.dirty_rate = dirtyrate;
> +
> +    trace_dirtyrate_do_calculate_bitmap(DirtyRateDirtyPages,
> +                                        time_s, dirtyrate);
> +}
> +
> +static void calculate_dirtyrate_dirty_bitmap(struct DirtyRateConfig config)
> +{
> +    int64_t msec = 0;
> +    int64_t start_time;
> +    uint64_t protect_flags = kvm_get_manual_dirty_log_protect();
> +
> +    dirtyrate_global_dirty_log_start();
> +
> +    /*
> +     * 1'round of log sync may return all 1 bits with
> +     * KVM_DIRTY_LOG_INITIALLY_SET enable
> +     * skip it unconditionally and start dirty tracking
> +     * from 2'round of log sync
> +     */
> +    memory_global_dirty_log_sync();

I think we need BQL for calling this.  E.g., memory_listeners can grow as we
call, also I'm not sure all ->log_sync() hooks are thread-safe.

> +
> +    /*
> +     * reset page protect manually and
> +     * start dirty tracking from now on
> +     */
> +    if (protect_flags & KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE) {
> +        dirtyrate_manual_reset_protect();

I think this needs BQL too.

Meanwhile after a second thought I think it's easier to drop patch 1 and call
dirtyrate_manual_reset_protect() unconditionally.  Say, kvm is not the only one
that may need a log clear (or say, re-protect), so checking kvm-only is not
actually a "complete" solution, because when there're more log_clear() hooks we
may want to call them too.

All modules providing log_clear() hook should be able to handle this correctly,
e.g., kvm_log_clear() can be called even without manual protect enabled, see
entry of kvm_physical_log_clear() which checks manual_dirty_log_protect.

> +    }
> +
> +    dirtyrate_dirtypages_clear();
> +
> +    start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
> +    DirtyStat.start_time = start_time / 1000;
> +
> +    msec = config.sample_period_seconds * 1000;
> +    msec = set_sample_page_period(msec, start_time);
> +    DirtyStat.calc_time = msec / 1000;
> +
> +    /* fetch dirty bitmap from kvm */
> +    memory_global_dirty_log_sync();
> +
> +    do_calculate_dirtyrate_bitmap();
> +
> +    if (protect_flags & KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE) {
> +        dirtyrate_manual_reset_protect();
> +    }

I feel like this chunk can be dropped.

> +
> +    dirtyrate_global_dirty_log_stop();
> +}

Thanks,

-- 
Peter Xu



  reply	other threads:[~2021-07-15 20:59 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-15 15:51 [PATCH v3 0/3] support dirtyrate measurement with dirty bitmap huangy81
     [not found] ` <cover.1626364220.git.huangy81@chinatelecom.cn>
2021-07-15 15:51   ` [PATCH v3 1/3] KVM: introduce kvm_get_manual_dirty_log_protect huangy81
2021-07-15 15:51   ` [PATCH v3 2/3] memory: introduce DirtyRateDirtyPages and util function huangy81
2021-07-15 20:49     ` Peter Xu
2021-07-15 15:51   ` [PATCH v3 3/3] migration/dirtyrate: implement dirty-bitmap dirtyrate calculation huangy81
2021-07-15 20:58     ` Peter Xu [this message]
2021-07-15 21:00 ` [PATCH v3 0/3] support dirtyrate measurement with dirty bitmap Peter Xu

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=YPChjjmp2NWwVd8s@t490s \
    --to=peterx@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=huangy81@chinatelecom.cn \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=zhengchuan@huawei.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.