mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 17:53:56 -06:00
softmmu/dirtylimit: Implement virtual CPU throttle
Setup a negative feedback system when vCPU thread handling KVM_EXIT_DIRTY_RING_FULL exit by introducing throttle_us_per_full field in struct CPUState. Sleep throttle_us_per_full microseconds to throttle vCPU if dirtylimit is in service. Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn> Reviewed-by: Peter Xu <peterx@redhat.com> Message-Id: <977e808e03a1cef5151cae75984658b6821be618.1656177590.git.huangy81@chinatelecom.cn> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
parent
4a06a7cc05
commit
baa609832e
5 changed files with 338 additions and 1 deletions
|
@ -45,6 +45,7 @@
|
|||
#include "qemu/guest-random.h"
|
||||
#include "sysemu/hw_accel.h"
|
||||
#include "kvm-cpus.h"
|
||||
#include "sysemu/dirtylimit.h"
|
||||
|
||||
#include "hw/boards.h"
|
||||
#include "monitor/stats.h"
|
||||
|
@ -477,6 +478,7 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
|||
cpu->kvm_state = s;
|
||||
cpu->vcpu_dirty = true;
|
||||
cpu->dirty_pages = 0;
|
||||
cpu->throttle_us_per_full = 0;
|
||||
|
||||
mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
|
||||
if (mmap_size < 0) {
|
||||
|
@ -1470,6 +1472,11 @@ static void *kvm_dirty_ring_reaper_thread(void *data)
|
|||
*/
|
||||
sleep(1);
|
||||
|
||||
/* keep sleeping so that dirtylimit not be interfered by reaper */
|
||||
if (dirtylimit_in_service()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
trace_kvm_dirty_ring_reaper("wakeup");
|
||||
r->reaper_state = KVM_DIRTY_RING_REAPER_REAPING;
|
||||
|
||||
|
@ -2975,8 +2982,19 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||
*/
|
||||
trace_kvm_dirty_ring_full(cpu->cpu_index);
|
||||
qemu_mutex_lock_iothread();
|
||||
kvm_dirty_ring_reap(kvm_state, NULL);
|
||||
/*
|
||||
* We throttle vCPU by making it sleep once it exit from kernel
|
||||
* due to dirty ring full. In the dirtylimit scenario, reaping
|
||||
* all vCPUs after a single vCPU dirty ring get full result in
|
||||
* the miss of sleep, so just reap the ring-fulled vCPU.
|
||||
*/
|
||||
if (dirtylimit_in_service()) {
|
||||
kvm_dirty_ring_reap(kvm_state, cpu);
|
||||
} else {
|
||||
kvm_dirty_ring_reap(kvm_state, NULL);
|
||||
}
|
||||
qemu_mutex_unlock_iothread();
|
||||
dirtylimit_vcpu_execute(cpu);
|
||||
ret = 0;
|
||||
break;
|
||||
case KVM_EXIT_SYSTEM_EVENT:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue