migration: optimize the downtime
Qemu_savevm_state_cleanup takes about 300ms in my ram migration tests with a 8U24G vm(20G is really occupied), the main cost comes from KVM_SET_USER_MEMORY_REGION ioctl when mem.memory_size = 0 in kvm_set_user_memory_region. In kmod, the main cost is kvm_zap_obsolete_pages, which traverses the active_mmu_pages list to zap the unsync sptes. It can be optimized by delaying memory_global_dirty_log_stop to the next vm_start. Changes v2->v3: - NULL VMChangeStateHandler if it is deleted and protect the scenario of nested invocations of memory_global_dirty_log_start/stop [Paolo] Changes v1->v2: - create a VMChangeStateHandler in memory.c to reduce the coupling [Paolo] Signed-off-by: Jay Zhou <jianjay.zhou@huawei.com> Message-Id: <1501237733-2736-1-git-send-email-jianjay.zhou@huawei.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
8bfce83a3b
commit
1931076077
36
memory.c
36
memory.c
@ -2357,8 +2357,15 @@ void memory_global_dirty_log_sync(void)
|
||||
}
|
||||
}
|
||||
|
||||
static VMChangeStateEntry *vmstate_change;
|
||||
|
||||
void memory_global_dirty_log_start(void)
|
||||
{
|
||||
if (vmstate_change) {
|
||||
qemu_del_vm_change_state_handler(vmstate_change);
|
||||
vmstate_change = NULL;
|
||||
}
|
||||
|
||||
global_dirty_log = true;
|
||||
|
||||
MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward);
|
||||
@ -2369,7 +2376,7 @@ void memory_global_dirty_log_start(void)
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
||||
void memory_global_dirty_log_stop(void)
|
||||
static void memory_global_dirty_log_do_stop(void)
|
||||
{
|
||||
global_dirty_log = false;
|
||||
|
||||
@ -2381,6 +2388,33 @@ void memory_global_dirty_log_stop(void)
|
||||
MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
|
||||
}
|
||||
|
||||
static void memory_vm_change_state_handler(void *opaque, int running,
|
||||
RunState state)
|
||||
{
|
||||
if (running) {
|
||||
memory_global_dirty_log_do_stop();
|
||||
|
||||
if (vmstate_change) {
|
||||
qemu_del_vm_change_state_handler(vmstate_change);
|
||||
vmstate_change = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void memory_global_dirty_log_stop(void)
|
||||
{
|
||||
if (!runstate_is_running()) {
|
||||
if (vmstate_change) {
|
||||
return;
|
||||
}
|
||||
vmstate_change = qemu_add_vm_change_state_handler(
|
||||
memory_vm_change_state_handler, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
memory_global_dirty_log_do_stop();
|
||||
}
|
||||
|
||||
static void listener_add_address_space(MemoryListener *listener,
|
||||
AddressSpace *as)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user