diff --git a/migration-dirtyrate-Add-RamblockDirtyInfo-to-store-s.patch b/migration-dirtyrate-Add-RamblockDirtyInfo-to-store-s.patch deleted file mode 100644 index 8028a29..0000000 --- a/migration-dirtyrate-Add-RamblockDirtyInfo-to-store-s.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 17b0582ebba622afbd8f454bbee8141ed2785f13 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: David Edmondson -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-4-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-Add-dirtyrate-statistics-series-.patch b/migration-dirtyrate-Add-dirtyrate-statistics-series-.patch deleted file mode 100644 index 1d56f80..0000000 --- a/migration-dirtyrate-Add-dirtyrate-statistics-series-.patch +++ /dev/null @@ -1,93 +0,0 @@ -From d1340703e127c02e9a586143039507ba10d73cfb Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-5-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-Add-trace_calls-to-make-it-easie.patch b/migration-dirtyrate-Add-trace_calls-to-make-it-easie.patch deleted file mode 100644 index 79d825c..0000000 --- a/migration-dirtyrate-Add-trace_calls-to-make-it-easie.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 8a36332d38c0c0ba6b7d8c096367a4ec7c94e522 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: David Edmondson -Message-Id: <1600237327-33618-13-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-Compare-page-hash-results-for-re.patch b/migration-dirtyrate-Compare-page-hash-results-for-re.patch deleted file mode 100644 index b9277d5..0000000 --- a/migration-dirtyrate-Compare-page-hash-results-for-re.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 949612c5bbc5414970aed7d7ec9390a058ee2246 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Signed-off-by: YanYing Zhuang -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-8-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-Implement-calculate_dirtyrate-fu.patch b/migration-dirtyrate-Implement-calculate_dirtyrate-fu.patch deleted file mode 100644 index 1fcb2c0..0000000 --- a/migration-dirtyrate-Implement-calculate_dirtyrate-fu.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 18102266fb18c4bfcdd4760e7111ca03a7520588 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Signed-off-by: YanYing Zhuang -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-11-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-Implement-qmp_cal_dirty_rate-qmp.patch b/migration-dirtyrate-Implement-qmp_cal_dirty_rate-qmp.patch deleted file mode 100644 index 04893d3..0000000 --- a/migration-dirtyrate-Implement-qmp_cal_dirty_rate-qmp.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 1f5f7156988cee6e678eff253df0e79788c950d7 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Message-Id: <1600237327-33618-12-git-send-email-zhengchuan@huawei.com> -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Dr. David Alan Gilbert - 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 - diff --git a/migration-dirtyrate-Implement-set_sample_page_period.patch b/migration-dirtyrate-Implement-set_sample_page_period.patch deleted file mode 100644 index fdb9c22..0000000 --- a/migration-dirtyrate-Implement-set_sample_page_period.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 905082a502e0600d40e784df2443ae99948cf52d Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: David Edmondson -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-10-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-Record-hash-results-for-each-sam.patch b/migration-dirtyrate-Record-hash-results-for-each-sam.patch deleted file mode 100644 index 5a5a8a9..0000000 --- a/migration-dirtyrate-Record-hash-results-for-each-sam.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 751dbc44b4ac0e0c0bce2f53d2ee79a6e6318188 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Signed-off-by: YanYing Zhuang -Reviewed-by: David Edmondson -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-7-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - #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 - diff --git a/migration-dirtyrate-add-DirtyRateStatus-to-denote-ca.patch b/migration-dirtyrate-add-DirtyRateStatus-to-denote-ca.patch deleted file mode 100644 index e0ebb2a..0000000 --- a/migration-dirtyrate-add-DirtyRateStatus-to-denote-ca.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 466b3eee340f022e53478e706e8d4dc02136b1e1 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-3-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert - 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 - diff --git a/migration-dirtyrate-move-RAMBLOCK_FOREACH_MIGRATABLE.patch b/migration-dirtyrate-move-RAMBLOCK_FOREACH_MIGRATABLE.patch deleted file mode 100644 index 16660d7..0000000 --- a/migration-dirtyrate-move-RAMBLOCK_FOREACH_MIGRATABLE.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 1cee10fe37193c6b5ed4e765a2a6d1e6c1411922 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: David Edmondson -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-6-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-present-dirty-rate-only-when-que.patch b/migration-dirtyrate-present-dirty-rate-only-when-que.patch deleted file mode 100644 index d6d5dd4..0000000 --- a/migration-dirtyrate-present-dirty-rate-only-when-que.patch +++ /dev/null @@ -1,69 +0,0 @@ -From ba399ad806d195f31d0b76fa55363a4147459a5b Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: David Edmondson -Message-Id: <1601350938-128320-3-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-record-start_time-and-calc_time-.patch b/migration-dirtyrate-record-start_time-and-calc_time-.patch deleted file mode 100644 index a4a4fed..0000000 --- a/migration-dirtyrate-record-start_time-and-calc_time-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 5de3e40a6c1a4afcc2612ac109326956e7cded63 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Message-Id: <1601350938-128320-2-git-send-email-zhengchuan@huawei.com> -Reviewed-by: David Edmondson -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/migration-dirtyrate-setup-up-query-dirtyrate-framwor.patch b/migration-dirtyrate-setup-up-query-dirtyrate-framwor.patch deleted file mode 100644 index f4a2b4f..0000000 --- a/migration-dirtyrate-setup-up-query-dirtyrate-framwor.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 18dbd0efc14aa190b2f4c364fa614b0994af5af0 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Signed-off-by: YanYing Zhuang -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: David Edmondson -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-2-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 -+ * -+ * 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 -+ * -+ * 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 - diff --git a/migration-dirtyrate-simplify-includes-in-dirtyrate.c.patch b/migration-dirtyrate-simplify-includes-in-dirtyrate.c.patch deleted file mode 100644 index 3bdb51b..0000000 --- a/migration-dirtyrate-simplify-includes-in-dirtyrate.c.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 91eed005e1af25f49ab38732cd3c9ea8071331b0 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Message-Id: <1604030281-112946-1-git-send-email-zhengchuan@huawei.com> -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - #include "qemu/osdep.h" -+#include - #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 - diff --git a/migration-dirtyrate-skip-sampling-ramblock-with-size.patch b/migration-dirtyrate-skip-sampling-ramblock-with-size.patch deleted file mode 100644 index 0e649e3..0000000 --- a/migration-dirtyrate-skip-sampling-ramblock-with-size.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0fcff073292e78e08ee24eb784783156b2974f4a Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -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 -Reviewed-by: David Edmondson -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Li Qiang -Message-Id: <1600237327-33618-9-git-send-email-zhengchuan@huawei.com> -Signed-off-by: Dr. David Alan Gilbert ---- - 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 - diff --git a/qemu.spec b/qemu.spec index 5924fd3..16893cf 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 38 +Release: 37 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -239,21 +239,6 @@ Patch0226: sd-sdhci-assert-data_count-is-within-fifo_buffer.patch Patch0227: msix-add-valid.accepts-methods-to-check-address.patch Patch0228: ide-atapi-check-io_buffer_index-in-ide_atapi_cmd_rep.patch Patch0229: net-vmxnet3-validate-configuration-values-during-act.patch -Patch0230: migration-dirtyrate-setup-up-query-dirtyrate-framwor.patch -Patch0231: migration-dirtyrate-add-DirtyRateStatus-to-denote-ca.patch -Patch0232: migration-dirtyrate-Add-RamblockDirtyInfo-to-store-s.patch -Patch0233: migration-dirtyrate-Add-dirtyrate-statistics-series-.patch -Patch0234: migration-dirtyrate-move-RAMBLOCK_FOREACH_MIGRATABLE.patch -Patch0235: migration-dirtyrate-Record-hash-results-for-each-sam.patch -Patch0236: migration-dirtyrate-Compare-page-hash-results-for-re.patch -Patch0237: migration-dirtyrate-skip-sampling-ramblock-with-size.patch -Patch0238: migration-dirtyrate-Implement-set_sample_page_period.patch -Patch0239: migration-dirtyrate-Implement-calculate_dirtyrate-fu.patch -Patch0240: migration-dirtyrate-Implement-qmp_cal_dirty_rate-qmp.patch -Patch0241: migration-dirtyrate-Add-trace_calls-to-make-it-easie.patch -Patch0242: migration-dirtyrate-record-start_time-and-calc_time-.patch -Patch0243: migration-dirtyrate-present-dirty-rate-only-when-que.patch -Patch0244: migration-dirtyrate-simplify-includes-in-dirtyrate.c.patch BuildRequires: flex BuildRequires: bison @@ -599,9 +584,6 @@ getent passwd qemu >/dev/null || \ %endif %changelog -* Sat Apr 17 2021 Chuan Zheng -- dirtyrate: add migration dirtyrate feature - * Thu Mar 18 2021 Chen Qun - net: vmxnet3: validate configuration values during activate (CVE-2021-20203)