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
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).