[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] Add inst_dirty_pages_rate in 'info migrate'
From: |
Chao Fan |
Subject: |
Re: [Qemu-devel] [PATCH v2] Add inst_dirty_pages_rate in 'info migrate' |
Date: |
Thu, 9 Mar 2017 18:05:38 +0800 |
User-agent: |
Mutt/1.7.1 (2016-10-04) |
On Wed, Mar 08, 2017 at 01:45:59PM +0000, Daniel P. Berrange wrote:
>On Wed, Mar 08, 2017 at 04:28:19PM +0800, Chao Fan wrote:
>> Auto-converge aims to accelerate migration by slowing down the
>> generation of dirty pages. But user doesn't know how to determine the
>> throttle value, so, a new item "inst-dirty-pages-rate" in "info migrate"
>> would be helpful for user's determination.
Hi Daniel,
Thank you for your reply.
>
>The "info migrate" command already reports a "dirty-pages-rate" value.
>
>Maybe I'm mis-understanding what you're calculcating, this this proposal
>looks the same, except reporting in bytes rather than page counts.
>
>QEMU in fact already records the bytes count internally too in the
>'dirty_pages_bytes' parameter which is calculated from taking
>'dirty_pages_size * TARGET_PAGE_SIZE'.
>
>So I wonder if we can just export the existing dirty-pages-bytes
>value in info migrate, and avoid needing this new code here:
>
It's different, inst-dirty-pages-rate in this patch is greater than
or equal to dirty-pages-bytes. Because in function
cpu_physical_memory_sync_dirty_bitmap, file include/exec/ram_addr.h:
if (src[idx][offset]) {
unsigned long bits = atomic_xchg(&src[idx][offset], 0);
unsigned long new_dirty;
new_dirty = ~dest[k];
dest[k] |= bits;
new_dirty &= bits;
num_dirty += ctpopl(new_dirty);
}
After these codes, only the pages not dirtied in bitmap(dest), but dirtied
in dirty_memory[DIRTY_MEMORY_MIGRATION] will be calculated. For example:
When ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION] = 0b00001111,
and atomic_rcu_read(&migration_bitmap_rcu)->bmap = 0b00000011,
the new_dirty will be 0b00001100, and this function will return 2 but not
4 which is expected.
Thanks,
Chao Fan
>> +static void migration_inst_rate(void)
>> +{
>> + int64_t dirty_pages_time_now;
>> + if (!dirty_pages_time_prev) {
>> + dirty_pages_time_prev = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
>> + }
>> + dirty_pages_time_now = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
>> + if (dirty_pages_time_now > dirty_pages_time_prev + 1000) {
>> + RAMBlock *block;
>> + MigrationState *s = migrate_get_current();
>> + int64_t inst_dirty_pages = 0;
>> + int64_t i;
>> + unsigned long *num;
>> + unsigned long len = 0;
>> +
>> + rcu_read_lock();
>> + DirtyMemoryBlocks *blocks = atomic_rcu_read(
>> + &ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]);
>> + QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
>> + if (len == 0) {
>> + len = block->offset;
>> + }
>> + len += block->used_length;
>> + }
>> + ram_addr_t idx = (len >> TARGET_PAGE_BITS) /
>> DIRTY_MEMORY_BLOCK_SIZE;
>> + if (((len >> TARGET_PAGE_BITS) % DIRTY_MEMORY_BLOCK_SIZE) != 0) {
>> + idx++;
>> + }
>> + for (i = 0; i < idx; i++) {
>> + num = blocks->blocks[i];
>> + inst_dirty_pages += bitmap_weight(num, DIRTY_MEMORY_BLOCK_SIZE);
>> + }
>> + rcu_read_unlock();
>> +
>> + s->inst_dirty_pages_rate = inst_dirty_pages * TARGET_PAGE_SIZE *
>> + 1000 / (dirty_pages_time_now - dirty_pages_time_prev);
>> + }
>> + dirty_pages_time_prev = dirty_pages_time_now;
>> }
>
>Regards,
>Daniel
>--
>|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
>|: http://libvirt.org -o- http://virt-manager.org :|
>|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
>
>