mirror of
https://github.com/xemu-project/xemu.git
synced 2025-03-03 18:17:22 +00:00
117 lines
2.8 KiB
C
117 lines
2.8 KiB
C
![]() |
/*
|
||
|
* Dirty page rate limit implementation code
|
||
|
*
|
||
|
* Copyright (c) 2022 CHINA TELECOM CO.,LTD.
|
||
|
*
|
||
|
* Authors:
|
||
|
* Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
|
||
|
*
|
||
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||
|
* See the COPYING file in the top-level directory.
|
||
|
*/
|
||
|
|
||
|
#include "qemu/osdep.h"
|
||
|
#include "qapi/error.h"
|
||
|
#include "qemu/main-loop.h"
|
||
|
#include "qapi/qapi-commands-migration.h"
|
||
|
#include "sysemu/dirtyrate.h"
|
||
|
#include "sysemu/dirtylimit.h"
|
||
|
#include "exec/memory.h"
|
||
|
#include "hw/boards.h"
|
||
|
|
||
|
struct {
|
||
|
VcpuStat stat;
|
||
|
bool running;
|
||
|
QemuThread thread;
|
||
|
} *vcpu_dirty_rate_stat;
|
||
|
|
||
|
static void vcpu_dirty_rate_stat_collect(void)
|
||
|
{
|
||
|
VcpuStat stat;
|
||
|
int i = 0;
|
||
|
|
||
|
/* calculate vcpu dirtyrate */
|
||
|
vcpu_calculate_dirtyrate(DIRTYLIMIT_CALC_TIME_MS,
|
||
|
&stat,
|
||
|
GLOBAL_DIRTY_LIMIT,
|
||
|
false);
|
||
|
|
||
|
for (i = 0; i < stat.nvcpu; i++) {
|
||
|
vcpu_dirty_rate_stat->stat.rates[i].id = i;
|
||
|
vcpu_dirty_rate_stat->stat.rates[i].dirty_rate =
|
||
|
stat.rates[i].dirty_rate;
|
||
|
}
|
||
|
|
||
|
free(stat.rates);
|
||
|
}
|
||
|
|
||
|
static void *vcpu_dirty_rate_stat_thread(void *opaque)
|
||
|
{
|
||
|
rcu_register_thread();
|
||
|
|
||
|
/* start log sync */
|
||
|
global_dirty_log_change(GLOBAL_DIRTY_LIMIT, true);
|
||
|
|
||
|
while (qatomic_read(&vcpu_dirty_rate_stat->running)) {
|
||
|
vcpu_dirty_rate_stat_collect();
|
||
|
}
|
||
|
|
||
|
/* stop log sync */
|
||
|
global_dirty_log_change(GLOBAL_DIRTY_LIMIT, false);
|
||
|
|
||
|
rcu_unregister_thread();
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
int64_t vcpu_dirty_rate_get(int cpu_index)
|
||
|
{
|
||
|
DirtyRateVcpu *rates = vcpu_dirty_rate_stat->stat.rates;
|
||
|
return qatomic_read_i64(&rates[cpu_index].dirty_rate);
|
||
|
}
|
||
|
|
||
|
void vcpu_dirty_rate_stat_start(void)
|
||
|
{
|
||
|
if (qatomic_read(&vcpu_dirty_rate_stat->running)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
qatomic_set(&vcpu_dirty_rate_stat->running, 1);
|
||
|
qemu_thread_create(&vcpu_dirty_rate_stat->thread,
|
||
|
"dirtyrate-stat",
|
||
|
vcpu_dirty_rate_stat_thread,
|
||
|
NULL,
|
||
|
QEMU_THREAD_JOINABLE);
|
||
|
}
|
||
|
|
||
|
void vcpu_dirty_rate_stat_stop(void)
|
||
|
{
|
||
|
qatomic_set(&vcpu_dirty_rate_stat->running, 0);
|
||
|
qemu_mutex_unlock_iothread();
|
||
|
qemu_thread_join(&vcpu_dirty_rate_stat->thread);
|
||
|
qemu_mutex_lock_iothread();
|
||
|
}
|
||
|
|
||
|
void vcpu_dirty_rate_stat_initialize(void)
|
||
|
{
|
||
|
MachineState *ms = MACHINE(qdev_get_machine());
|
||
|
int max_cpus = ms->smp.max_cpus;
|
||
|
|
||
|
vcpu_dirty_rate_stat =
|
||
|
g_malloc0(sizeof(*vcpu_dirty_rate_stat));
|
||
|
|
||
|
vcpu_dirty_rate_stat->stat.nvcpu = max_cpus;
|
||
|
vcpu_dirty_rate_stat->stat.rates =
|
||
|
g_malloc0(sizeof(DirtyRateVcpu) * max_cpus);
|
||
|
|
||
|
vcpu_dirty_rate_stat->running = false;
|
||
|
}
|
||
|
|
||
|
void vcpu_dirty_rate_stat_finalize(void)
|
||
|
{
|
||
|
free(vcpu_dirty_rate_stat->stat.rates);
|
||
|
vcpu_dirty_rate_stat->stat.rates = NULL;
|
||
|
|
||
|
free(vcpu_dirty_rate_stat);
|
||
|
vcpu_dirty_rate_stat = NULL;
|
||
|
}
|