qemu-devel
[Top][All Lists]
Advanced

[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/ :|
>
>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]