* Chuan Zheng (zhengch...@huawei.com) wrote: > From: Zheng Chuan <zhengch...@huawei.com> > > Compare hash results for recorded ramblock. > > Signed-off-by: Zheng Chuan <zhengch...@huawei.com> > Signed-off-by: YanYing Zhang <ann.zhuangyany...@huawei.com> > --- > migration/dirtyrate.c | 77 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 77 insertions(+) > > diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c > index 45cfc91..7badc53 100644 > --- a/migration/dirtyrate.c > +++ b/migration/dirtyrate.c > @@ -202,6 +202,83 @@ static int record_block_hash_info(struct > dirtyrate_config config, > return 0; > } > > +static int cal_block_dirty_rate(struct block_dirty_info *info) > +{ > + uint8_t *md = NULL; > + size_t hash_len; > + int i; > + int ret = 0; > + > + hash_len = qcrypto_hash_digest_len(QCRYPTO_HASH_ALG_MD5); > + md = g_new0(uint8_t, hash_len);
Is 'hash_len' actually constant for a given algorithm, like MD5 ? i.e. can we just have a nice fixed size array? > + for (i = 0; i < info->sample_pages_count; i++) { > + ret = get_block_vfn_hash(info, info->sample_page_vfn[i], &md, > &hash_len); > + if (ret < 0) { > + goto out; > + } > + > + if (memcmp(md, info->hash_result + i * hash_len, hash_len) != 0) { > + info->sample_dirty_count++; When the page doesn't match, do we have to update info->hash_result with the new hash? If the page is only modified once, and we catch it on this cycle, we wouldn't want to catch it next time around. > + } > + } > + > +out: > + g_free(md); > + return ret; > +} > + > +static bool find_block_matched(RAMBlock *block, struct block_dirty_info > *infos, > + int count, struct block_dirty_info **matched) > +{ > + int i; > + > + for (i = 0; i < count; i++) { > + if (!strcmp(infos[i].idstr, qemu_ram_get_idstr(block))) { > + break; > + } > + } > + > + if (i == count) { > + return false; > + } > + > + if (infos[i].block_addr != qemu_ram_get_host_addr(block) || > + infos[i].block_pages != > + (qemu_ram_get_used_length(block) >> DIRTYRATE_PAGE_SIZE_SHIFT)) { How does this happen? > + return false; > + } > + > + *matched = &infos[i]; > + return true; > +} > + > +static int compare_block_hash_info(struct block_dirty_info *info, int > block_index) > +{ > + struct block_dirty_info *block_dinfo = NULL; > + RAMBlock *block = NULL; > + > + RAMBLOCK_FOREACH_MIGRATABLE(block) { > + if (ram_block_skip(block) < 0) { > + continue; > + } > + block_dinfo = NULL; > + if (!find_block_matched(block, info, block_index + 1, &block_dinfo)) > { > + continue; > + } > + if (cal_block_dirty_rate(block_dinfo) < 0) { > + return -1; > + } > + update_dirtyrate_stat(block_dinfo); > + } > + if (!dirty_stat.total_sample_count) { > + return -1; > + } > + > + return 0; > +} > + > + > static void calculate_dirtyrate(struct dirtyrate_config config, int64_t time) > { > /* todo */ > -- > 1.8.3.1 > -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK