- support dirty restraint on vCPU - support SPR AMX in Qemu - fix compilation errors of sw64 Signed-off-by: yezengruan <yezengruan@huawei.com>
215 lines
6.1 KiB
Diff
215 lines
6.1 KiB
Diff
From 1c1049bda8e91cc6015c32fc7cc9d0f16ad46b58 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
|
|
<huangy81@chinatelecom.cn>
|
|
Date: Sun, 26 Jun 2022 01:38:33 +0800
|
|
Subject: [PATCH 1/3] softmmu/dirtylimit: Implement vCPU dirtyrate calculation
|
|
periodically
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Introduce the third method GLOBAL_DIRTY_LIMIT of dirty
|
|
tracking for calculate dirtyrate periodly for dirty page
|
|
rate limit.
|
|
|
|
Add dirtylimit.c to implement dirtyrate calculation periodly,
|
|
which will be used for dirty page rate limit.
|
|
|
|
Add dirtylimit.h to export util functions for dirty page rate
|
|
limit implementation.
|
|
|
|
Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
|
|
Reviewed-by: Peter Xu <peterx@redhat.com>
|
|
Message-Id: <5d0d641bffcb9b1c4cc3e323b6dfecb36050d948.1656177590.git.huangy81@chinatelecom.cn>
|
|
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
---
|
|
include/exec/memory.h | 5 +-
|
|
include/sysemu/dirtylimit.h | 22 +++++++
|
|
softmmu/dirtylimit.c | 116 ++++++++++++++++++++++++++++++++++++
|
|
softmmu/meson.build | 1 +
|
|
4 files changed, 143 insertions(+), 1 deletion(-)
|
|
create mode 100644 include/sysemu/dirtylimit.h
|
|
create mode 100644 softmmu/dirtylimit.c
|
|
|
|
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
|
index 3e84d62e40..4326d74b95 100644
|
|
--- a/include/exec/memory.h
|
|
+++ b/include/exec/memory.h
|
|
@@ -69,7 +69,10 @@ static inline void fuzz_dma_read_cb(size_t addr,
|
|
/* Dirty tracking enabled because measuring dirty rate */
|
|
#define GLOBAL_DIRTY_DIRTY_RATE (1U << 1)
|
|
|
|
-#define GLOBAL_DIRTY_MASK (0x3)
|
|
+/* Dirty tracking enabled because dirty limit */
|
|
+#define GLOBAL_DIRTY_LIMIT (1U << 2)
|
|
+
|
|
+#define GLOBAL_DIRTY_MASK (0x7)
|
|
|
|
extern unsigned int global_dirty_tracking;
|
|
|
|
diff --git a/include/sysemu/dirtylimit.h b/include/sysemu/dirtylimit.h
|
|
new file mode 100644
|
|
index 0000000000..da459f03d6
|
|
--- /dev/null
|
|
+++ b/include/sysemu/dirtylimit.h
|
|
@@ -0,0 +1,22 @@
|
|
+/*
|
|
+ * Dirty page rate limit common functions
|
|
+ *
|
|
+ * 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.
|
|
+ */
|
|
+#ifndef QEMU_DIRTYRLIMIT_H
|
|
+#define QEMU_DIRTYRLIMIT_H
|
|
+
|
|
+#define DIRTYLIMIT_CALC_TIME_MS 1000 /* 1000ms */
|
|
+
|
|
+int64_t vcpu_dirty_rate_get(int cpu_index);
|
|
+void vcpu_dirty_rate_stat_start(void);
|
|
+void vcpu_dirty_rate_stat_stop(void);
|
|
+void vcpu_dirty_rate_stat_initialize(void);
|
|
+void vcpu_dirty_rate_stat_finalize(void);
|
|
+#endif
|
|
diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
|
|
new file mode 100644
|
|
index 0000000000..ebdc064c9d
|
|
--- /dev/null
|
|
+++ b/softmmu/dirtylimit.c
|
|
@@ -0,0 +1,116 @@
|
|
+/*
|
|
+ * 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;
|
|
+}
|
|
diff --git a/softmmu/meson.build b/softmmu/meson.build
|
|
index d8e03018ab..95029a5db2 100644
|
|
--- a/softmmu/meson.build
|
|
+++ b/softmmu/meson.build
|
|
@@ -15,6 +15,7 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files(
|
|
'vl.c',
|
|
'cpu-timers.c',
|
|
'runstate-action.c',
|
|
+ 'dirtylimit.c',
|
|
)])
|
|
|
|
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: [files(
|
|
--
|
|
2.27.0
|
|
|