- s390x/sclp: Simplify get_sclp_device() - target/ppc: Remove msr_pr macro - docs/system/target-arm: Re-alphabetize board list - migration: Extend query-migrate to provide dirty page limit info - migration: Implement dirty-limit convergence algo - migration: Put the detection logic before auto-converge checking - migration: Refactor auto-converge capability logic - migration: Introduce dirty-limit capability - qapi/migration: Introduce vcpu-dirty-limit parameters - qapi/migration: Introduce x-vcpu-dirty-limit-period parameter - Change the value of no_ged from true to false - Allow UNIX socket option for VNC websocket - tpm_emulator: Avoid double initialization during - chardev/char-socket: Update AF_UNIX for Windows - KVM: dirty ring: add missing memory barrier - i386: reset KVM nested state upon CPU reset - esp: Handle CMD_BUSRESET by resetting the SCSI bus - dbus-vmstate: Restrict error checks to registered proxies in dbus_get_proxies - vfio/pci: Add Ascend310b scend910b support - target/i386: Export RFDS bit to guests - target/i386: Add new CPU model SierraForest - target/i386: Introduce Icelake-Server-v7 to enable TSX - hw/virtio: handle un-configured shutdown in virtio-pci - target/s390x: display deprecation status in '-cpu help' - target/i386: display deprecation status in '-cpu help' - pc-bios/s390-ccw: Fix booting with logical block size < physical block size Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
177 lines
6.3 KiB
Diff
177 lines
6.3 KiB
Diff
From ba8973a75fffa55977dfa12a850827e11081280f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
|
|
<yong.huang@smartx.com>
|
|
Date: Thu, 8 Jun 2023 00:21:58 +0800
|
|
Subject: [PATCH] migration: Extend query-migrate to provide dirty page limit
|
|
info
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
There is a conflict when merging patches in qemu-6.2.0, and there is a phenomenon that the corresponding files and functions cannot be found.Merge after modifying the patch by wangguochun@kylinos.cn
|
|
|
|
Extend query-migrate to provide throttle time and estimated
|
|
ring full time with dirty-limit capability enabled, through which
|
|
we can observe if dirty limit take effect during live migration.
|
|
|
|
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
|
|
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
|
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
|
Message-ID: <168733225273.5845.15871826788879741674-8@git.sr.ht>
|
|
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
|
---
|
|
include/sysemu/dirtylimit.h | 2 ++
|
|
migration/migration.c | 10 ++++++++++
|
|
monitor/hmp-cmds.c | 10 ++++++++++
|
|
qapi/migration.json | 16 ++++++++++++++-
|
|
softmmu/dirtylimit.c | 39 +++++++++++++++++++++++++++++++++++++
|
|
5 files changed, 76 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/include/sysemu/dirtylimit.h b/include/sysemu/dirtylimit.h
|
|
index 8d2c1f3a6b..d11ebbbbdb 100644
|
|
--- a/include/sysemu/dirtylimit.h
|
|
+++ b/include/sysemu/dirtylimit.h
|
|
@@ -34,4 +34,6 @@ void dirtylimit_set_vcpu(int cpu_index,
|
|
void dirtylimit_set_all(uint64_t quota,
|
|
bool enable);
|
|
void dirtylimit_vcpu_execute(CPUState *cpu);
|
|
+uint64_t dirtylimit_throttle_time_per_round(void);
|
|
+uint64_t dirtylimit_ring_full_time(void);
|
|
#endif
|
|
diff --git a/migration/migration.c b/migration/migration.c
|
|
index e6a2e48f7a..3da2ed37f3 100644
|
|
--- a/migration/migration.c
|
|
+++ b/migration/migration.c
|
|
@@ -61,6 +61,7 @@
|
|
#include "sysemu/cpus.h"
|
|
#include "yank_functions.h"
|
|
#include "sysemu/kvm.h"
|
|
+#include "sysemu/dirtylimit.h"
|
|
|
|
#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */
|
|
|
|
@@ -1060,6 +1061,15 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
|
|
info->ram->remaining = ram_bytes_remaining();
|
|
info->ram->dirty_pages_rate = ram_counters.dirty_pages_rate;
|
|
}
|
|
+
|
|
+ if (migrate_dirty_limit() && dirtylimit_in_service()) {
|
|
+ info->has_dirty_limit_throttle_time_per_round = true;
|
|
+ info->dirty_limit_throttle_time_per_round =
|
|
+ dirtylimit_throttle_time_per_round();
|
|
+
|
|
+ info->has_dirty_limit_ring_full_time = true;
|
|
+ info->dirty_limit_ring_full_time = dirtylimit_ring_full_time();
|
|
+ }
|
|
}
|
|
|
|
static void populate_disk_info(MigrationInfo *info)
|
|
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
|
|
index 01493cd2c0..c139e8087e 100644
|
|
--- a/monitor/hmp-cmds.c
|
|
+++ b/monitor/hmp-cmds.c
|
|
@@ -339,6 +339,16 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
|
info->cpu_throttle_percentage);
|
|
}
|
|
|
|
+ if (info->has_dirty_limit_throttle_time_per_round) {
|
|
+ monitor_printf(mon, "dirty-limit throttle time: %" PRIu64 " us\n",
|
|
+ info->dirty_limit_throttle_time_per_round);
|
|
+ }
|
|
+
|
|
+ if (info->has_dirty_limit_ring_full_time) {
|
|
+ monitor_printf(mon, "dirty-limit ring full time: %" PRIu64 " us\n",
|
|
+ info->dirty_limit_ring_full_time);
|
|
+ }
|
|
+
|
|
if (info->has_postcopy_blocktime) {
|
|
monitor_printf(mon, "postcopy blocktime: %u\n",
|
|
info->postcopy_blocktime);
|
|
diff --git a/qapi/migration.json b/qapi/migration.json
|
|
index 4751c5ee53..a36a4e943b 100644
|
|
--- a/qapi/migration.json
|
|
+++ b/qapi/migration.json
|
|
@@ -228,6 +228,18 @@
|
|
# Present and non-empty when migration is blocked.
|
|
# (since 6.0)
|
|
#
|
|
+# @dirty-limit-throttle-time-per-round: Maximum throttle time (in microseconds) of virtual
|
|
+# CPUs each dirty ring full round, which shows how
|
|
+# MigrationCapability dirty-limit affects the guest
|
|
+# during live migration. (since 8.1)
|
|
+#
|
|
+# @dirty-limit-ring-full-time: Estimated average dirty ring full time (in microseconds)
|
|
+# each dirty ring full round, note that the value equals
|
|
+# dirty ring memory size divided by average dirty page rate
|
|
+# of virtual CPU, which can be used to observe the average
|
|
+# memory load of virtual CPU indirectly. Note that zero
|
|
+# means guest doesn't dirty memory (since 8.1)
|
|
+#
|
|
# Since: 0.14
|
|
##
|
|
{ 'struct': 'MigrationInfo',
|
|
@@ -245,7 +257,9 @@
|
|
'*postcopy-blocktime' : 'uint32',
|
|
'*postcopy-vcpu-blocktime': ['uint32'],
|
|
'*compression': 'CompressionStats',
|
|
- '*socket-address': ['SocketAddress'] } }
|
|
+ '*socket-address': ['SocketAddress'],
|
|
+ '*dirty-limit-throttle-time-per-round': 'uint64',
|
|
+ '*dirty-limit-ring-full-time': 'uint64'} }
|
|
|
|
##
|
|
# @query-migrate:
|
|
diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
|
|
index a3337c0e20..5e6e5aba67 100644
|
|
--- a/softmmu/dirtylimit.c
|
|
+++ b/softmmu/dirtylimit.c
|
|
@@ -564,6 +564,45 @@ out:
|
|
hmp_handle_error(mon, err);
|
|
}
|
|
|
|
+/* Return the max throttle time of each virtual CPU */
|
|
+uint64_t dirtylimit_throttle_time_per_round(void)
|
|
+{
|
|
+ CPUState *cpu;
|
|
+ int64_t max = 0;
|
|
+
|
|
+ CPU_FOREACH(cpu) {
|
|
+ if (cpu->throttle_us_per_full > max) {
|
|
+ max = cpu->throttle_us_per_full;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return max;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Estimate average dirty ring full time of each virtaul CPU.
|
|
+ * Return 0 if guest doesn't dirty memory.
|
|
+ */
|
|
+uint64_t dirtylimit_ring_full_time(void)
|
|
+{
|
|
+ CPUState *cpu;
|
|
+ uint64_t curr_rate = 0;
|
|
+ int nvcpus = 0;
|
|
+
|
|
+ CPU_FOREACH(cpu) {
|
|
+ if (cpu->running) {
|
|
+ nvcpus++;
|
|
+ curr_rate += vcpu_dirty_rate_get(cpu->cpu_index);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!curr_rate || !nvcpus) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return dirtylimit_dirty_ring_full_time(curr_rate / nvcpus);
|
|
+}
|
|
+
|
|
static struct DirtyLimitInfo *dirtylimit_query_vcpu(int cpu_index)
|
|
{
|
|
DirtyLimitInfo *info = NULL;
|
|
--
|
|
2.27.0
|
|
|