From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: Zheng Chuan <zhengchuan@huawei.com>
Cc: berrange@redhat.com, zhang.zhanghailiang@huawei.com,
quintela@redhat.com, qemu-devel@nongnu.org,
xiexiangyou@huawei.com, alex.chen@huawei.com,
ann.zhuangyanying@huawei.com, fangying1@huawei.com
Subject: Re: [PATCH v5 06/12] migration/dirtyrate: Record hash results for each sampled page
Date: Thu, 27 Aug 2020 09:31:14 +0100 [thread overview]
Message-ID: <20200827083114.GA2837@work-vm> (raw)
In-Reply-To: <3a61c786-ca80-5658-d307-4ae638ad9de0@huawei.com>
* Zheng Chuan (zhengchuan@huawei.com) wrote:
>
>
> On 2020/8/26 20:35, Dr. David Alan Gilbert wrote:
> > * Chuan Zheng (zhengchuan@huawei.com) wrote:
> >> Record hash results for each sampled page, crc32 is taken to calculate
> >> hash results for each sampled 4K-page.
> >>
> >> Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
> >> Signed-off-by: YanYing Zhuang <ann.zhuangyanying@huawei.com>
> >> ---
> >> migration/dirtyrate.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >> migration/dirtyrate.h | 15 ++++++
> >> 2 files changed, 151 insertions(+)
> >>
> >> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
> >> index f6a94d8..66de426 100644
> >> --- a/migration/dirtyrate.c
> >> +++ b/migration/dirtyrate.c
> >> @@ -10,6 +10,7 @@
> >> * See the COPYING file in the top-level directory.
> >> */
> >>
> >> +#include <zlib.h>
> >> #include "qemu/osdep.h"
> >> #include "qapi/error.h"
> >> #include "crypto/hash.h"
> >> @@ -66,6 +67,141 @@ static void update_dirtyrate(uint64_t msec)
> >> DirtyStat.dirty_rate = dirtyrate;
> >> }
> >>
> >> +/*
> >> + * get hash result for the sampled memory with length of 4K byte in ramblock,
> >> + * which starts from ramblock base address.
> >> + */
> >> +static uint32_t get_ramblock_vfn_hash(struct RamblockDirtyInfo *info,
> >> + uint64_t vfn)
> >> +{
> >> + struct iovec iov_array;
> >> + uint32_t crc;
> >> +
> >> + iov_array.iov_base = info->ramblock_addr +
> >> + vfn * DIRTYRATE_SAMPLE_PAGE_SIZE;
> >> + iov_array.iov_len = DIRTYRATE_SAMPLE_PAGE_SIZE;
> >> +
> >> + crc = crc32(0, iov_array.iov_base, iov_array.iov_len);
> >> +
> >> + return crc;
> >> +}
> >> +
> >> +static int save_ramblock_hash(struct RamblockDirtyInfo *info)
> >> +{
> >> + unsigned int sample_pages_count;
> >> + int i;
> >> + int ret = -1;
> >> + GRand *rand = g_rand_new();
> >> +
> >> + sample_pages_count = info->sample_pages_count;
> >> +
> >> + /* ramblock size less than one page, return success to skip this ramblock */
> >> + if (unlikely(info->ramblock_pages == 0 || sample_pages_count == 0)) {
> >> + ret = 0;
> >> + goto out;
> >> + }
> >> +
> >> + info->hash_result = g_try_malloc0_n(sample_pages_count,
> >> + sizeof(uint32_t));
> >> + if (!info->hash_result) {
> >> + ret = -1;
> >> + goto out;
> >> + }
> >> +
> >> + info->sample_page_vfn = g_try_malloc0_n(sample_pages_count,
> >> + sizeof(uint64_t));
> >> + if (!info->sample_page_vfn) {
> >> + g_free(info->hash_result);
> >> + ret = -1;
> >> + goto out;
> >> + }
> >> +
> >> + for (i = 0; i < sample_pages_count; i++) {
> >> + info->sample_page_vfn[i] = g_rand_int_range(rand, 0,
> >> + info->ramblock_pages - 1);
> >> + info->hash_result[i] = get_ramblock_vfn_hash(info,
> >> + info->sample_page_vfn[i]);
> >> + }
> >> + ret = 0;
> >> +
> >> +out:
> >> + g_rand_free(rand);
> >> + return ret;
> >> +}
> >> +
> >> +static void get_ramblock_dirty_info(RAMBlock *block,
> >> + struct RamblockDirtyInfo *info,
> >> + struct DirtyRateConfig *config)
> >> +{
> >> + uint64_t sample_pages_per_gigabytes = config->sample_pages_per_gigabytes;
> >> +
> >> + /* Right shift 30 bits to calc block size in GB */
> >> + info->sample_pages_count = (qemu_ram_get_used_length(block) *
> >> + sample_pages_per_gigabytes) >>
> >> + DIRTYRATE_PAGE_SHIFT_GB;
> >> +
> >> + /* Right shift 12 bits to calc page count in 4KB */
> >> + info->ramblock_pages = qemu_ram_get_used_length(block) >>
> >> + DIRTYRATE_PAGE_SHIFT_KB;
> >> + info->ramblock_addr = qemu_ram_get_host_addr(block);
> >> + strcpy(info->idstr, qemu_ram_get_idstr(block));
> >> +}
> >> +
> >> +static struct RamblockDirtyInfo *
> >> +alloc_ramblock_dirty_info(int *block_index,
> >> + struct RamblockDirtyInfo *block_dinfo)
> >> +{
> >> + struct RamblockDirtyInfo *info = NULL;
> >> + int index = *block_index;
> >> +
> >> + if (!block_dinfo) {
> >> + index = 0;
> >> + block_dinfo = g_try_new(struct RamblockDirtyInfo, 1);
> >> + } else {
> >> + index++;
> >> + block_dinfo = g_try_realloc(block_dinfo, (index + 1) *
> >> + sizeof(struct RamblockDirtyInfo));
> >> + }
> >> + if (!block_dinfo) {
> >> + return NULL;
> >> + }
> >> +
> >> + info = &block_dinfo[index];
> >> + *block_index = index;
> >> + memset(info, 0, sizeof(struct RamblockDirtyInfo));
> >> +
> >> + return block_dinfo;
> >> +}
> >> +
> >> +static int record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
> >> + struct DirtyRateConfig config,
> >> + int *block_index)
> >> +{
> >> + struct RamblockDirtyInfo *info = NULL;
> >> + struct RamblockDirtyInfo *dinfo = NULL;
> >> + RAMBlock *block = NULL;
> >> + int index = 0;
> >> +
> >> + RAMBLOCK_FOREACH_MIGRATABLE(block) {
> >> + dinfo = alloc_ramblock_dirty_info(&index, dinfo);
> >> + if (dinfo == NULL) {
> >> + return -1;
> >> + }
> >> + info = &dinfo[index];
> >> + get_ramblock_dirty_info(block, info, &config);
> >> + if (save_ramblock_hash(info) < 0) {
> >> + *block_dinfo = dinfo;
> >> + *block_index = index;
> >> + return -1;
> >> + }
> >> + }
> >> +
> >> + *block_dinfo = dinfo;
> >> + *block_index = index;
> >> +
> >> + return 0;
> >> +}
> >> +
> >> static void calculate_dirtyrate(struct DirtyRateConfig config)
> >> {
> >> /* todo */
> >> diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
> >> index 8e25d93..e3adead 100644
> >> --- a/migration/dirtyrate.h
> >> +++ b/migration/dirtyrate.h
> >> @@ -24,6 +24,21 @@
> >> */
> >> #define RAMBLOCK_INFO_MAX_LEN 256
> >>
> >> +/*
> >> + * Sample page size 4K as default.
> >> + */
> >> +#define DIRTYRATE_SAMPLE_PAGE_SIZE 4096
> >> +
> >> +/*
> >> + * Sample page size 4K shift
> >> + */
> >> +#define DIRTYRATE_PAGE_SHIFT_KB 12
> >> +
> >> +/*
> >> + * Sample page size 1G shift
> >> + */
> >> +#define DIRTYRATE_PAGE_SHIFT_GB 30
> >
> > Your naming is really odd here; 'PAGE_SHIFT_KB' divides
> > by 4KB, where as 'PAGE_SHIFT_GB' divices by 1KB.
> >
> > Simplify this; you can just do >>30 for GB because it's well known;
> > you don't need a #define constant for simple KB,MB,GB since
> > we all know them.
> >
> Hi, Dave.
> Thank you for review.
> OK, i will fix that in V6:)
> > Also, I've asked before - do you really want 4KB explicitly - or
> > should you just use TARGET_PAGE_SIZE and TARGET_PAGE_BITS ?
> >
> > Dave
> >
> TARGET_PAGE_SIZE will be 2M or 1G for HugePage.
> As you see, what we get is hash result of every 'virtual' 4K-page.
> We care about if it is dirty within 4K length in ramblock, which would be more
> accurate than TARGET_PAGE_SIZE which could be 2M or 1G.
> On the other hand, the hugepage will be broken up into 4K during migration.
>
> I think it is better we do hash at 'virtual' 4K-page granularity.
TARGET_PAGE_SIZE is never 2M or 1G; it's always based on the smallest
MMU page on the platform; on x86 it's always 4kB; it's the unit that the
migration code works in when dealing with pages.
(use TARGET_PAGE_BITS to shift by).
Dave
> >> +
> >> /* Take 1s as default for calculation duration */
> >> #define DEFAULT_FETCH_DIRTYRATE_TIME_SEC 1
> >>
> >> --
> >> 1.8.3.1
> >>
>
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
next prev parent reply other threads:[~2020-08-27 8:32 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-25 1:40 [PATCH v5 00/12] *** A Method for evaluating dirty page rate *** Chuan Zheng
2020-08-25 1:40 ` [PATCH v5 01/12] migration/dirtyrate: setup up query-dirtyrate framwork Chuan Zheng
2020-08-25 17:54 ` Dr. David Alan Gilbert
2020-08-25 1:40 ` [PATCH v5 02/12] migration/dirtyrate: add DirtyRateStatus to denote calculation status Chuan Zheng
2020-08-26 11:49 ` Dr. David Alan Gilbert
2020-08-27 6:09 ` Zheng Chuan
2020-08-25 1:40 ` [PATCH v5 03/12] migration/dirtyrate: Add RamlockDirtyInfo to store sampled page info Chuan Zheng
2020-08-26 11:59 ` Dr. David Alan Gilbert
2020-08-25 1:40 ` [PATCH v5 04/12] migration/dirtyrate: Add dirtyrate statistics series functions Chuan Zheng
2020-08-26 12:09 ` Dr. David Alan Gilbert
2020-08-27 6:12 ` Zheng Chuan
2020-08-25 1:40 ` [PATCH v5 05/12] migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into ram.h Chuan Zheng
2020-08-25 1:40 ` [PATCH v5 06/12] migration/dirtyrate: Record hash results for each sampled page Chuan Zheng
2020-08-26 12:35 ` Dr. David Alan Gilbert
2020-08-27 6:41 ` Zheng Chuan
2020-08-27 8:31 ` Dr. David Alan Gilbert [this message]
2020-08-25 1:40 ` [PATCH v5 07/12] migration/dirtyrate: Compare page hash results for recorded " Chuan Zheng
2020-08-26 16:36 ` Dr. David Alan Gilbert
2020-08-25 1:40 ` [PATCH v5 08/12] migration/dirtyrate: skip sampling ramblock with size below MIN_RAMBLOCK_SIZE Chuan Zheng
2020-08-26 16:54 ` Dr. David Alan Gilbert
2020-08-25 1:40 ` [PATCH v5 09/12] migration/dirtyrate: Implement get_sample_page_period() and block_sample_page_period() Chuan Zheng
2020-08-25 1:40 ` [PATCH v5 10/12] migration/dirtyrate: Implement calculate_dirtyrate() function Chuan Zheng
2020-08-25 1:40 ` [PATCH v5 11/12] migration/dirtyrate: Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function Chuan Zheng
2020-08-25 1:40 ` [PATCH v5 12/12] migration/dirtyrate: Add trace_calls to make it easier to debug Chuan Zheng
2020-08-26 17:20 ` Dr. David Alan Gilbert
-- strict thread matches above, loose matches on Subject: below --
2020-08-24 9:14 [PATCH v5 00/12] *** A Method for evaluating dirty page rate *** Chuan Zheng
2020-08-24 9:14 ` [PATCH v5 06/12] migration/dirtyrate: Record hash results for each sampled page Chuan Zheng
2020-08-26 9:56 ` David Edmondson
2020-08-26 12:30 ` Dr. David Alan Gilbert
2020-08-26 12:33 ` David Edmondson
2020-08-27 6:28 ` Zheng Chuan
2020-08-27 7:11 ` David Edmondson
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=20200827083114.GA2837@work-vm \
--to=dgilbert@redhat.com \
--cc=alex.chen@huawei.com \
--cc=ann.zhuangyanying@huawei.com \
--cc=berrange@redhat.com \
--cc=fangying1@huawei.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=xiexiangyou@huawei.com \
--cc=zhang.zhanghailiang@huawei.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.