From: Hyman Huang(黄勇) <huang...@chinatelecom.cn> implement dirtyrate calculation periodically basing on dirty-ring and throttle vCPU until it reachs the quota dirtyrate given by user.
introduce qmp commands set-dirty-limit/cancel-dirty-limit to set/cancel dirty limit on vCPU. Signed-off-by: Hyman Huang(黄勇) <huang...@chinatelecom.cn> --- cpus-common.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/hw/core/cpu.h | 7 +++++++ qapi/misc.json | 44 ++++++++++++++++++++++++++++++++++++++++++++ softmmu/vl.c | 1 + 4 files changed, 93 insertions(+) diff --git a/cpus-common.c b/cpus-common.c index 6e73d3e..e32612b 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -23,6 +23,11 @@ #include "hw/core/cpu.h" #include "sysemu/cpus.h" #include "qemu/lockable.h" +#include "sysemu/dirtylimit.h" +#include "sysemu/cpu-throttle.h" +#include "sysemu/kvm.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-misc.h" static QemuMutex qemu_cpu_list_lock; static QemuCond exclusive_cond; @@ -352,3 +357,39 @@ void process_queued_cpu_work(CPUState *cpu) qemu_mutex_unlock(&cpu->work_mutex); qemu_cond_broadcast(&qemu_work_cond); } + +void qmp_set_dirty_limit(int64_t idx, + uint64_t dirtyrate, + Error **errp) +{ + if (!kvm_dirty_ring_enabled()) { + error_setg(errp, "dirty ring not enable, needed by dirty restraint!"); + return; + } + + dirtylimit_calc(); + dirtylimit_vcpu(idx, dirtyrate); +} + +void qmp_cancel_dirty_limit(int64_t idx, + Error **errp) +{ + if (!kvm_dirty_ring_enabled()) { + error_setg(errp, "dirty ring not enable, needed by dirty restraint!"); + return; + } + + if (unlikely(!dirtylimit_cancel_vcpu(idx))) { + dirtylimit_calc_quit(); + } +} + +void dirtylimit_setup(int max_cpus) +{ + if (!kvm_dirty_ring_enabled()) { + return; + } + + dirtylimit_calc_state_init(max_cpus); + dirtylimit_state_init(max_cpus); +} diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index e948e81..dd65e9e 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -881,6 +881,13 @@ void end_exclusive(void); */ void qemu_init_vcpu(CPUState *cpu); +/** + * dirtylimit_setup: + * + * dirtylimit setup. + */ +void dirtylimit_setup(int max_cpus); + #define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ #define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ #define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ diff --git a/qapi/misc.json b/qapi/misc.json index 358548a..7f6da34 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -527,3 +527,47 @@ 'data': { '*option': 'str' }, 'returns': ['CommandLineOptionInfo'], 'allow-preconfig': true } + +## +# @DirtyRateQuotaVcpu: +# +# Dirty rate of vcpu. +# +# @idx: vcpu index. +# +# @dirtyrate: dirty rate. +# +# Since: 6.3 +# +## +{ 'struct': 'DirtyRateQuotaVcpu', + 'data': { 'idx': 'int', 'dirtyrate': 'uint64' } } + +## +# @set-dirty-limit: +# +# Since: 6.3 +# +# Example: +# {"execute": "set-dirty-limit"} +# "arguments": { "idx": "cpu-index", +# "dirtyrate": "quota-dirtyrate" } } +# +## +{ 'command': 'set-dirty-limit', + 'data': 'DirtyRateQuotaVcpu' } + +## +# @cancel-dirty-limit: +# +# @idx: index of vCPU to be canceled +# +# Since: 6.3 +# +# Example: +# {"execute": "cancel-dirty-limit"} +# "arguments": { "idx": "cpu-index" } } +# +## +{ 'command': 'cancel-dirty-limit', + 'data': { 'idx': 'int' } } diff --git a/softmmu/vl.c b/softmmu/vl.c index 1159a64..170ee23 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -3776,5 +3776,6 @@ void qemu_init(int argc, char **argv, char **envp) qemu_init_displays(); accel_setup_post(current_machine); os_setup_post(); + dirtylimit_setup(current_machine->smp.max_cpus); resume_mux_open(); } -- 1.8.3.1