!147 Automatically generate code patches with openeuler

From: @zhendongchen
Reviewed-by: @yorifang
Signed-off-by: @yorifang
This commit is contained in:
openeuler-ci-bot 2020-12-03 20:38:37 +08:00 committed by Gitee
commit d044c682ed
16 changed files with 1413 additions and 1 deletions

View File

@ -0,0 +1,54 @@
From 17b0582ebba622afbd8f454bbee8141ed2785f13 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:21:58 +0800
Subject: [PATCH] migration/dirtyrate: Add RamblockDirtyInfo to store sampled
page info
Add RamblockDirtyInfo to store sampled page info of each ramblock.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-4-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 84ab9409ac..8707df852d 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -19,10 +19,28 @@
*/
#define DIRTYRATE_DEFAULT_SAMPLE_PAGES 512
+/*
+ * Record ramblock idstr
+ */
+#define RAMBLOCK_INFO_MAX_LEN 256
+
struct DirtyRateConfig {
uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
int64_t sample_period_seconds; /* time duration between two sampling */
};
+/*
+ * Store dirtypage info for each ramblock.
+ */
+struct RamblockDirtyInfo {
+ char idstr[RAMBLOCK_INFO_MAX_LEN]; /* idstr for each ramblock */
+ uint8_t *ramblock_addr; /* base address of ramblock we measure */
+ uint64_t ramblock_pages; /* ramblock size in TARGET_PAGE_SIZE */
+ uint64_t *sample_page_vfn; /* relative offset address for sampled page */
+ uint64_t sample_pages_count; /* count of sampled pages */
+ uint64_t sample_dirty_count; /* count of dirty pages we measure */
+ uint32_t *hash_result; /* array of hash result for sampled pages */
+};
+
void *get_dirtyrate_thread(void *arg);
#endif
--
2.27.0

View File

@ -0,0 +1,93 @@
From d1340703e127c02e9a586143039507ba10d73cfb Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:21:59 +0800
Subject: [PATCH] migration/dirtyrate: Add dirtyrate statistics series
functions
Add dirtyrate statistics functions to record/update dirtyrate info.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-5-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 32 ++++++++++++++++++++++++++++++++
migration/dirtyrate.h | 12 ++++++++++++
2 files changed, 44 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 44a60bf10d..cbb323d6ec 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -23,6 +23,7 @@
#include "dirtyrate.h"
static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
+static struct DirtyRateStat DirtyStat;
static int dirtyrate_set_state(int *state, int old_state, int new_state)
{
@@ -34,6 +35,37 @@ static int dirtyrate_set_state(int *state, int old_state, int new_state)
}
}
+static void reset_dirtyrate_stat(void)
+{
+ DirtyStat.total_dirty_samples = 0;
+ DirtyStat.total_sample_count = 0;
+ DirtyStat.total_block_mem_MB = 0;
+ DirtyStat.dirty_rate = -1;
+ DirtyStat.start_time = 0;
+ DirtyStat.calc_time = 0;
+}
+
+static void update_dirtyrate_stat(struct RamblockDirtyInfo *info)
+{
+ DirtyStat.total_dirty_samples += info->sample_dirty_count;
+ DirtyStat.total_sample_count += info->sample_pages_count;
+ /* size of total pages in MB */
+ DirtyStat.total_block_mem_MB += (info->ramblock_pages *
+ TARGET_PAGE_SIZE) >> 20;
+}
+
+static void update_dirtyrate(uint64_t msec)
+{
+ uint64_t dirtyrate;
+ uint64_t total_dirty_samples = DirtyStat.total_dirty_samples;
+ uint64_t total_sample_count = DirtyStat.total_sample_count;
+ uint64_t total_block_mem_MB = DirtyStat.total_block_mem_MB;
+
+ dirtyrate = total_dirty_samples * total_block_mem_MB *
+ 1000 / (total_sample_count * msec);
+
+ DirtyStat.dirty_rate = dirtyrate;
+}
static void calculate_dirtyrate(struct DirtyRateConfig config)
{
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 8707df852d..312debca6f 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -42,5 +42,17 @@ struct RamblockDirtyInfo {
uint32_t *hash_result; /* array of hash result for sampled pages */
};
+/*
+ * Store calculation statistics for each measure.
+ */
+struct DirtyRateStat {
+ uint64_t total_dirty_samples; /* total dirty sampled page */
+ uint64_t total_sample_count; /* total sampled pages */
+ uint64_t total_block_mem_MB; /* size of total sampled pages in MB */
+ int64_t dirty_rate; /* dirty rate in MB/s */
+ int64_t start_time; /* calculation start time in units of second */
+ int64_t calc_time; /* time duration of two sampling in units of second */
+};
+
void *get_dirtyrate_thread(void *arg);
#endif
--
2.27.0

View File

@ -0,0 +1,99 @@
From 8a36332d38c0c0ba6b7d8c096367a4ec7c94e522 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:07 +0800
Subject: [PATCH] migration/dirtyrate: Add trace_calls to make it easier to
debug
Add trace_calls to make it easier to debug
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Message-Id: <1600237327-33618-13-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 9 +++++++++
migration/trace-events | 8 ++++++++
2 files changed, 17 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 9d9155f8ab..80936a4ca6 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -22,6 +22,7 @@
#include "qapi/qapi-commands-migration.h"
#include "migration.h"
#include "ram.h"
+#include "trace.h"
#include "dirtyrate.h"
static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
@@ -54,6 +55,7 @@ static bool is_sample_period_valid(int64_t sec)
static int dirtyrate_set_state(int *state, int old_state, int new_state)
{
assert(new_state < DIRTY_RATE_STATUS__MAX);
+ trace_dirtyrate_set_state(DirtyRateStatus_str(new_state));
if (atomic_cmpxchg(state, old_state, new_state) == old_state) {
return 0;
} else {
@@ -76,6 +78,8 @@ static struct DirtyRateInfo *query_dirty_rate_info(void)
info->start_time = DirtyStat.start_time;
info->calc_time = DirtyStat.calc_time;
+ trace_query_dirty_rate_info(DirtyRateStatus_str(CalculatingState));
+
return info;
}
@@ -123,6 +127,7 @@ static uint32_t get_ramblock_vfn_hash(struct RamblockDirtyInfo *info,
crc = crc32(0, (info->ramblock_addr +
vfn * TARGET_PAGE_SIZE), TARGET_PAGE_SIZE);
+ trace_get_ramblock_vfn_hash(info->idstr, vfn, crc);
return crc;
}
@@ -201,6 +206,8 @@ static bool skip_sample_ramblock(RAMBlock *block)
* Sample only blocks larger than MIN_RAMBLOCK_SIZE.
*/
if (qemu_ram_get_used_length(block) < (MIN_RAMBLOCK_SIZE << 10)) {
+ trace_skip_sample_ramblock(block->idstr,
+ qemu_ram_get_used_length(block));
return true;
}
@@ -260,6 +267,7 @@ static void calc_page_dirty_rate(struct RamblockDirtyInfo *info)
for (i = 0; i < info->sample_pages_count; i++) {
crc = get_ramblock_vfn_hash(info, info->sample_page_vfn[i]);
if (crc != info->hash_result[i]) {
+ trace_calc_page_dirty_rate(info->idstr, crc, info->hash_result[i]);
info->sample_dirty_count++;
}
}
@@ -285,6 +293,7 @@ find_block_matched(RAMBlock *block, int count,
if (infos[i].ramblock_addr != qemu_ram_get_host_addr(block) ||
infos[i].ramblock_pages !=
(qemu_ram_get_used_length(block) >> TARGET_PAGE_BITS)) {
+ trace_find_page_matched(block->idstr);
return NULL;
}
diff --git a/migration/trace-events b/migration/trace-events
index d8e54c367a..69620c43c2 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -296,3 +296,11 @@ dirty_bitmap_load_bits_zeroes(void) ""
dirty_bitmap_load_header(uint32_t flags) "flags 0x%x"
dirty_bitmap_load_enter(void) ""
dirty_bitmap_load_success(void) ""
+
+# dirtyrate.c
+dirtyrate_set_state(const char *new_state) "new state %s"
+query_dirty_rate_info(const char *new_state) "current state %s"
+get_ramblock_vfn_hash(const char *idstr, uint64_t vfn, uint32_t crc) "ramblock name: %s, vfn: %"PRIu64 ", crc: %" PRIu32
+calc_page_dirty_rate(const char *idstr, uint32_t new_crc, uint32_t old_crc) "ramblock name: %s, new crc: %" PRIu32 ", old crc: %" PRIu32
+skip_sample_ramblock(const char *idstr, uint64_t ramblock_size) "ramblock name: %s, ramblock size: %" PRIu64
+find_page_matched(const char *idstr) "ramblock %s addr or size changed"
--
2.27.0

View File

@ -0,0 +1,95 @@
From 949612c5bbc5414970aed7d7ec9390a058ee2246 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:02 +0800
Subject: [PATCH] migration/dirtyrate: Compare page hash results for recorded
sampled page
Compare page hash results for recorded sampled page.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Signed-off-by: YanYing Zhuang <ann.zhuangyanying@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-8-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 63 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index f93601f8ab..0412f825dc 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -177,6 +177,69 @@ out:
return ret;
}
+static void calc_page_dirty_rate(struct RamblockDirtyInfo *info)
+{
+ uint32_t crc;
+ int i;
+
+ for (i = 0; i < info->sample_pages_count; i++) {
+ crc = get_ramblock_vfn_hash(info, info->sample_page_vfn[i]);
+ if (crc != info->hash_result[i]) {
+ info->sample_dirty_count++;
+ }
+ }
+}
+
+static struct RamblockDirtyInfo *
+find_block_matched(RAMBlock *block, int count,
+ struct RamblockDirtyInfo *infos)
+{
+ int i;
+ struct RamblockDirtyInfo *matched;
+
+ for (i = 0; i < count; i++) {
+ if (!strcmp(infos[i].idstr, qemu_ram_get_idstr(block))) {
+ break;
+ }
+ }
+
+ if (i == count) {
+ return NULL;
+ }
+
+ if (infos[i].ramblock_addr != qemu_ram_get_host_addr(block) ||
+ infos[i].ramblock_pages !=
+ (qemu_ram_get_used_length(block) >> TARGET_PAGE_BITS)) {
+ return NULL;
+ }
+
+ matched = &infos[i];
+
+ return matched;
+}
+
+static bool compare_page_hash_info(struct RamblockDirtyInfo *info,
+ int block_count)
+{
+ struct RamblockDirtyInfo *block_dinfo = NULL;
+ RAMBlock *block = NULL;
+
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
+ block_dinfo = find_block_matched(block, block_count, info);
+ if (block_dinfo == NULL) {
+ continue;
+ }
+ calc_page_dirty_rate(block_dinfo);
+ update_dirtyrate_stat(block_dinfo);
+ }
+
+ if (DirtyStat.total_sample_count == 0) {
+ return false;
+ }
+
+ return true;
+}
+
static void calculate_dirtyrate(struct DirtyRateConfig config)
{
/* todo */
--
2.27.0

View File

@ -0,0 +1,83 @@
From 18102266fb18c4bfcdd4760e7111ca03a7520588 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:05 +0800
Subject: [PATCH] migration/dirtyrate: Implement calculate_dirtyrate() function
Implement calculate_dirtyrate() function.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Signed-off-by: YanYing Zhuang <ann.zhuangyanying@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-11-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 45 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 485d6467c9..c7a389a527 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -162,6 +162,21 @@ static void get_ramblock_dirty_info(RAMBlock *block,
strcpy(info->idstr, qemu_ram_get_idstr(block));
}
+static void free_ramblock_dirty_info(struct RamblockDirtyInfo *infos, int count)
+{
+ int i;
+
+ if (!infos) {
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ g_free(infos[i].sample_page_vfn);
+ g_free(infos[i].hash_result);
+ }
+ g_free(infos);
+}
+
static bool skip_sample_ramblock(RAMBlock *block)
{
/*
@@ -287,8 +302,34 @@ static bool compare_page_hash_info(struct RamblockDirtyInfo *info,
static void calculate_dirtyrate(struct DirtyRateConfig config)
{
- /* todo */
- return;
+ struct RamblockDirtyInfo *block_dinfo = NULL;
+ int block_count = 0;
+ int64_t msec = 0;
+ int64_t initial_time;
+
+ rcu_register_thread();
+ reset_dirtyrate_stat();
+ rcu_read_lock();
+ initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ if (!record_ramblock_hash_info(&block_dinfo, config, &block_count)) {
+ goto out;
+ }
+ rcu_read_unlock();
+
+ msec = config.sample_period_seconds * 1000;
+ msec = set_sample_page_period(msec, initial_time);
+
+ rcu_read_lock();
+ if (!compare_page_hash_info(block_dinfo, block_count)) {
+ goto out;
+ }
+
+ update_dirtyrate(msec);
+
+out:
+ rcu_read_unlock();
+ free_ramblock_dirty_info(block_dinfo, block_count);
+ rcu_unregister_thread();
}
void *get_dirtyrate_thread(void *arg)
--
2.27.0

View File

@ -0,0 +1,164 @@
From 1f5f7156988cee6e678eff253df0e79788c950d7 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:06 +0800
Subject: [PATCH] migration/dirtyrate: Implement
qmp_cal_dirty_rate()/qmp_get_dirty_rate() function
Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function which could be called
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Message-Id: <1600237327-33618-12-git-send-email-zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
atomic function fixup
Wording fixup in migration.json based on Eric's review
---
migration/dirtyrate.c | 62 +++++++++++++++++++++++++++++++++++++++++++
qapi/migration.json | 50 ++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index c7a389a527..9d9155f8ab 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -61,6 +61,24 @@ static int dirtyrate_set_state(int *state, int old_state, int new_state)
}
}
+static struct DirtyRateInfo *query_dirty_rate_info(void)
+{
+ int64_t dirty_rate = DirtyStat.dirty_rate;
+ struct DirtyRateInfo *info = g_malloc0(sizeof(DirtyRateInfo));
+
+ if (atomic_read(&CalculatingState) == DIRTY_RATE_STATUS_MEASURED) {
+ info->dirty_rate = dirty_rate;
+ } else {
+ info->dirty_rate = -1;
+ }
+
+ info->status = CalculatingState;
+ info->start_time = DirtyStat.start_time;
+ info->calc_time = DirtyStat.calc_time;
+
+ return info;
+}
+
static void reset_dirtyrate_stat(void)
{
DirtyStat.total_dirty_samples = 0;
@@ -318,6 +336,8 @@ static void calculate_dirtyrate(struct DirtyRateConfig config)
msec = config.sample_period_seconds * 1000;
msec = set_sample_page_period(msec, initial_time);
+ DirtyStat.start_time = initial_time / 1000;
+ DirtyStat.calc_time = msec / 1000;
rcu_read_lock();
if (!compare_page_hash_info(block_dinfo, block_count)) {
@@ -353,3 +373,45 @@ void *get_dirtyrate_thread(void *arg)
}
return NULL;
}
+
+void qmp_calc_dirty_rate(int64_t calc_time, Error **errp)
+{
+ static struct DirtyRateConfig config;
+ QemuThread thread;
+ int ret;
+
+ /*
+ * If the dirty rate is already being measured, don't attempt to start.
+ */
+ if (atomic_read(&CalculatingState) == DIRTY_RATE_STATUS_MEASURING) {
+ error_setg(errp, "the dirty rate is already being measured.");
+ return;
+ }
+
+ if (!is_sample_period_valid(calc_time)) {
+ error_setg(errp, "calc-time is out of range[%d, %d].",
+ MIN_FETCH_DIRTYRATE_TIME_SEC,
+ MAX_FETCH_DIRTYRATE_TIME_SEC);
+ return;
+ }
+
+ /*
+ * Init calculation state as unstarted.
+ */
+ ret = dirtyrate_set_state(&CalculatingState, CalculatingState,
+ DIRTY_RATE_STATUS_UNSTARTED);
+ if (ret == -1) {
+ error_setg(errp, "init dirty rate calculation state failed.");
+ return;
+ }
+
+ config.sample_period_seconds = calc_time;
+ config.sample_pages_per_gigabytes = DIRTYRATE_DEFAULT_SAMPLE_PAGES;
+ qemu_thread_create(&thread, "get_dirtyrate", get_dirtyrate_thread,
+ (void *)&config, QEMU_THREAD_DETACHED);
+}
+
+struct DirtyRateInfo *qmp_query_dirty_rate(Error **errp)
+{
+ return query_dirty_rate_info();
+}
diff --git a/qapi/migration.json b/qapi/migration.json
index fdddde0af7..76f5b42493 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1462,3 +1462,53 @@
##
{ 'enum': 'DirtyRateStatus',
'data': [ 'unstarted', 'measuring', 'measured'] }
+
+##
+# @DirtyRateInfo:
+#
+# Information about current dirty page rate of vm.
+#
+# @dirty-rate: @dirtyrate describing the dirty page rate of vm
+# in units of MB/s.
+# If this field returns '-1', it means querying has not
+# yet started or completed.
+#
+# @status: status containing dirtyrate query status includes
+# 'unstarted' or 'measuring' or 'measured'
+#
+# @start-time: start time in units of second for calculation
+#
+# @calc-time: time in units of second for sample dirty pages
+#
+# Since: 5.2
+#
+##
+{ 'struct': 'DirtyRateInfo',
+ 'data': {'dirty-rate': 'int64',
+ 'status': 'DirtyRateStatus',
+ 'start-time': 'int64',
+ 'calc-time': 'int64'} }
+
+##
+# @calc-dirty-rate:
+#
+# start calculating dirty page rate for vm
+#
+# @calc-time: time in units of second for sample dirty pages
+#
+# Since: 5.2
+#
+# Example:
+# {"command": "calc-dirty-rate", "data": {"calc-time": 1} }
+#
+##
+{ 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64'} }
+
+##
+# @query-dirty-rate:
+#
+# query dirty page rate in units of MB/s for vm
+#
+# Since: 5.2
+##
+{ 'command': 'query-dirty-rate', 'returns': 'DirtyRateInfo' }
--
2.27.0

View File

@ -0,0 +1,75 @@
From 905082a502e0600d40e784df2443ae99948cf52d Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:04 +0800
Subject: [PATCH] migration/dirtyrate: Implement set_sample_page_period() and
is_sample_period_valid()
Implement is_sample_period_valid() to check if the sample period is vaild and
do set_sample_page_period() to sleep specific time between sample actions.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-10-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 24 ++++++++++++++++++++++++
migration/dirtyrate.h | 6 ++++++
2 files changed, 30 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 97bb883850..485d6467c9 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -27,6 +27,30 @@
static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
static struct DirtyRateStat DirtyStat;
+static int64_t set_sample_page_period(int64_t msec, int64_t initial_time)
+{
+ int64_t current_time;
+
+ current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ if ((current_time - initial_time) >= msec) {
+ msec = current_time - initial_time;
+ } else {
+ g_usleep((msec + initial_time - current_time) * 1000);
+ }
+
+ return msec;
+}
+
+static bool is_sample_period_valid(int64_t sec)
+{
+ if (sec < MIN_FETCH_DIRTYRATE_TIME_SEC ||
+ sec > MAX_FETCH_DIRTYRATE_TIME_SEC) {
+ return false;
+ }
+
+ return true;
+}
+
static int dirtyrate_set_state(int *state, int old_state, int new_state)
{
assert(new_state < DIRTY_RATE_STATUS__MAX);
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index be5b8ec2b1..6ec429534d 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -29,6 +29,12 @@
*/
#define MIN_RAMBLOCK_SIZE 128
+/*
+ * Take 1s as minimum time for calculation duration
+ */
+#define MIN_FETCH_DIRTYRATE_TIME_SEC 1
+#define MAX_FETCH_DIRTYRATE_TIME_SEC 60
+
struct DirtyRateConfig {
uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
int64_t sample_period_seconds; /* time duration between two sampling */
--
2.27.0

View File

@ -0,0 +1,149 @@
From 751dbc44b4ac0e0c0bce2f53d2ee79a6e6318188 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:01 +0800
Subject: [PATCH] migration/dirtyrate: Record hash results for each sampled
page
Record hash results for each sampled page, crc32 is taken to calculate
hash results for each sampled length in TARGET_PAGE_SIZE.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Signed-off-by: YanYing Zhuang <ann.zhuangyanying@huawei.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-7-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 109 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 1ccc71077d..f93601f8ab 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 "cpu.h"
@@ -68,6 +69,114 @@ static void update_dirtyrate(uint64_t msec)
DirtyStat.dirty_rate = dirtyrate;
}
+/*
+ * get hash result for the sampled memory with length of TARGET_PAGE_SIZE
+ * in ramblock, which starts from ramblock base address.
+ */
+static uint32_t get_ramblock_vfn_hash(struct RamblockDirtyInfo *info,
+ uint64_t vfn)
+{
+ uint32_t crc;
+
+ crc = crc32(0, (info->ramblock_addr +
+ vfn * TARGET_PAGE_SIZE), TARGET_PAGE_SIZE);
+
+ return crc;
+}
+
+static bool save_ramblock_hash(struct RamblockDirtyInfo *info)
+{
+ unsigned int sample_pages_count;
+ int i;
+ GRand *rand;
+
+ 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)) {
+ return true;
+ }
+
+ info->hash_result = g_try_malloc0_n(sample_pages_count,
+ sizeof(uint32_t));
+ if (!info->hash_result) {
+ return false;
+ }
+
+ info->sample_page_vfn = g_try_malloc0_n(sample_pages_count,
+ sizeof(uint64_t));
+ if (!info->sample_page_vfn) {
+ g_free(info->hash_result);
+ return false;
+ }
+
+ rand = g_rand_new();
+ 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]);
+ }
+ g_rand_free(rand);
+
+ return true;
+}
+
+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 ramblock size in GB */
+ info->sample_pages_count = (qemu_ram_get_used_length(block) *
+ sample_pages_per_gigabytes) >> 30;
+ /* Right shift TARGET_PAGE_BITS to calc page count */
+ info->ramblock_pages = qemu_ram_get_used_length(block) >>
+ TARGET_PAGE_BITS;
+ info->ramblock_addr = qemu_ram_get_host_addr(block);
+ strcpy(info->idstr, qemu_ram_get_idstr(block));
+}
+
+static bool record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
+ struct DirtyRateConfig config,
+ int *block_count)
+{
+ struct RamblockDirtyInfo *info = NULL;
+ struct RamblockDirtyInfo *dinfo = NULL;
+ RAMBlock *block = NULL;
+ int total_count = 0;
+ int index = 0;
+ bool ret = false;
+
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
+ total_count++;
+ }
+
+ dinfo = g_try_malloc0_n(total_count, sizeof(struct RamblockDirtyInfo));
+ if (dinfo == NULL) {
+ goto out;
+ }
+
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
+ if (index >= total_count) {
+ break;
+ }
+ info = &dinfo[index];
+ get_ramblock_dirty_info(block, info, &config);
+ if (!save_ramblock_hash(info)) {
+ goto out;
+ }
+ index++;
+ }
+ ret = true;
+
+out:
+ *block_count = index;
+ *block_dinfo = dinfo;
+ return ret;
+}
+
static void calculate_dirtyrate(struct DirtyRateConfig config)
{
/* todo */
--
2.27.0

View File

@ -0,0 +1,93 @@
From 466b3eee340f022e53478e706e8d4dc02136b1e1 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:21:57 +0800
Subject: [PATCH] migration/dirtyrate: add DirtyRateStatus to denote
calculation status
add DirtyRateStatus to denote calculating status.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-3-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
atomic name fixup
---
migration/dirtyrate.c | 26 ++++++++++++++++++++++++++
qapi/migration.json | 17 +++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 29ef663acb..44a60bf10d 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -22,6 +22,19 @@
#include "migration.h"
#include "dirtyrate.h"
+static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
+
+static int dirtyrate_set_state(int *state, int old_state, int new_state)
+{
+ assert(new_state < DIRTY_RATE_STATUS__MAX);
+ if (atomic_cmpxchg(state, old_state, new_state) == old_state) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+
static void calculate_dirtyrate(struct DirtyRateConfig config)
{
/* todo */
@@ -31,8 +44,21 @@ static void calculate_dirtyrate(struct DirtyRateConfig config)
void *get_dirtyrate_thread(void *arg)
{
struct DirtyRateConfig config = *(struct DirtyRateConfig *)arg;
+ int ret;
+
+ ret = dirtyrate_set_state(&CalculatingState, DIRTY_RATE_STATUS_UNSTARTED,
+ DIRTY_RATE_STATUS_MEASURING);
+ if (ret == -1) {
+ error_report("change dirtyrate state failed.");
+ return NULL;
+ }
calculate_dirtyrate(config);
+ ret = dirtyrate_set_state(&CalculatingState, DIRTY_RATE_STATUS_MEASURING,
+ DIRTY_RATE_STATUS_MEASURED);
+ if (ret == -1) {
+ error_report("change dirtyrate state failed.");
+ }
return NULL;
}
diff --git a/qapi/migration.json b/qapi/migration.json
index 9cfbaf8c6c..fdddde0af7 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1445,3 +1445,20 @@
# Since: 3.0
##
{ 'command': 'migrate-pause', 'allow-oob': true }
+
+##
+# @DirtyRateStatus:
+#
+# An enumeration of dirtyrate status.
+#
+# @unstarted: the dirtyrate thread has not been started.
+#
+# @measuring: the dirtyrate thread is measuring.
+#
+# @measured: the dirtyrate thread has measured and results are available.
+#
+# Since: 5.2
+#
+##
+{ 'enum': 'DirtyRateStatus',
+ 'data': [ 'unstarted', 'measuring', 'measured'] }
--
2.27.0

View File

@ -0,0 +1,84 @@
From 1cee10fe37193c6b5ed4e765a2a6d1e6c1411922 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:00 +0800
Subject: [PATCH] migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into
ram.h
RAMBLOCK_FOREACH_MIGRATABLE is need in dirtyrate measure,
move the existing definition up into migration/ram.h
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-6-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 1 +
migration/ram.c | 11 +----------
migration/ram.h | 10 ++++++++++
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index cbb323d6ec..1ccc71077d 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -20,6 +20,7 @@
#include "qemu/rcu_queue.h"
#include "qapi/qapi-commands-migration.h"
#include "migration.h"
+#include "ram.h"
#include "dirtyrate.h"
static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
diff --git a/migration/ram.c b/migration/ram.c
index 848059d9fb..1a33c7b3e2 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -159,21 +159,12 @@ out:
return ret;
}
-static bool ramblock_is_ignored(RAMBlock *block)
+bool ramblock_is_ignored(RAMBlock *block)
{
return !qemu_ram_is_migratable(block) ||
(migrate_ignore_shared() && qemu_ram_is_shared(block));
}
-/* Should be holding either ram_list.mutex, or the RCU lock. */
-#define RAMBLOCK_FOREACH_NOT_IGNORED(block) \
- INTERNAL_RAMBLOCK_FOREACH(block) \
- if (ramblock_is_ignored(block)) {} else
-
-#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
- INTERNAL_RAMBLOCK_FOREACH(block) \
- if (!qemu_ram_is_migratable(block)) {} else
-
#undef RAMBLOCK_FOREACH
int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque)
diff --git a/migration/ram.h b/migration/ram.h
index a788ff0e8e..565ec86b1f 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -37,6 +37,16 @@ extern MigrationStats ram_counters;
extern XBZRLECacheStats xbzrle_counters;
extern CompressionStats compression_counters;
+bool ramblock_is_ignored(RAMBlock *block);
+/* Should be holding either ram_list.mutex, or the RCU lock. */
+#define RAMBLOCK_FOREACH_NOT_IGNORED(block) \
+ INTERNAL_RAMBLOCK_FOREACH(block) \
+ if (ramblock_is_ignored(block)) {} else
+
+#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
+ INTERNAL_RAMBLOCK_FOREACH(block) \
+ if (!qemu_ram_is_migratable(block)) {} else
+
int xbzrle_cache_resize(int64_t new_size, Error **errp);
uint64_t ram_bytes_remaining(void);
uint64_t ram_bytes_total(void);
--
2.27.0

View File

@ -0,0 +1,69 @@
From ba399ad806d195f31d0b76fa55363a4147459a5b Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Tue, 29 Sep 2020 11:42:18 +0800
Subject: [PATCH] migration/dirtyrate: present dirty rate only when querying
the rate has completed
Make dirty_rate field optional, present dirty rate only when querying
the rate has completed.
The qmp results is shown as follow:
@unstarted:
{"return":{"status":"unstarted","start-time":0,"calc-time":0},"id":"libvirt-12"}
@measuring:
{"return":{"status":"measuring","start-time":102931,"calc-time":1},"id":"libvirt-85"}
@measured:
{"return":{"status":"measured","dirty-rate":4,"start-time":150146,"calc-time":1},"id":"libvirt-15"}
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Message-Id: <1601350938-128320-3-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 3 +--
qapi/migration.json | 8 +++-----
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index f1c007d569..00c8085456 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -69,9 +69,8 @@ static struct DirtyRateInfo *query_dirty_rate_info(void)
struct DirtyRateInfo *info = g_malloc0(sizeof(DirtyRateInfo));
if (atomic_read(&CalculatingState) == DIRTY_RATE_STATUS_MEASURED) {
+ info->has_dirty_rate = true;
info->dirty_rate = dirty_rate;
- } else {
- info->dirty_rate = -1;
}
info->status = CalculatingState;
diff --git a/qapi/migration.json b/qapi/migration.json
index 76f5b42493..6844ddfab3 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1468,10 +1468,8 @@
#
# Information about current dirty page rate of vm.
#
-# @dirty-rate: @dirtyrate describing the dirty page rate of vm
-# in units of MB/s.
-# If this field returns '-1', it means querying has not
-# yet started or completed.
+# @dirty-rate: an estimate of the dirty page rate of the VM in units of
+# MB/s, present only when estimating the rate has completed.
#
# @status: status containing dirtyrate query status includes
# 'unstarted' or 'measuring' or 'measured'
@@ -1484,7 +1482,7 @@
#
##
{ 'struct': 'DirtyRateInfo',
- 'data': {'dirty-rate': 'int64',
+ 'data': {'*dirty-rate': 'int64',
'status': 'DirtyRateStatus',
'start-time': 'int64',
'calc-time': 'int64'} }
--
2.27.0

View File

@ -0,0 +1,71 @@
From 5de3e40a6c1a4afcc2612ac109326956e7cded63 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Tue, 29 Sep 2020 11:42:17 +0800
Subject: [PATCH] migration/dirtyrate: record start_time and calc_time while at
the measuring state
Querying could include both the start-time and the calc-time while at the measuring
state, allowing a caller to determine when they should expect to come back looking
for a result.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Message-Id: <1601350938-128320-2-git-send-email-zhengchuan@huawei.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 80936a4ca6..f1c007d569 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -83,14 +83,14 @@ static struct DirtyRateInfo *query_dirty_rate_info(void)
return info;
}
-static void reset_dirtyrate_stat(void)
+static void init_dirtyrate_stat(int64_t start_time, int64_t calc_time)
{
DirtyStat.total_dirty_samples = 0;
DirtyStat.total_sample_count = 0;
DirtyStat.total_block_mem_MB = 0;
DirtyStat.dirty_rate = -1;
- DirtyStat.start_time = 0;
- DirtyStat.calc_time = 0;
+ DirtyStat.start_time = start_time;
+ DirtyStat.calc_time = calc_time;
}
static void update_dirtyrate_stat(struct RamblockDirtyInfo *info)
@@ -335,7 +335,6 @@ static void calculate_dirtyrate(struct DirtyRateConfig config)
int64_t initial_time;
rcu_register_thread();
- reset_dirtyrate_stat();
rcu_read_lock();
initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
if (!record_ramblock_hash_info(&block_dinfo, config, &block_count)) {
@@ -365,6 +364,8 @@ void *get_dirtyrate_thread(void *arg)
{
struct DirtyRateConfig config = *(struct DirtyRateConfig *)arg;
int ret;
+ int64_t start_time;
+ int64_t calc_time;
ret = dirtyrate_set_state(&CalculatingState, DIRTY_RATE_STATUS_UNSTARTED,
DIRTY_RATE_STATUS_MEASURING);
@@ -373,6 +374,10 @@ void *get_dirtyrate_thread(void *arg)
return NULL;
}
+ start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
+ calc_time = config.sample_period_seconds;
+ init_dirtyrate_stat(start_time, calc_time);
+
calculate_dirtyrate(config);
ret = dirtyrate_set_state(&CalculatingState, DIRTY_RATE_STATUS_MEASURING,
--
2.27.0

View File

@ -0,0 +1,116 @@
From 18dbd0efc14aa190b2f4c364fa614b0994af5af0 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:21:56 +0800
Subject: [PATCH] migration/dirtyrate: setup up query-dirtyrate framwork
Add get_dirtyrate_thread() functions to setup query-dirtyrate
framework.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Signed-off-by: YanYing Zhuang <ann.zhuangyanying@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-2-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
Makefile.target | 1 +
migration/dirtyrate.c | 38 ++++++++++++++++++++++++++++++++++++++
migration/dirtyrate.h | 28 ++++++++++++++++++++++++++++
3 files changed, 67 insertions(+)
create mode 100644 migration/dirtyrate.c
create mode 100644 migration/dirtyrate.h
diff --git a/Makefile.target b/Makefile.target
index 933b27453a..5ea840964c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -161,6 +161,7 @@ obj-y += qapi/
obj-y += memory.o
obj-y += memory_mapping.o
obj-y += migration/ram.o
+obj-y += migration/dirtyrate.o
LIBS := $(libs_softmmu) $(LIBS)
# Hardware support
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
new file mode 100644
index 0000000000..29ef663acb
--- /dev/null
+++ b/migration/dirtyrate.c
@@ -0,0 +1,38 @@
+/*
+ * Dirtyrate implement code
+ *
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * Authors:
+ * Chuan Zheng <zhengchuan@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "qemu/config-file.h"
+#include "exec/memory.h"
+#include "exec/ram_addr.h"
+#include "exec/target_page.h"
+#include "qemu/rcu_queue.h"
+#include "qapi/qapi-commands-migration.h"
+#include "migration.h"
+#include "dirtyrate.h"
+
+static void calculate_dirtyrate(struct DirtyRateConfig config)
+{
+ /* todo */
+ return;
+}
+
+void *get_dirtyrate_thread(void *arg)
+{
+ struct DirtyRateConfig config = *(struct DirtyRateConfig *)arg;
+
+ calculate_dirtyrate(config);
+
+ return NULL;
+}
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
new file mode 100644
index 0000000000..84ab9409ac
--- /dev/null
+++ b/migration/dirtyrate.h
@@ -0,0 +1,28 @@
+/*
+ * Dirtyrate common functions
+ *
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Chuan Zheng <zhengchuan@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_MIGRATION_DIRTYRATE_H
+#define QEMU_MIGRATION_DIRTYRATE_H
+
+/*
+ * Sample 512 pages per GB as default.
+ * TODO: Make it configurable.
+ */
+#define DIRTYRATE_DEFAULT_SAMPLE_PAGES 512
+
+struct DirtyRateConfig {
+ uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
+ int64_t sample_period_seconds; /* time duration between two sampling */
+};
+
+void *get_dirtyrate_thread(void *arg);
+#endif
--
2.27.0

View File

@ -0,0 +1,43 @@
From 91eed005e1af25f49ab38732cd3c9ea8071331b0 Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Fri, 30 Oct 2020 11:58:01 +0800
Subject: [PATCH] migration/dirtyrate: simplify includes in dirtyrate.c
Remove redundant blank line which is left by Commit 662770af7c6e8c,
also take this opportunity to remove redundant includes in dirtyrate.c.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Message-Id: <1604030281-112946-1-git-send-email-zhengchuan@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 00c8085456..9a6d0e2cc6 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -10,17 +10,16 @@
* See the COPYING file in the top-level directory.
*/
-#include <zlib.h>
#include "qemu/osdep.h"
+#include <zlib.h>
#include "qapi/error.h"
#include "cpu.h"
-#include "qemu/config-file.h"
#include "exec/memory.h"
#include "exec/ram_addr.h"
#include "exec/target_page.h"
#include "qemu/rcu_queue.h"
+#include "qemu/error-report.h"
#include "qapi/qapi-commands-migration.h"
-#include "migration.h"
#include "ram.h"
#include "trace.h"
#include "dirtyrate.h"
--
2.27.0

View File

@ -0,0 +1,92 @@
From 0fcff073292e78e08ee24eb784783156b2974f4a Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 16 Sep 2020 14:22:03 +0800
Subject: [PATCH] migration/dirtyrate: skip sampling ramblock with size below
MIN_RAMBLOCK_SIZE
In order to sample real RAM, skip ramblock with size below MIN_RAMBLOCK_SIZE
which is set as 128M.
Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1600237327-33618-9-git-send-email-zhengchuan@huawei.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
migration/dirtyrate.c | 21 +++++++++++++++++++++
migration/dirtyrate.h | 5 +++++
2 files changed, 26 insertions(+)
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 0412f825dc..97bb883850 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -138,6 +138,18 @@ static void get_ramblock_dirty_info(RAMBlock *block,
strcpy(info->idstr, qemu_ram_get_idstr(block));
}
+static bool skip_sample_ramblock(RAMBlock *block)
+{
+ /*
+ * Sample only blocks larger than MIN_RAMBLOCK_SIZE.
+ */
+ if (qemu_ram_get_used_length(block) < (MIN_RAMBLOCK_SIZE << 10)) {
+ return true;
+ }
+
+ return false;
+}
+
static bool record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
struct DirtyRateConfig config,
int *block_count)
@@ -150,6 +162,9 @@ static bool record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
bool ret = false;
RAMBLOCK_FOREACH_MIGRATABLE(block) {
+ if (skip_sample_ramblock(block)) {
+ continue;
+ }
total_count++;
}
@@ -159,6 +174,9 @@ static bool record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
}
RAMBLOCK_FOREACH_MIGRATABLE(block) {
+ if (skip_sample_ramblock(block)) {
+ continue;
+ }
if (index >= total_count) {
break;
}
@@ -225,6 +243,9 @@ static bool compare_page_hash_info(struct RamblockDirtyInfo *info,
RAMBlock *block = NULL;
RAMBLOCK_FOREACH_MIGRATABLE(block) {
+ if (skip_sample_ramblock(block)) {
+ continue;
+ }
block_dinfo = find_block_matched(block, block_count, info);
if (block_dinfo == NULL) {
continue;
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 312debca6f..be5b8ec2b1 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -24,6 +24,11 @@
*/
#define RAMBLOCK_INFO_MAX_LEN 256
+/*
+ * Minimum RAMBlock size to sample, in megabytes.
+ */
+#define MIN_RAMBLOCK_SIZE 128
+
struct DirtyRateConfig {
uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
int64_t sample_period_seconds; /* time duration between two sampling */
--
2.27.0

View File

@ -1,6 +1,6 @@
Name: qemu Name: qemu
Version: 4.1.0 Version: 4.1.0
Release: 29 Release: 30
Epoch: 2 Epoch: 2
Summary: QEMU is a generic and open source machine emulator and virtualizer Summary: QEMU is a generic and open source machine emulator and virtualizer
License: GPLv2 and BSD and MIT and CC-BY License: GPLv2 and BSD and MIT and CC-BY
@ -249,6 +249,21 @@ Patch0236: block-Remove-unused-include.patch
Patch0237: ssi-Fix-bad-printf-format-specifiers.patch Patch0237: ssi-Fix-bad-printf-format-specifiers.patch
Patch0238: net-l2tpv3-Remove-redundant-check-in-net_init_l2tpv3.patch Patch0238: net-l2tpv3-Remove-redundant-check-in-net_init_l2tpv3.patch
Patch0239: ati-check-x-y-display-parameter-values.patch Patch0239: ati-check-x-y-display-parameter-values.patch
Patch0240: migration-dirtyrate-setup-up-query-dirtyrate-framwor.patch
Patch0241: migration-dirtyrate-add-DirtyRateStatus-to-denote-ca.patch
Patch0242: migration-dirtyrate-Add-RamblockDirtyInfo-to-store-s.patch
Patch0243: migration-dirtyrate-Add-dirtyrate-statistics-series-.patch
Patch0244: migration-dirtyrate-move-RAMBLOCK_FOREACH_MIGRATABLE.patch
Patch0245: migration-dirtyrate-Record-hash-results-for-each-sam.patch
Patch0246: migration-dirtyrate-Compare-page-hash-results-for-re.patch
Patch0247: migration-dirtyrate-skip-sampling-ramblock-with-size.patch
Patch0248: migration-dirtyrate-Implement-set_sample_page_period.patch
Patch0249: migration-dirtyrate-Implement-calculate_dirtyrate-fu.patch
Patch0250: migration-dirtyrate-Implement-qmp_cal_dirty_rate-qmp.patch
Patch0251: migration-dirtyrate-Add-trace_calls-to-make-it-easie.patch
Patch0252: migration-dirtyrate-record-start_time-and-calc_time-.patch
Patch0253: migration-dirtyrate-present-dirty-rate-only-when-que.patch
Patch0254: migration-dirtyrate-simplify-includes-in-dirtyrate.c.patch
BuildRequires: flex BuildRequires: flex
BuildRequires: bison BuildRequires: bison
@ -595,6 +610,23 @@ getent passwd qemu >/dev/null || \
%endif %endif
%changelog %changelog
* Fri Oct 30 2020 Huawei Technologies Co., Ltd <alex.chen@huawei.com>
- migration/dirtyrate: setup up query-dirtyrate framwork
- migration/dirtyrate: add DirtyRateStatus to denote calculation status
- migration/dirtyrate: Add RamblockDirtyInfo to store sampled page info
- migration/dirtyrate: Add dirtyrate statistics series functions
- migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into ram.h
- migration/dirtyrate: Record hash results for each sampled page
- migration/dirtyrate: Compare page hash results for recorded sampled page
- migration/dirtyrate: skip sampling ramblock with size below MIN_RAMBLOCK_SIZE
- migration/dirtyrate: Implement set_sample_page_period() and is_sample_period_valid()
- migration/dirtyrate: Implement calculate_dirtyrate() function
- migration/dirtyrate: Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function
- migration/dirtyrate: Add trace_calls to make it easier to debug
- migration/dirtyrate: record start_time and calc_time while at the measuring state
- migration/dirtyrate: present dirty rate only when querying the rate has completed
- migration/dirtyrate: simplify includes in dirtyrate.c
* Wed Nov 18 2020 Huawei Technologies Co., Ltd <alex.chen@huawei.com> * Wed Nov 18 2020 Huawei Technologies Co., Ltd <alex.chen@huawei.com>
- ati: check x y display parameter values - ati: check x y display parameter values