diff options
author | Hyman Huang(黄勇) | 2022-06-25 19:38:35 +0200 |
---|---|---|
committer | Dr. David Alan Gilbert | 2022-07-20 13:15:08 +0200 |
commit | baa609832e1849915b62be2abfbdc1d0e5909a7b (patch) | |
tree | 3a679a7051cd4547dabd3afcf1b777bdb1aae60f /accel/kvm/kvm-all.c | |
parent | accel/kvm/kvm-all: Introduce kvm_dirty_ring_size function (diff) | |
download | qemu-baa609832e1849915b62be2abfbdc1d0e5909a7b.tar.gz qemu-baa609832e1849915b62be2abfbdc1d0e5909a7b.tar.xz qemu-baa609832e1849915b62be2abfbdc1d0e5909a7b.zip |
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>
Diffstat (limited to 'accel/kvm/kvm-all.c')
-rw-r--r-- | accel/kvm/kvm-all.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 184aecab5c..3187656570 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -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: |