From 54e4aa7a8d9258a8694393a085f350afa731c372 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Tue, 8 Feb 2022 20:48:17 +0800 Subject: [PATCH 01/22] cpu: parse +/- feature to avoid failure To avoid cpu feature parse failure, +/- feature is added. Signed-off-by: Xu Yandong Signed-off-by: Mingwang Li --- cpu-parse-feature-to-avoid-failure.patch | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 cpu-parse-feature-to-avoid-failure.patch diff --git a/cpu-parse-feature-to-avoid-failure.patch b/cpu-parse-feature-to-avoid-failure.patch new file mode 100644 index 00000000..4ae42d90 --- /dev/null +++ b/cpu-parse-feature-to-avoid-failure.patch @@ -0,0 +1,68 @@ +From ef83cde8dd2c9b404527354489b14d2bd238733d Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 8 Feb 2022 20:48:17 +0800 +Subject: [PATCH] cpu: parse +/- feature to avoid failure + +To avoid cpu feature parse failure, +/- feature is added. + +Signed-off-by: Xu Yandong +Signed-off-by: Mingwang Li +--- + target/arm/cpu64.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index 15245a60a8..019edc66c9 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -933,10 +933,47 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs) + return g_strdup("aarch64"); + } + ++/* Parse "+feature,-feature,feature=foo" CPU feature string ++ */ ++static void arm_cpu_parse_featurestr(const char *typename, char *features, ++ Error **errp ) ++{ ++ char *featurestr; ++ char *val; ++ static bool cpu_globals_initialized; ++ ++ if (cpu_globals_initialized) { ++ return; ++ } ++ cpu_globals_initialized = true; ++ ++ featurestr = features ? strtok(features, ",") : NULL; ++ while (featurestr) { ++ val = strchr(featurestr, '='); ++ if (val) { ++ GlobalProperty *prop = g_new0(typeof(*prop), 1); ++ *val = 0; ++ val++; ++ prop->driver = typename; ++ prop->property = g_strdup(featurestr); ++ prop->value = g_strdup(val); ++ qdev_prop_register_global(prop); ++ } else if (featurestr[0] == '+' || featurestr[0] == '-') { ++ warn_report("Ignore %s feature\n", featurestr); ++ } else { ++ error_setg(errp, "Expected key=value format, found %s.", ++ featurestr); ++ return; ++ } ++ featurestr = strtok(NULL, ","); ++ } ++} ++ + static void aarch64_cpu_class_init(ObjectClass *oc, void *data) + { + CPUClass *cc = CPU_CLASS(oc); + ++ cc->parse_features = arm_cpu_parse_featurestr; + cc->gdb_read_register = aarch64_cpu_gdb_read_register; + cc->gdb_write_register = aarch64_cpu_gdb_write_register; + cc->gdb_num_core_regs = 34; +-- +2.27.0 + -- Gitee From 578d1369579e2392bc889edadf821a43924bddbf Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Tue, 8 Feb 2022 21:36:22 +0800 Subject: [PATCH 02/22] cpu: add Kunpeng-920 cpu support Add the Kunpeng-920 CPU model Signed-off-by: Xu Yandong Signed-off-by: Mingwang Li --- cpu-add-Kunpeng-920-cpu-support.patch | 68 +++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 cpu-add-Kunpeng-920-cpu-support.patch diff --git a/cpu-add-Kunpeng-920-cpu-support.patch b/cpu-add-Kunpeng-920-cpu-support.patch new file mode 100644 index 00000000..5e24be91 --- /dev/null +++ b/cpu-add-Kunpeng-920-cpu-support.patch @@ -0,0 +1,68 @@ +From 8ebab06c4824626ab4d7204133cd1e7b9c67f468 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 8 Feb 2022 21:36:22 +0800 +Subject: [PATCH] cpu: add Kunpeng-920 cpu support + +Add the Kunpeng-920 CPU model + +Signed-off-by: Xu Yandong +Signed-off-by: Mingwang Li +--- + hw/arm/virt.c | 1 + + target/arm/cpu64.c | 21 +++++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 30da05dfe0..a4a35584e9 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -201,6 +201,7 @@ static const char *valid_cpus[] = { + ARM_CPU_TYPE_NAME("cortex-a53"), + ARM_CPU_TYPE_NAME("cortex-a57"), + ARM_CPU_TYPE_NAME("cortex-a72"), ++ ARM_CPU_TYPE_NAME("Kunpeng-920"), + ARM_CPU_TYPE_NAME("a64fx"), + ARM_CPU_TYPE_NAME("host"), + ARM_CPU_TYPE_NAME("max"), +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index 019edc66c9..aaca79f7c3 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -248,6 +248,26 @@ static void aarch64_a72_initfn(Object *obj) + define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); + } + ++static void aarch64_kunpeng_920_initfn(Object *obj) ++{ ++ ARMCPU *cpu = ARM_CPU(obj); ++ ++ /* ++ * Hisilicon Kunpeng-920 CPU is similar to cortex-a72, ++ * so first initialize cpu data as cortex-a72, ++ * and then update the special register. ++ */ ++ aarch64_a72_initfn(obj); ++ ++ cpu->midr = 0x480fd010; ++ cpu->ctr = 0x84448004; ++ cpu->isar.id_aa64pfr0 = 0x11001111; ++ cpu->isar.id_aa64dfr0 = 0x110305408; ++ cpu->isar.id_aa64isar0 = 0x10211120; ++ cpu->isar.id_aa64mmfr0 = 0x101125; ++ cpu->kvm_target = KVM_ARM_TARGET_GENERIC_V8; ++} ++ + void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) + { + /* +@@ -892,6 +912,7 @@ static const ARMCPUInfo aarch64_cpus[] = { + { .name = "cortex-a57", .initfn = aarch64_a57_initfn }, + { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, + { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, ++ { .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn}, + { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, + { .name = "max", .initfn = aarch64_max_initfn }, + }; +-- +2.27.0 + -- Gitee From f15a05d6a1188800391ac376b3b39a9589e4538d Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Tue, 8 Feb 2022 22:18:55 +0800 Subject: [PATCH 03/22] cpu: add Cortex-A72 processor kvm target support The ARM Cortex-A72 is ARMv8-A micro-architecture, add kvm target to ARM Cortex-A72 processor definition. Signed-off-by: Xu Yandong Signed-off-by: Mingwang Li --- ...tex-A72-processor-kvm-target-support.patch | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 cpu-add-Cortex-A72-processor-kvm-target-support.patch diff --git a/cpu-add-Cortex-A72-processor-kvm-target-support.patch b/cpu-add-Cortex-A72-processor-kvm-target-support.patch new file mode 100644 index 00000000..9a83a8d5 --- /dev/null +++ b/cpu-add-Cortex-A72-processor-kvm-target-support.patch @@ -0,0 +1,51 @@ +From f0da7fa5230b5f771570b2c12288e4a56a20dd97 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 8 Feb 2022 22:18:55 +0800 +Subject: [PATCH] cpu: add Cortex-A72 processor kvm target support + +The ARM Cortex-A72 is ARMv8-A micro-architecture, +add kvm target to ARM Cortex-A72 processor definition. + +Signed-off-by: Xu Yandong +Signed-off-by: Mingwang Li +--- + target/arm/cpu64.c | 1 + + target/arm/kvm-consts.h | 3 +++ + 2 files changed, 4 insertions(+) + +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index aaca79f7c3..556b6f3691 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -202,6 +202,7 @@ static void aarch64_a72_initfn(Object *obj) + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,cortex-a72"; ++ cpu->kvm_target = QEMU_KVM_ARM_TARGET_GENERIC_V8; + set_feature(&cpu->env, ARM_FEATURE_V8); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); +diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h +index 580f1c1fee..5f1311ade7 100644 +--- a/target/arm/kvm-consts.h ++++ b/target/arm/kvm-consts.h +@@ -130,6 +130,8 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED); + #define QEMU_KVM_ARM_TARGET_CORTEX_A57 2 + #define QEMU_KVM_ARM_TARGET_XGENE_POTENZA 3 + #define QEMU_KVM_ARM_TARGET_CORTEX_A53 4 ++/* Generic ARM v8 target */ ++#define QEMU_KVM_ARM_TARGET_GENERIC_V8 5 + + /* There's no kernel define for this: sentinel value which + * matches no KVM target value for either 64 or 32 bit +@@ -141,6 +143,7 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8); + MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57); + MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA); + MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53); ++MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_GENERIC_V8, KVM_ARM_TARGET_GENERIC_V8); + + #define CP_REG_ARM64 0x6000000000000000ULL + #define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000 +-- +2.27.0 + -- Gitee From 94163d806c242c9aa462bc903900990ef3976ff1 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Tue, 8 Feb 2022 22:56:37 +0800 Subject: [PATCH 04/22] add Phytium's CPU models: FT-2000+ and Tengyun-S2500. Signed-off-by: Jiadong Zeng Signed-off-by: Mingwang Li --- ...CPU-models-FT-2000-and-Tengyun-S2500.patch | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch diff --git a/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch b/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch new file mode 100644 index 00000000..0bc4707a --- /dev/null +++ b/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch @@ -0,0 +1,74 @@ +From ec35c96006851a956a7e401f29af0ffe137c4bb9 Mon Sep 17 00:00:00 2001 +From: Jiadong Zeng +Date: Tue, 8 Feb 2022 22:56:37 +0800 +Subject: [PATCH] add Phytium's CPU models: FT-2000+ and Tengyun-S2500. + +Signed-off-by: Jiadong Zeng +Signed-off-by: Mingwang Li +--- + hw/arm/virt.c | 2 ++ + target/arm/cpu64.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index a4a35584e9..3c972fdab0 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -202,6 +202,8 @@ static const char *valid_cpus[] = { + ARM_CPU_TYPE_NAME("cortex-a57"), + ARM_CPU_TYPE_NAME("cortex-a72"), + ARM_CPU_TYPE_NAME("Kunpeng-920"), ++ ARM_CPU_TYPE_NAME("FT-2000+"), ++ ARM_CPU_TYPE_NAME("Tengyun-S2500"), + ARM_CPU_TYPE_NAME("a64fx"), + ARM_CPU_TYPE_NAME("host"), + ARM_CPU_TYPE_NAME("max"), +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index 556b6f3691..08d886de7b 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -676,6 +676,32 @@ static Property arm_cpu_pauth_property = + static Property arm_cpu_pauth_impdef_property = + DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false); + ++static void aarch64_max_ft2000plus_initfn(Object *obj) ++{ ++ ARMCPU *cpu = ARM_CPU(obj); ++ ++ if (kvm_enabled()) { ++ kvm_arm_set_cpu_features_from_host(cpu); ++ kvm_arm_add_vcpu_properties(obj); ++ } else { ++ aarch64_a72_initfn(obj); ++ cpu->midr = 0x70186622; ++ } ++} ++ ++static void aarch64_max_tengyun_s2500_initfn(Object *obj) ++{ ++ ARMCPU *cpu = ARM_CPU(obj); ++ ++ if (kvm_enabled()) { ++ kvm_arm_set_cpu_features_from_host(cpu); ++ kvm_arm_add_vcpu_properties(obj); ++ } else { ++ aarch64_a72_initfn(obj); ++ cpu->midr = 0x70186632; ++ } ++} ++ + /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host); + * otherwise, a CPU with as many features enabled as our emulation supports. + * The version of '-cpu max' for qemu-system-arm is defined in cpu.c; +@@ -914,6 +940,8 @@ static const ARMCPUInfo aarch64_cpus[] = { + { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, + { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, + { .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn}, ++ { .name = "FT-2000+", .initfn = aarch64_max_ft2000plus_initfn }, ++ { .name = "Tengyun-S2500", .initfn = aarch64_max_tengyun_s2500_initfn }, + { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, + { .name = "max", .initfn = aarch64_max_initfn }, + }; +-- +2.27.0 + -- Gitee From b5afdd989e3d0dca62fc9a3a94f2343ff5e018c4 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Wed, 9 Feb 2022 11:28:11 +0800 Subject: [PATCH 05/22] =?UTF-8?q?spec:=20Update=20patch=20and=20changelog?= =?UTF-8?q?=20with=20!225=20=E5=9B=9E=E5=90=88openEuler=20CPU=20model=20?= =?UTF-8?q?=E8=87=AA=E7=A0=94patch=20Merge=20pull=20request=20!225=20from?= =?UTF-8?q?=20limingwang/qemu-6.2.0=20!225?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpu: parse +/- feature to avoid failure cpu: add Kunpeng-920 cpu support cpu: add Cortex-A72 processor kvm target support add Phytium's CPU models: FT-2000+ and Tengyun-S2500. Signed-off-by: Chen Qun --- qemu.spec | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) diff --git a/qemu.spec b/qemu.spec index 4efe98fb..91d7f5da 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,455 +1,919 @@ Name: qemu +Patch0002: cpu-add-Kunpeng-920-cpu-support.patch +Patch0003: cpu-add-Cortex-A72-processor-kvm-target-support.patch +Patch0004: add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch Version: 6.2.0 +Patch0001: cpu-parse-feature-to-avoid-failure.patch Release: 1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch Epoch: 2 +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU is a generic and open source machine emulator and virtualizer +Patch0001: cpu-parse-feature-to-avoid-failure.patch License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 +Patch0001: cpu-parse-feature-to-avoid-failure.patch URL: http://www.qemu.org +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source0: https://www.qemu.org/download/%{name}-%{version}%{?rcstr}.tar.xz +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source1: 80-kvm.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source2: 99-qemu-guest-agent.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch Source3: bridge.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: flex +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gcc +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: bison +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: texinfo +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: perl-podlators +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: kernel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: chrpath +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gettext +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: python-sphinx +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: ninja-build +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: zlib-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: zstd-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gtk3-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: gnutls-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: numactl-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: device-mapper-multipath-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: rdma-core-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libcap-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libcap-ng-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: cyrus-sasl-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libaio-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: usbredir-devel >= 0.5.2 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libseccomp-devel >= 2.3.0 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: systemd-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libiscsi-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: snappy-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: lzo-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: ncurses-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libattr-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libcurl-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libjpeg-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libpng-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: brlapi-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: pixman-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libusbx-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: bzip2-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libepoxy-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libtasn1-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libxml2-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libudev-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: pam-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: perl-Test-Harness +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: python3-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: librbd-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: krb5-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libssh-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: glib2 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: spice-server-devel >= 0.12.5 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: spice-protocol >= 0.12.3 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: libfdt-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch BuildRequires: virglrenderer-devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): /usr/bin/getent +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): /usr/sbin/groupadd +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): /usr/sbin/useradd +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(preun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): qemu-block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): qemu-block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description +Patch0001: cpu-parse-feature-to-avoid-failure.patch QEMU is a FAST! processor emulator using dynamic translation to achieve good emulation speed. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch QEMU has two operating modes: +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch Full system emulation. In this mode, QEMU emulates a full system (for example a PC), +Patch0001: cpu-parse-feature-to-avoid-failure.patch including one or several processors and various peripherals. It can be used to launch +Patch0001: cpu-parse-feature-to-avoid-failure.patch different Operating Systems without rebooting the PC or to debug system code. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch User mode emulation. In this mode, QEMU can launch processes compiled for one CPU on another CPU. +Patch0001: cpu-parse-feature-to-avoid-failure.patch It can be used to launch the Wine Windows API emulator (https://www.winehq.org) or to ease +Patch0001: cpu-parse-feature-to-avoid-failure.patch cross-compilation and cross-debugging. +Patch0001: cpu-parse-feature-to-avoid-failure.patch You can refer to https://www.qemu.org for more infortmation. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU guest agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(post): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(preun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch Requires(postun): systemd-units +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides an agent to run inside guests, which communicates +Patch0001: cpu-parse-feature-to-avoid-failure.patch with the host over a virtio-serial channel named "org.qemu.guest_agent.0" +Patch0001: cpu-parse-feature-to-avoid-failure.patch Please refer to https://wiki.qemu.org/Features/GuestAgent for more information. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package help +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Documents for qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch Buildarch: noarch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description help +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides documents for qemu related man help and information. +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package img +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU command line tool for manipulating disk images +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description img +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides a command line tool for manipulating disk images +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides RBD support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides block-ssh support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides block-iscsi support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: Qemu-block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package provides block-curl support for Qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch %{ix86} x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %package seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch Summary: QEMU seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch %description seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch This package include bios-256k.bin and bios.bin of seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %prep +Patch0001: cpu-parse-feature-to-avoid-failure.patch %setup -q -n qemu-%{version}%{?rcstr} +Patch0001: cpu-parse-feature-to-avoid-failure.patch %autopatch -p1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %build +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch buildarch="x86_64-softmmu" +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch buildarch="aarch64-softmmu" +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch buildldflags="VL_LDFLAGS=-Wl,--build-id" +Patch0001: cpu-parse-feature-to-avoid-failure.patch qemubuilddir="build" +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch ./configure \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --prefix=%{_prefix} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --target-list=${buildarch} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --extra-cflags="%{optflags} -fPIE -DPIE -fPIC" \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --extra-ldflags="-Wl,--build-id -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack" \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --datadir=%{_datadir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --docdir=%{_docdir}/ \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --libdir=%{_libdir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --libexecdir=%{_libexecdir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --localstatedir=%{_localstatedir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --sysconfdir=%{_sysconfdir} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --interp-prefix=%{_prefix}/qemu-%%M \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --firmwarepath=%{_datadir}/%{name} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --with-pkgversion=%{name}-%{version}-%{release} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --python=/usr/bin/python3 \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-slirp \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-gtk \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-docs \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-guest-agent \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-pie \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-numa \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-mpath \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-libnfs \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-bzip2 \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-kvm \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-tcg \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-rdma \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-linux-aio \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-cap-ng \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-vhost-user \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-tpm \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-modules \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-libssh \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-spice \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-fdt \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-virglrenderer \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-cap-ng \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-libusb \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-dmg \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-qcow1 \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-vdi \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-vvfat \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-qed \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-parallels \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-capstone \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-smartcard \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --enable-zstd \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch --disable-plugins +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch make %{?_smp_mflags} $buildldflags V=1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch cp ${qemubuilddir}/${buildarch}/qemu-system-* qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %install +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch make %{?_smp_mflags} DESTDIR=%{buildroot} \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch install +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %find_lang %{name} +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -m 0755 qemu-kvm %{buildroot}%{_libexecdir}/ +Patch0001: cpu-parse-feature-to-avoid-failure.patch ln -s %{_libexecdir}/qemu-kvm %{buildroot}/%{_bindir}/qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm %{buildroot}/%{_bindir}/qemu-system-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 contrib/systemd/qemu-pr-helper.service %{buildroot}%{_unitdir}/qemu-pr-helper.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 contrib/systemd/qemu-pr-helper.socket %{buildroot}%{_unitdir}/qemu-pr-helper.socket +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 qemu.sasl %{buildroot}%{_sysconfdir}/sasl2/qemu.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -m 0644 %{_sourcedir}/bridge.conf %{buildroot}%{_sysconfdir}/qemu/bridge.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -m 0644 %{_sourcedir}/80-kvm.rules %{buildroot}/usr/lib/udev/rules.d/80-kvm.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch # For qemu-guest-agent package +Patch0001: cpu-parse-feature-to-avoid-failure.patch %global _udevdir /lib/udev/rules.d +Patch0001: cpu-parse-feature-to-avoid-failure.patch +- cpu: parse +/- feature to avoid failure +- cpu: add Kunpeng-920 cpu support +- cpu: add Cortex-A72 processor kvm target support +- add Phytium's CPU models: FT-2000+ and Tengyun-S2500. + install -D -p -m 0644 contrib/systemd/qemu-guest-agent.service %{buildroot}%{_unitdir}/qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -m 0644 %{_sourcedir}/99-qemu-guest-agent.rules %{buildroot}%{_udevdir}/99-qemu-guest-agent.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch mkdir -p %{buildroot}%{_localstatedir}/log +Patch0001: cpu-parse-feature-to-avoid-failure.patch touch %{buildroot}%{_localstatedir}/log/qga-fsfreeze-hook.log +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch # For qemu docs package +Patch0001: cpu-parse-feature-to-avoid-failure.patch %global qemudocdir %{_docdir}/%{name} +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/specs +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/.buildinfo +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/objects.inv +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/genindex.html +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{qemudocdir}/index.html +Patch0001: cpu-parse-feature-to-avoid-failure.patch install -D -p -m 0644 -t %{buildroot}%{qemudocdir} README.rst COPYING COPYING.LIB LICENSE +Patch0001: cpu-parse-feature-to-avoid-failure.patch chmod -x %{buildroot}%{_mandir}/man1/* +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch aarch64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vgabios*bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/bios*.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/linuxboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/kvmvapic.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/sgabios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/multiboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/linuxboot_dma.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/pvh.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vgabios-ati.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/bios-microvm.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/multiboot_dma.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/npcm7xx_bootrom.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/openbios-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/slof.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/QEMU,*.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/bamboo.dtb +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/canyonlands.dtb +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware.img +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/palcode-clipper +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/petalogix-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/ppc_* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/qemu_vga.ndrv +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/s390-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/skiboot.lid +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/spapr-* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/u-boot* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_bindir}/ivshmem* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -f %{buildroot}%{_datadir}/%{name}/edk2* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/firmware +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/opensbi* +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/qemu-nsis.bmp +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/audio-oss.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/audio-pa.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/block-gluster.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-curses.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-gtk.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-sdl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/audio-spice.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/chardev-baum.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/chardev-spice.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-display-qxl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-usb-host.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/hw-usb-redirect.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-opengl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-app.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-core.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_libexecdir}/vhost-user-gpu +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vhost-user/50-qemu-gpu.json +Patch0001: cpu-parse-feature-to-avoid-failure.patch rm -rf %{buildroot}%{_datadir}/%{name}/vhost-user/50-qemu-virtiofsd.json +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-rbd.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-iscsi.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-curl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch strip %{buildroot}%{_libdir}/%{name}/block-ssh.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch for f in %{buildroot}%{_bindir}/* %{buildroot}%{_libdir}/* \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{buildroot}%{_libexecdir}/*; do +Patch0001: cpu-parse-feature-to-avoid-failure.patch if file $f | grep -q ELF | grep -q -i shared; then chrpath --delete $f; fi +Patch0001: cpu-parse-feature-to-avoid-failure.patch done +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %check +Patch0001: cpu-parse-feature-to-avoid-failure.patch make check V=1 +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %pre +Patch0001: cpu-parse-feature-to-avoid-failure.patch getent group kvm >/dev/null || groupadd -g 36 -r kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch getent group qemu >/dev/null || groupadd -g 107 -r qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch getent passwd qemu >/dev/null || \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ +Patch0001: cpu-parse-feature-to-avoid-failure.patch -c "qemu user" qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %post guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %systemd_post qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %preun guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %systemd_preun qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %postun guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %systemd_postun_with_restart qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files -f %{name}.lang +Patch0001: cpu-parse-feature-to-avoid-failure.patch %dir %{_datadir}/%{name}/ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libexecdir}/qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-kvm +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/accel-qtest-*.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/accel-tcg-*.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-vga-gl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-vga.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu-gl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu-pci-gl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu-pci.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/hw-display-virtio-gpu.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-virtio.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-e1000.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-e1000e.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-rtl8139.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-pcnet.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-ne2k_pci.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-eepro100.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/efi-vmxnet3.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-virtio.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-e1000.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-ne2k_pci.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-pcnet.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-rtl8139.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pxe-eepro100.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/qboot.rom +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/trace-events-all +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/applications/qemu.desktop +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/icons/hicolor/*/apps/* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/keymaps/ +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/elf2dmp +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-edid +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-keymap +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-pr-helper +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libexecdir}/virtfs-proxy-helper +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libexecdir}/virtiofsd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_unitdir}/qemu-pr-helper.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_unitdir}/qemu-pr-helper.socket +Patch0001: cpu-parse-feature-to-avoid-failure.patch %attr(4755, root, root) %{_libexecdir}/qemu-bridge-helper +Patch0001: cpu-parse-feature-to-avoid-failure.patch %config(noreplace) %{_sysconfdir}/sasl2/qemu.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch %dir %{_sysconfdir}/qemu +Patch0001: cpu-parse-feature-to-avoid-failure.patch %config(noreplace) %{_sysconfdir}/qemu/bridge.conf +Patch0001: cpu-parse-feature-to-avoid-failure.patch /usr/lib/udev/rules.d/80-kvm.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/COPYING +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/COPYING.LIB +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/LICENSE +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios-256k.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-cirrus.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-qxl.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-stdvga.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-vmware.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-virtio.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-ramfb.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/vgabios-bochs-display.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/linuxboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/linuxboot_dma.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/pvh.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/multiboot.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/kvmvapic.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/sgabios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files help +Patch0001: cpu-parse-feature-to-avoid-failure.patch %dir %{qemudocdir} +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/about +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/devel +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/interop +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/search* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/_static +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/system +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/tools +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/user +Patch0001: cpu-parse-feature-to-avoid-failure.patch %doc %{qemudocdir}/README.rst +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/qemu.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/qemu-img.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/qemu-storage-daemon.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/virtfs-proxy-helper.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man1/virtiofsd.1* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-block-drivers.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-cpu-models.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-ga-ref.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-qmp-ref.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man7/qemu-storage-daemon-qmp-ref.7* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-ga.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-nbd.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-pr-helper.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files guest-agent +Patch0001: cpu-parse-feature-to-avoid-failure.patch %defattr(-,root,root,-) +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-ga +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_mandir}/man8/qemu-ga.8* +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_unitdir}/qemu-guest-agent.service +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_udevdir}/99-qemu-guest-agent.rules +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ghost %{_localstatedir}/log/qga-fsfreeze-hook.log +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files img +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-img +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-io +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-nbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_bindir}/qemu-storage-daemon +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-rbd +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-rbd.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-ssh +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-ssh.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-iscsi +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-iscsi.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files block-curl +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_libdir}/%{name}/block-curl.so +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %ifarch %{ix86} x86_64 +Patch0001: cpu-parse-feature-to-avoid-failure.patch %files seabios +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios-256k.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %{_datadir}/%{name}/bios.bin +Patch0001: cpu-parse-feature-to-avoid-failure.patch %endif +Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0001: cpu-parse-feature-to-avoid-failure.patch %changelog +* Wed Feb 09 2022 Chen Qun +Patch0001: cpu-parse-feature-to-avoid-failure.patch * Thu Jan 27 2022 Xiangdong Liu +Patch0001: cpu-parse-feature-to-avoid-failure.patch - Package init +Patch0001: cpu-parse-feature-to-avoid-failure.patch -- Gitee From 39d44ca71649f95d003b03e658843b78f0c16b29 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Mon, 29 Jul 2019 16:22:12 +0800 Subject: [PATCH 06/22] vhost: cancel migration when vhost-user restarted during migraiton Qemu will abort when vhost-user process is restarted during migration when vhost_log_global_start/stop is called. The reason is clear that vhost_dev_set_log returns -1 because network connection is temporarily lost. Let's cancel migraiton and report it to user in this abnormal situation. Signed-off-by: Ying Fang Reviewed-by: Gonglei --- ...ration-when-vhost-user-restarted-dur.patch | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 vhost-cancel-migration-when-vhost-user-restarted-dur.patch diff --git a/vhost-cancel-migration-when-vhost-user-restarted-dur.patch b/vhost-cancel-migration-when-vhost-user-restarted-dur.patch new file mode 100644 index 00000000..b4142d52 --- /dev/null +++ b/vhost-cancel-migration-when-vhost-user-restarted-dur.patch @@ -0,0 +1,60 @@ +From d41206e959717f68a31da4a2d875d33035baeb9f Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Mon, 29 Jul 2019 16:22:12 +0800 +Subject: [PATCH] vhost: cancel migration when vhost-user restarted during + migraiton + +Qemu will abort when vhost-user process is restarted during migration +when vhost_log_global_start/stop is called. The reason is clear that +vhost_dev_set_log returns -1 because network connection is temporarily +lost. Let's cancel migraiton and report it to user in this abnormal +situation. + +Signed-off-by: Ying Fang +Reviewed-by: Gonglei +--- + hw/virtio/vhost.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c +index 437347ad01..dafb23c481 100644 +--- a/hw/virtio/vhost.c ++++ b/hw/virtio/vhost.c +@@ -25,6 +25,7 @@ + #include "hw/virtio/virtio-access.h" + #include "migration/blocker.h" + #include "migration/qemu-file-types.h" ++#include "migration/migration.h" + #include "sysemu/dma.h" + #include "sysemu/tcg.h" + #include "trace.h" +@@ -947,20 +948,24 @@ check_dev_state: + static void vhost_log_global_start(MemoryListener *listener) + { + int r; ++ Error *errp = NULL; + + r = vhost_migration_log(listener, true); + if (r < 0) { +- abort(); ++ error_setg(&errp, "Failed to start vhost migration log"); ++ migrate_fd_error(migrate_get_current(), errp); + } + } + + static void vhost_log_global_stop(MemoryListener *listener) + { + int r; ++ Error *errp = NULL; + + r = vhost_migration_log(listener, false); + if (r < 0) { +- abort(); ++ error_setg(&errp, "Failed to stop vhost migration log"); ++ migrate_fd_error(migrate_get_current(), errp); + } + } + +-- +2.27.0 + -- Gitee From c4a8623e281a99416fdaa742c78af2978745f5f7 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 30 Jan 2021 14:57:54 +0800 Subject: [PATCH 07/22] migration: Add multi-thread compress method A multi-thread compress method parameter is added to hold the method we are going to use. By default the 'zlib' method is used to maintain the compatibility as before. Signed-off-by: Chuan Zheng Signed-off-by: Zeyu Jin Signed-off-by: Ying Fang --- ...ion-Add-multi-thread-compress-method.patch | 238 ++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 migration-Add-multi-thread-compress-method.patch diff --git a/migration-Add-multi-thread-compress-method.patch b/migration-Add-multi-thread-compress-method.patch new file mode 100644 index 00000000..9e259c8b --- /dev/null +++ b/migration-Add-multi-thread-compress-method.patch @@ -0,0 +1,238 @@ +From 39d851b5d5517fbcecc8d16229ae72ca152899b7 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 14:57:54 +0800 +Subject: [PATCH] migration: Add multi-thread compress method + +A multi-thread compress method parameter is added to hold the method we +are going to use. By default the 'zlib' method is used to maintain the +compatibility as before. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + hw/core/qdev-properties-system.c | 11 +++++++++++ + include/hw/qdev-properties.h | 4 ++++ + migration/migration.c | 11 +++++++++++ + monitor/hmp-cmds.c | 13 +++++++++++++ + qapi/migration.json | 26 +++++++++++++++++++++++++- + 5 files changed, 64 insertions(+), 1 deletion(-) + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index a91f60567a..8c265bed6f 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -1119,3 +1119,14 @@ const PropertyInfo qdev_prop_uuid = { + .set = set_uuid, + .set_default_value = set_default_uuid_auto, + }; ++ ++/* --- CompressMethod --- */ ++const PropertyInfo qdev_prop_compress_method = { ++ .name = "CompressMethod", ++ .description = "multi-thread compression method, " ++ "zlib", ++ .enum_table = &CompressMethod_lookup, ++ .get = qdev_propinfo_get_enum, ++ .set = qdev_propinfo_set_enum, ++ .set_default_value = qdev_propinfo_set_default_value_enum, ++}; +diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h +index f7925f67d0..ea129d65a6 100644 +--- a/include/hw/qdev-properties.h ++++ b/include/hw/qdev-properties.h +@@ -58,6 +58,7 @@ extern const PropertyInfo qdev_prop_int64; + extern const PropertyInfo qdev_prop_size; + extern const PropertyInfo qdev_prop_string; + extern const PropertyInfo qdev_prop_on_off_auto; ++extern const PropertyInfo qdev_prop_compress_method; + extern const PropertyInfo qdev_prop_size32; + extern const PropertyInfo qdev_prop_arraylen; + extern const PropertyInfo qdev_prop_link; +@@ -161,6 +162,9 @@ extern const PropertyInfo qdev_prop_link; + DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*) + #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto) ++#define DEFINE_PROP_COMPRESS_METHOD(_n, _s, _f, _d) \ ++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_compress_method, \ ++ CompressMethod) + #define DEFINE_PROP_SIZE32(_n, _s, _f, _d) \ + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size32, uint32_t) + +diff --git a/migration/migration.c b/migration/migration.c +index abaf6f9e3d..fa3db87d75 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -83,6 +83,7 @@ + #define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2 + /*0: means nocompress, 1: best speed, ... 9: best compress ratio */ + #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1 ++#define DEFAULT_MIGRATE_COMPRESS_METHOD COMPRESS_METHOD_ZLIB + /* Define default autoconverge cpu throttle migration parameters */ + #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50 + #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20 +@@ -855,6 +856,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) + params->compress_wait_thread = s->parameters.compress_wait_thread; + params->has_decompress_threads = true; + params->decompress_threads = s->parameters.decompress_threads; ++ params->has_compress_method = true; ++ params->compress_method = s->parameters.compress_method; + params->has_throttle_trigger_threshold = true; + params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; + params->has_cpu_throttle_initial = true; +@@ -1491,6 +1494,10 @@ static void migrate_params_test_apply(MigrateSetParameters *params, + dest->decompress_threads = params->decompress_threads; + } + ++ if (params->has_compress_method) { ++ dest->compress_method = params->compress_method; ++ } ++ + if (params->has_throttle_trigger_threshold) { + dest->throttle_trigger_threshold = params->throttle_trigger_threshold; + } +@@ -4159,6 +4166,9 @@ static Property migration_properties[] = { + DEFINE_PROP_UINT8("x-decompress-threads", MigrationState, + parameters.decompress_threads, + DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT), ++ DEFINE_PROP_COMPRESS_METHOD("compress-method", MigrationState, ++ parameters.compress_method, ++ DEFAULT_MIGRATE_COMPRESS_METHOD), + DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState, + parameters.throttle_trigger_threshold, + DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD), +@@ -4275,6 +4285,7 @@ static void migration_instance_init(Object *obj) + params->has_compress_level = true; + params->has_compress_threads = true; + params->has_decompress_threads = true; ++ params->has_compress_method = true; + params->has_throttle_trigger_threshold = true; + params->has_cpu_throttle_initial = true; + params->has_cpu_throttle_increment = true; +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index 9c91bf93e9..294652034e 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -45,6 +45,7 @@ + #include "qapi/qapi-visit-net.h" + #include "qapi/qapi-visit-migration.h" + #include "qapi/qmp/qdict.h" ++#include "qapi/qapi-visit-migration.h" + #include "qapi/qmp/qerror.h" + #include "qapi/string-input-visitor.h" + #include "qapi/string-output-visitor.h" +@@ -429,6 +430,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) + MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS), + params->decompress_threads); + assert(params->has_throttle_trigger_threshold); ++ monitor_printf(mon, "%s: %s\n", ++ MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_METHOD), ++ CompressMethod_str(params->compress_method)); + monitor_printf(mon, "%s: %u\n", + MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD), + params->throttle_trigger_threshold); +@@ -1191,6 +1195,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) + MigrateSetParameters *p = g_new0(MigrateSetParameters, 1); + uint64_t valuebw = 0; + uint64_t cache_size; ++ CompressMethod compress_method; + Error *err = NULL; + int val, ret; + +@@ -1216,6 +1221,14 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) + p->has_decompress_threads = true; + visit_type_uint8(v, param, &p->decompress_threads, &err); + break; ++ case MIGRATION_PARAMETER_COMPRESS_METHOD: ++ p->has_compress_method = true; ++ visit_type_CompressMethod(v, param, &compress_method, &err); ++ if (err) { ++ break; ++ } ++ p->compress_method = compress_method; ++ break; + case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD: + p->has_throttle_trigger_threshold = true; + visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err); +diff --git a/qapi/migration.json b/qapi/migration.json +index bbfd48cf0b..3a76907ea9 100644 +--- a/qapi/migration.json ++++ b/qapi/migration.json +@@ -596,6 +596,19 @@ + 'bitmaps': [ 'BitmapMigrationBitmapAlias' ] + } } + ++## ++# @CompressMethod: ++# ++# An enumeration of multi-thread compression methods. ++# ++# @zlib: use zlib compression method. ++# ++# Since: 5.0 ++# ++## ++{ 'enum': 'CompressMethod', ++ 'data': [ 'zlib' ] } ++ + ## + # @MigrationParameter: + # +@@ -632,6 +645,9 @@ + # compression, so set the decompress-threads to the number about 1/4 + # of compress-threads is adequate. + # ++# @compress-method: Which multi-thread compression method to use. ++# Defaults to none. (Since 5.0) ++# + # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period + # to trigger throttling. It is expressed as percentage. + # The default value is 50. (Since 5.0) +@@ -758,7 +774,7 @@ + 'data': ['announce-initial', 'announce-max', + 'announce-rounds', 'announce-step', + 'compress-level', 'compress-threads', 'decompress-threads', +- 'compress-wait-thread', 'throttle-trigger-threshold', ++ 'compress-wait-thread', 'compress-method', 'throttle-trigger-threshold', + 'cpu-throttle-initial', 'cpu-throttle-increment', + 'cpu-throttle-tailslow', + 'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth', +@@ -797,6 +813,9 @@ + # + # @decompress-threads: decompression thread count + # ++# @compress-method: Set compression method to use in multi-thread compression. ++# Defaults to none. (Since 5.0) ++# + # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period + # to trigger throttling. It is expressed as percentage. + # The default value is 50. (Since 5.0) +@@ -930,6 +949,7 @@ + '*compress-threads': 'uint8', + '*compress-wait-thread': 'bool', + '*decompress-threads': 'uint8', ++ '*compress-method': 'CompressMethod', + '*throttle-trigger-threshold': 'uint8', + '*cpu-throttle-initial': 'uint8', + '*cpu-throttle-increment': 'uint8', +@@ -995,6 +1015,9 @@ + # + # @decompress-threads: decompression thread count + # ++# @compress-method: Which multi-thread compression method to use. ++# Defaults to none. (Since 5.0) ++# + # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period + # to trigger throttling. It is expressed as percentage. + # The default value is 50. (Since 5.0) +@@ -1128,6 +1151,7 @@ + '*compress-threads': 'uint8', + '*compress-wait-thread': 'bool', + '*decompress-threads': 'uint8', ++ '*compress-method': 'CompressMethod', + '*throttle-trigger-threshold': 'uint8', + '*cpu-throttle-initial': 'uint8', + '*cpu-throttle-increment': 'uint8', +-- +2.27.0 + -- Gitee From 26b6d0fc51cb2f6cd9d21df5164fb150caaa29f8 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 30 Jan 2021 15:21:17 +0800 Subject: [PATCH 08/22] migration: Refactoring multi-thread compress migration Code refactor for the compression procedure which includes: 1. Move qemu_compress_data and qemu_put_compression_data from qemu-file.c to ram.c, for the reason that most part of the code logical has nothing to do with qemu-file. Besides, the decompression code is located at ram.c only. 2. Simplify the function input arguments for compression and decompression. Wrap the input into the param structure which already exists. This change also makes the function much more flexible for other compression methods. Signed-off-by: Chuan Zheng Signed-off-by: Zeyu Jin Signed-off-by: Ying Fang --- ...oring-multi-thread-compress-migratio.patch | 289 ++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 migration-Refactoring-multi-thread-compress-migratio.patch diff --git a/migration-Refactoring-multi-thread-compress-migratio.patch b/migration-Refactoring-multi-thread-compress-migratio.patch new file mode 100644 index 00000000..2f98b3ac --- /dev/null +++ b/migration-Refactoring-multi-thread-compress-migratio.patch @@ -0,0 +1,289 @@ +From b871594aa1798ddcc7f5124e5b3e1c5d858c155c Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 15:21:17 +0800 +Subject: [PATCH] migration: Refactoring multi-thread compress migration + +Code refactor for the compression procedure which includes: + +1. Move qemu_compress_data and qemu_put_compression_data from qemu-file.c to +ram.c, for the reason that most part of the code logical has nothing to do +with qemu-file. Besides, the decompression code is located at ram.c only. + +2. Simplify the function input arguments for compression and decompression. +Wrap the input into the param structure which already exists. This change also +makes the function much more flexible for other compression methods. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + migration/qemu-file.c | 61 ++++++------------------------- + migration/qemu-file.h | 4 +- + migration/ram.c | 85 +++++++++++++++++++++++++++++++------------ + 3 files changed, 75 insertions(+), 75 deletions(-) + +diff --git a/migration/qemu-file.c b/migration/qemu-file.c +index 6338d8e2ff..e07026da4f 100644 +--- a/migration/qemu-file.c ++++ b/migration/qemu-file.c +@@ -745,55 +745,6 @@ uint64_t qemu_get_be64(QEMUFile *f) + return v; + } + +-/* return the size after compression, or negative value on error */ +-static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len, +- const uint8_t *source, size_t source_len) +-{ +- int err; +- +- err = deflateReset(stream); +- if (err != Z_OK) { +- return -1; +- } +- +- stream->avail_in = source_len; +- stream->next_in = (uint8_t *)source; +- stream->avail_out = dest_len; +- stream->next_out = dest; +- +- err = deflate(stream, Z_FINISH); +- if (err != Z_STREAM_END) { +- return -1; +- } +- +- return stream->next_out - dest; +-} +- +-/* Compress size bytes of data start at p and store the compressed +- * data to the buffer of f. +- * +- * Since the file is dummy file with empty_ops, return -1 if f has no space to +- * save the compressed data. +- */ +-ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, +- const uint8_t *p, size_t size) +-{ +- ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t); +- +- if (blen < compressBound(size)) { +- return -1; +- } +- +- blen = qemu_compress_data(stream, f->buf + f->buf_index + sizeof(int32_t), +- blen, p, size); +- if (blen < 0) { +- return -1; +- } +- +- qemu_put_be32(f, blen); +- add_buf_to_iovec(f, blen); +- return blen + sizeof(int32_t); +-} + + /* Put the data in the buffer of f_src to the buffer of f_des, and + * then reset the buf_index of f_src to 0. +@@ -866,3 +817,15 @@ QIOChannel *qemu_file_get_ioc(QEMUFile *file) + { + return file->has_ioc ? QIO_CHANNEL(file->opaque) : NULL; + } ++ ++ssize_t qemu_put_compress_start(QEMUFile *f, uint8_t **dest_ptr) ++{ ++ *dest_ptr = f->buf + f->buf_index + sizeof(int32_t); ++ return IO_BUF_SIZE - f->buf_index - sizeof(int32_t); ++} ++ ++void qemu_put_compress_end(QEMUFile *f, unsigned int v) ++{ ++ qemu_put_be32(f, v); ++ add_buf_to_iovec(f, v); ++} +diff --git a/migration/qemu-file.h b/migration/qemu-file.h +index 3f36d4dc8c..617a1373ad 100644 +--- a/migration/qemu-file.h ++++ b/migration/qemu-file.h +@@ -139,8 +139,6 @@ bool qemu_file_is_writable(QEMUFile *f); + + size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset); + size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size); +-ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, +- const uint8_t *p, size_t size); + int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src); + + /* +@@ -167,6 +165,8 @@ void ram_control_before_iterate(QEMUFile *f, uint64_t flags); + void ram_control_after_iterate(QEMUFile *f, uint64_t flags); + void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data); + ++ssize_t qemu_put_compress_start(QEMUFile *f, uint8_t **dest_ptr); ++void qemu_put_compress_end(QEMUFile *f, unsigned int v); + /* Whenever this is found in the data stream, the flags + * will be passed to ram_control_load_hook in the incoming-migration + * side. This lets before_ram_iterate/after_ram_iterate add +diff --git a/migration/ram.c b/migration/ram.c +index 863035d235..1176816fba 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -449,26 +449,22 @@ static QemuThread *decompress_threads; + static QemuMutex decomp_done_lock; + static QemuCond decomp_done_cond; + +-static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, +- ram_addr_t offset, uint8_t *source_buf); ++static bool do_compress_ram_page(CompressParam *param, RAMBlock *block); + + static void *do_data_compress(void *opaque) + { + CompressParam *param = opaque; + RAMBlock *block; +- ram_addr_t offset; + bool zero_page; + + qemu_mutex_lock(¶m->mutex); + while (!param->quit) { + if (param->block) { + block = param->block; +- offset = param->offset; + param->block = NULL; + qemu_mutex_unlock(¶m->mutex); + +- zero_page = do_compress_ram_page(param->file, ¶m->stream, +- block, offset, param->originbuf); ++ zero_page = do_compress_ram_page(param, block); + + qemu_mutex_lock(&comp_done_lock); + param->done = true; +@@ -1342,28 +1338,73 @@ static int ram_save_multifd_page(RAMState *rs, RAMBlock *block, + return 1; + } + +-static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, +- ram_addr_t offset, uint8_t *source_buf) ++/* ++ * Compress size bytes of data start at p and store the compressed ++ * data to the buffer of f. ++ * ++ * Since the file is dummy file with empty_ops, return -1 if f has no space to ++ * save the compressed data. ++ */ ++static ssize_t qemu_put_compression_data(CompressParam *param, size_t size) ++{ ++ int err; ++ uint8_t *dest = NULL; ++ z_stream *stream = ¶m->stream; ++ uint8_t *p = param->originbuf; ++ QEMUFile *f = f = param->file; ++ ssize_t blen = qemu_put_compress_start(f, &dest); ++ ++ if (blen < compressBound(size)) { ++ return -1; ++ } ++ ++ err = deflateReset(stream); ++ if (err != Z_OK) { ++ return -1; ++ } ++ ++ stream->avail_in = size; ++ stream->next_in = p; ++ stream->avail_out = blen; ++ stream->next_out = dest; ++ ++ err = deflate(stream, Z_FINISH); ++ if (err != Z_STREAM_END) { ++ return -1; ++ } ++ ++ blen = stream->next_out - dest; ++ if (blen < 0) { ++ return -1; ++ } ++ ++ qemu_put_compress_end(f, blen); ++ return blen + sizeof(int32_t); ++} ++ ++static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) + { + RAMState *rs = ram_state; ++ ram_addr_t offset = param->offset; + uint8_t *p = block->host + (offset & TARGET_PAGE_MASK); + bool zero_page = false; + int ret; + +- if (save_zero_page_to_file(rs, f, block, offset)) { ++ if (save_zero_page_to_file(rs, param->file, block, offset)) { + zero_page = true; + goto exit; + } + +- save_page_header(rs, f, block, offset | RAM_SAVE_FLAG_COMPRESS_PAGE); ++ save_page_header(rs, param->file, block, ++ offset | RAM_SAVE_FLAG_COMPRESS_PAGE); + + /* + * copy it to a internal buffer to avoid it being modified by VM + * so that we can catch up the error during compression and + * decompression + */ +- memcpy(source_buf, p, TARGET_PAGE_SIZE); +- ret = qemu_put_compression_data(f, stream, source_buf, TARGET_PAGE_SIZE); ++ memcpy(param->originbuf, p, TARGET_PAGE_SIZE); ++ ret = qemu_put_compression_data(param, TARGET_PAGE_SIZE); + if (ret < 0) { + qemu_file_set_error(migrate_get_current()->to_dst_file, ret); + error_report("compressed data failed!"); +@@ -3374,19 +3415,20 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) + + /* return the size after decompression, or negative value on error */ + static int +-qemu_uncompress_data(z_stream *stream, uint8_t *dest, size_t dest_len, +- const uint8_t *source, size_t source_len) ++qemu_uncompress_data(DecompressParam *param, uint8_t *dest, size_t pagesize) + { + int err; + ++ z_stream *stream = ¶m->stream; ++ + err = inflateReset(stream); + if (err != Z_OK) { + return -1; + } + +- stream->avail_in = source_len; +- stream->next_in = (uint8_t *)source; +- stream->avail_out = dest_len; ++ stream->avail_in = param->len; ++ stream->next_in = param->compbuf; ++ stream->avail_out = pagesize; + stream->next_out = dest; + + err = inflate(stream, Z_NO_FLUSH); +@@ -3400,22 +3442,17 @@ qemu_uncompress_data(z_stream *stream, uint8_t *dest, size_t dest_len, + static void *do_data_decompress(void *opaque) + { + DecompressParam *param = opaque; +- unsigned long pagesize; + uint8_t *des; +- int len, ret; ++ int ret; + + qemu_mutex_lock(¶m->mutex); + while (!param->quit) { + if (param->des) { + des = param->des; +- len = param->len; + param->des = 0; + qemu_mutex_unlock(¶m->mutex); + +- pagesize = TARGET_PAGE_SIZE; +- +- ret = qemu_uncompress_data(¶m->stream, des, pagesize, +- param->compbuf, len); ++ ret = qemu_uncompress_data(param, des, TARGET_PAGE_SIZE); + if (ret < 0 && migrate_get_current()->decompress_error_check) { + error_report("decompress data failed"); + qemu_file_set_error(decomp_file, ret); +-- +2.27.0 + -- Gitee From b717e5114ca96521ad6c08688d2859eb29497642 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 30 Jan 2021 15:57:31 +0800 Subject: [PATCH 09/22] migration: Add multi-thread compress ops Add the MigrationCompressOps and MigrationDecompressOps structures to make the compression method configurable for multi-thread compression migration. Signed-off-by: Chuan Zheng Signed-off-by: Zeyu Jin Signed-off-by: Ying Fang --- migration-Add-multi-thread-compress-ops.patch | 443 ++++++++++++++++++ 1 file changed, 443 insertions(+) create mode 100644 migration-Add-multi-thread-compress-ops.patch diff --git a/migration-Add-multi-thread-compress-ops.patch b/migration-Add-multi-thread-compress-ops.patch new file mode 100644 index 00000000..5787db39 --- /dev/null +++ b/migration-Add-multi-thread-compress-ops.patch @@ -0,0 +1,443 @@ +From 5e4bc7ceaf81a4932c92e479e9add947b698395b Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 15:57:31 +0800 +Subject: [PATCH] migration: Add multi-thread compress ops + +Add the MigrationCompressOps and MigrationDecompressOps structures to make +the compression method configurable for multi-thread compression migration. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + migration/migration.c | 9 ++ + migration/migration.h | 1 + + migration/ram.c | 269 ++++++++++++++++++++++++++++++------------ + 3 files changed, 201 insertions(+), 78 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index fa3db87d75..07dc059251 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2456,6 +2456,15 @@ int migrate_decompress_threads(void) + return s->parameters.decompress_threads; + } + ++CompressMethod migrate_compress_method(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.compress_method; ++} ++ + bool migrate_dirty_bitmaps(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index 8130b703eb..4ed4f555da 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -355,6 +355,7 @@ int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); + int migrate_decompress_threads(void); ++CompressMethod migrate_compress_method(void); + bool migrate_use_events(void); + bool migrate_postcopy_blocktime(void); + bool migrate_background_snapshot(void); +diff --git a/migration/ram.c b/migration/ram.c +index 1176816fba..069560e7f9 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -417,6 +417,9 @@ struct CompressParam { + /* internally used fields */ + z_stream stream; + uint8_t *originbuf; ++ ++ /* for zlib compression */ ++ z_stream stream; + }; + typedef struct CompressParam CompressParam; + +@@ -428,12 +431,29 @@ struct DecompressParam { + void *des; + uint8_t *compbuf; + int len; ++ ++ /* for zlib compression */ + z_stream stream; + }; + typedef struct DecompressParam DecompressParam; + ++typedef struct { ++ int (*save_setup)(CompressParam *param); ++ void (*save_cleanup)(CompressParam *param); ++ ssize_t (*compress_data)(CompressParam *param, size_t size); ++} MigrationCompressOps; ++ ++typedef struct { ++ int (*load_setup)(DecompressParam *param); ++ void (*load_cleanup)(DecompressParam *param); ++ int (*decompress_data)(DecompressParam *param, uint8_t *dest, size_t size); ++ int (*check_len)(int len); ++} MigrationDecompressOps; ++ + static CompressParam *comp_param; + static QemuThread *compress_threads; ++static MigrationCompressOps *compress_ops; ++static MigrationDecompressOps *decompress_ops; + /* comp_done_cond is used to wake up the migration thread when + * one of the compression threads has finished the compression. + * comp_done_lock is used to co-work with comp_done_cond. +@@ -451,6 +471,157 @@ static QemuCond decomp_done_cond; + + static bool do_compress_ram_page(CompressParam *param, RAMBlock *block); + ++static int zlib_save_setup(CompressParam *param) ++{ ++ if (deflateInit(¶m->stream, ++ migrate_compress_level()) != Z_OK) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static ssize_t zlib_compress_data(CompressParam *param, size_t size) ++ ++ int err; ++ uint8_t *dest = NULL; ++ z_stream *stream = ¶m->stream; ++ uint8_t *p = param->originbuf; ++ QEMUFile *f = f = param->file; ++ ssize_t blen = qemu_put_compress_start(f, &dest); ++ ++ if (blen < compressBound(size)) { ++ return -1; ++ } ++ ++ err = deflateReset(stream); ++ if (err != Z_OK) { ++ return -1; ++ } ++ ++ stream->avail_in = size; ++ stream->next_in = p; ++ stream->avail_out = blen; ++ stream->next_out = dest; ++ ++ err = deflate(stream, Z_FINISH); ++ if (err != Z_STREAM_END) { ++ return -1; ++ } ++ ++ blen = stream->next_out - dest; ++ if (blen < 0) { ++ return -1; ++ } ++ ++ qemu_put_compress_end(f, blen); ++ return blen + sizeof(int32_t); ++} ++ ++static void zlib_save_cleanup(CompressParam *param) ++{ ++ deflateEnd(¶m->stream); ++} ++ ++static int zlib_load_setup(DecompressParam *param) ++{ ++ if (inflateInit(¶m->stream) != Z_OK) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++zlib_decompress_data(DecompressParam *param, uint8_t *dest, size_t size) ++{ ++ int err; ++ ++ z_stream *stream = ¶m->stream; ++ ++ err = inflateReset(stream); ++ if (err != Z_OK) { ++ return -1; ++ } ++ ++ stream->avail_in = param->len; ++ stream->next_in = param->compbuf; ++ stream->avail_out = size; ++ stream->next_out = dest; ++ ++ err = inflate(stream, Z_NO_FLUSH); ++ if (err != Z_STREAM_END) { ++ return -1; ++ } ++ ++ return stream->total_out; ++} ++ ++static void zlib_load_cleanup(DecompressParam *param) ++{ ++ inflateEnd(¶m->stream); ++} ++ ++static int zlib_check_len(int len) ++{ ++ return len < 0 || len > compressBound(TARGET_PAGE_SIZE); ++} ++ ++static int set_compress_ops(void) ++{ ++ compress_ops = g_new0(MigrationCompressOps, 1); ++ ++ switch (migrate_compress_method()) { ++ case COMPRESS_METHOD_ZLIB: ++ compress_ops->save_setup = zlib_save_setup; ++ compress_ops->save_cleanup = zlib_save_cleanup; ++ compress_ops->compress_data = zlib_compress_data; ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int set_decompress_ops(void) ++{ ++ decompress_ops = g_new0(MigrationDecompressOps, 1); ++ ++ switch (migrate_compress_method()) { ++ case COMPRESS_METHOD_ZLIB: ++ decompress_ops->load_setup = zlib_load_setup; ++ decompress_ops->load_cleanup = zlib_load_cleanup; ++ decompress_ops->decompress_data = zlib_decompress_data; ++ decompress_ops->check_len = zlib_check_len; ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void clean_compress_ops(void) ++{ ++ compress_ops->save_setup = NULL; ++ compress_ops->save_cleanup = NULL; ++ compress_ops->compress_data = NULL; ++ ++ g_free(compress_ops); ++ compress_ops = NULL; ++} ++ ++static void clean_decompress_ops(void) ++{ ++ decompress_ops->load_setup = NULL; ++ decompress_ops->load_cleanup = NULL; ++ decompress_ops->decompress_data = NULL; ++ ++ g_free(decompress_ops); ++ decompress_ops = NULL; ++} ++ + static void *do_data_compress(void *opaque) + { + CompressParam *param = opaque; +@@ -508,7 +679,7 @@ static void compress_threads_save_cleanup(void) + qemu_thread_join(compress_threads + i); + qemu_mutex_destroy(&comp_param[i].mutex); + qemu_cond_destroy(&comp_param[i].cond); +- deflateEnd(&comp_param[i].stream); ++ compress_ops->save_cleanup(&comp_param[i]); + g_free(comp_param[i].originbuf); + qemu_fclose(comp_param[i].file); + comp_param[i].file = NULL; +@@ -519,6 +690,7 @@ static void compress_threads_save_cleanup(void) + g_free(comp_param); + compress_threads = NULL; + comp_param = NULL; ++ clean_compress_ops(); + } + + static int compress_threads_save_setup(void) +@@ -528,6 +700,12 @@ static int compress_threads_save_setup(void) + if (!migrate_use_compression()) { + return 0; + } ++ ++ if (set_compress_ops() < 0) { ++ clean_compress_ops(); ++ return -1; ++ } ++ + thread_count = migrate_compress_threads(); + compress_threads = g_new0(QemuThread, thread_count); + comp_param = g_new0(CompressParam, thread_count); +@@ -539,8 +717,7 @@ static int compress_threads_save_setup(void) + goto exit; + } + +- if (deflateInit(&comp_param[i].stream, +- migrate_compress_level()) != Z_OK) { ++ if (compress_ops->save_setup(&comp_param[i]) < 0) { + g_free(comp_param[i].originbuf); + goto exit; + } +@@ -1338,50 +1515,6 @@ static int ram_save_multifd_page(RAMState *rs, RAMBlock *block, + return 1; + } + +-/* +- * Compress size bytes of data start at p and store the compressed +- * data to the buffer of f. +- * +- * Since the file is dummy file with empty_ops, return -1 if f has no space to +- * save the compressed data. +- */ +-static ssize_t qemu_put_compression_data(CompressParam *param, size_t size) +-{ +- int err; +- uint8_t *dest = NULL; +- z_stream *stream = ¶m->stream; +- uint8_t *p = param->originbuf; +- QEMUFile *f = f = param->file; +- ssize_t blen = qemu_put_compress_start(f, &dest); +- +- if (blen < compressBound(size)) { +- return -1; +- } +- +- err = deflateReset(stream); +- if (err != Z_OK) { +- return -1; +- } +- +- stream->avail_in = size; +- stream->next_in = p; +- stream->avail_out = blen; +- stream->next_out = dest; +- +- err = deflate(stream, Z_FINISH); +- if (err != Z_STREAM_END) { +- return -1; +- } +- +- blen = stream->next_out - dest; +- if (blen < 0) { +- return -1; +- } +- +- qemu_put_compress_end(f, blen); +- return blen + sizeof(int32_t); +-} +- + static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) + { + RAMState *rs = ram_state; +@@ -1404,7 +1537,7 @@ static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) + * decompression + */ + memcpy(param->originbuf, p, TARGET_PAGE_SIZE); +- ret = qemu_put_compression_data(param, TARGET_PAGE_SIZE); ++ ret = compress_ops->compress_data(param, TARGET_PAGE_SIZE); + if (ret < 0) { + qemu_file_set_error(migrate_get_current()->to_dst_file, ret); + error_report("compressed data failed!"); +@@ -3413,32 +3546,6 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) + } + } + +-/* return the size after decompression, or negative value on error */ +-static int +-qemu_uncompress_data(DecompressParam *param, uint8_t *dest, size_t pagesize) +-{ +- int err; +- +- z_stream *stream = ¶m->stream; +- +- err = inflateReset(stream); +- if (err != Z_OK) { +- return -1; +- } +- +- stream->avail_in = param->len; +- stream->next_in = param->compbuf; +- stream->avail_out = pagesize; +- stream->next_out = dest; +- +- err = inflate(stream, Z_NO_FLUSH); +- if (err != Z_STREAM_END) { +- return -1; +- } +- +- return stream->total_out; +-} +- + static void *do_data_decompress(void *opaque) + { + DecompressParam *param = opaque; +@@ -3452,7 +3559,7 @@ static void *do_data_decompress(void *opaque) + param->des = 0; + qemu_mutex_unlock(¶m->mutex); + +- ret = qemu_uncompress_data(param, des, TARGET_PAGE_SIZE); ++ ret = decompress_ops->decompress_data(param, des, TARGET_PAGE_SIZE); + if (ret < 0 && migrate_get_current()->decompress_error_check) { + error_report("decompress data failed"); + qemu_file_set_error(decomp_file, ret); +@@ -3522,7 +3629,7 @@ static void compress_threads_load_cleanup(void) + qemu_thread_join(decompress_threads + i); + qemu_mutex_destroy(&decomp_param[i].mutex); + qemu_cond_destroy(&decomp_param[i].cond); +- inflateEnd(&decomp_param[i].stream); ++ decompress_ops->load_cleanup(&decomp_param[i]); + g_free(decomp_param[i].compbuf); + decomp_param[i].compbuf = NULL; + } +@@ -3531,6 +3638,7 @@ static void compress_threads_load_cleanup(void) + decompress_threads = NULL; + decomp_param = NULL; + decomp_file = NULL; ++ clean_decompress_ops(); + } + + static int compress_threads_load_setup(QEMUFile *f) +@@ -3541,6 +3649,11 @@ static int compress_threads_load_setup(QEMUFile *f) + return 0; + } + ++ if (set_decompress_ops() < 0) { ++ clean_decompress_ops(); ++ return -1; ++ } ++ + thread_count = migrate_decompress_threads(); + decompress_threads = g_new0(QemuThread, thread_count); + decomp_param = g_new0(DecompressParam, thread_count); +@@ -3548,7 +3661,7 @@ static int compress_threads_load_setup(QEMUFile *f) + qemu_cond_init(&decomp_done_cond); + decomp_file = f; + for (i = 0; i < thread_count; i++) { +- if (inflateInit(&decomp_param[i].stream) != Z_OK) { ++ if (decompress_ops->load_setup(&decomp_param[i]) < 0) { + goto exit; + } + +@@ -4156,7 +4269,7 @@ static int ram_load_precopy(QEMUFile *f) + + case RAM_SAVE_FLAG_COMPRESS_PAGE: + len = qemu_get_be32(f); +- if (len < 0 || len > compressBound(TARGET_PAGE_SIZE)) { ++ if (decompress_ops->check_len(len)) { + error_report("Invalid compressed data length: %d", len); + ret = -EINVAL; + break; +-- +2.27.0 + -- Gitee From 7ec0ecb91eb4368f962ae899562ae58682a93a9c Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 30 Jan 2021 16:15:10 +0800 Subject: [PATCH 10/22] migration: Add zstd support in multi-thread compression This patch enables zstd option in multi-thread compression. Signed-off-by: Chuan Zheng Signed-off-by: Zeyu Jin Signed-off-by: Ying Fang --- ...td-support-in-multi-thread-compressi.patch | 239 ++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 migration-Add-zstd-support-in-multi-thread-compressi.patch diff --git a/migration-Add-zstd-support-in-multi-thread-compressi.patch b/migration-Add-zstd-support-in-multi-thread-compressi.patch new file mode 100644 index 00000000..26d665a8 --- /dev/null +++ b/migration-Add-zstd-support-in-multi-thread-compressi.patch @@ -0,0 +1,239 @@ +From bafba05f7405ba31213120d99679cc4b6c1be68e Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 16:15:10 +0800 +Subject: [PATCH] migration: Add zstd support in multi-thread compression + +This patch enables zstd option in multi-thread compression. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + hw/core/qdev-properties-system.c | 2 +- + migration/ram.c | 131 ++++++++++++++++++++++++++++++- + qapi/migration.json | 3 +- + 3 files changed, 132 insertions(+), 4 deletions(-) + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index 8c265bed6f..6a6ff03be7 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -1124,7 +1124,7 @@ const PropertyInfo qdev_prop_uuid = { + const PropertyInfo qdev_prop_compress_method = { + .name = "CompressMethod", + .description = "multi-thread compression method, " +- "zlib", ++ "zlib/zstd", + .enum_table = &CompressMethod_lookup, + .get = qdev_propinfo_get_enum, + .set = qdev_propinfo_set_enum, +diff --git a/migration/ram.c b/migration/ram.c +index 069560e7f9..c3484ee1a9 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -62,6 +62,11 @@ + #include "qemu/userfaultfd.h" + #endif /* defined(__linux__) */ + ++#ifdef CONFIG_ZSTD ++#include ++#include ++#endif ++ + /***********************************************************/ + /* ram save/restore */ + +@@ -415,11 +420,16 @@ struct CompressParam { + ram_addr_t offset; + + /* internally used fields */ +- z_stream stream; + uint8_t *originbuf; + + /* for zlib compression */ + z_stream stream; ++ ++#ifdef CONFIG_ZSTD ++ ZSTD_CStream *zstd_cs; ++ ZSTD_inBuffer in; ++ ZSTD_outBuffer out; ++#endif + }; + typedef struct CompressParam CompressParam; + +@@ -434,6 +444,11 @@ struct DecompressParam { + + /* for zlib compression */ + z_stream stream; ++#ifdef CONFIG_ZSTD ++ ZSTD_DStream *zstd_ds; ++ ZSTD_inBuffer in; ++ ZSTD_outBuffer out; ++#endif + }; + typedef struct DecompressParam DecompressParam; + +@@ -482,7 +497,7 @@ static int zlib_save_setup(CompressParam *param) + } + + static ssize_t zlib_compress_data(CompressParam *param, size_t size) +- ++{ + int err; + uint8_t *dest = NULL; + z_stream *stream = ¶m->stream; +@@ -567,6 +582,103 @@ static int zlib_check_len(int len) + return len < 0 || len > compressBound(TARGET_PAGE_SIZE); + } + ++#ifdef CONFIG_ZSTD ++static int zstd_save_setup(CompressParam *param) ++{ ++ int res; ++ param->zstd_cs = ZSTD_createCStream(); ++ if (!param->zstd_cs) { ++ return -1; ++ } ++ res = ZSTD_initCStream(param->zstd_cs, migrate_compress_level()); ++ if (ZSTD_isError(res)) { ++ return -1; ++ } ++ return 0; ++} ++static void zstd_save_cleanup(CompressParam *param) ++{ ++ ZSTD_freeCStream(param->zstd_cs); ++ param->zstd_cs = NULL; ++} ++static ssize_t zstd_compress_data(CompressParam *param, size_t size) ++{ ++ int ret; ++ uint8_t *dest = NULL; ++ uint8_t *p = param->originbuf; ++ QEMUFile *f = f = param->file; ++ ssize_t blen = qemu_put_compress_start(f, &dest); ++ if (blen < ZSTD_compressBound(size)) { ++ return -1; ++ } ++ param->out.dst = dest; ++ param->out.size = blen; ++ param->out.pos = 0; ++ param->in.src = p; ++ param->in.size = size; ++ param->in.pos = 0; ++ do { ++ ret = ZSTD_compressStream2(param->zstd_cs, ¶m->out, ++ ¶m->in, ZSTD_e_end); ++ } while (ret > 0 && (param->in.size - param->in.pos > 0) ++ && (param->out.size - param->out.pos > 0)); ++ if (ret > 0 && (param->in.size - param->in.pos > 0)) { ++ return -1; ++ } ++ if (ZSTD_isError(ret)) { ++ return -1; ++ } ++ blen = param->out.pos; ++ qemu_put_compress_end(f, blen); ++ return blen + sizeof(int32_t); ++} ++ ++static int zstd_load_setup(DecompressParam *param) ++{ ++ int ret; ++ param->zstd_ds = ZSTD_createDStream(); ++ if (!param->zstd_ds) { ++ return -1; ++ } ++ ret = ZSTD_initDStream(param->zstd_ds); ++ if (ZSTD_isError(ret)) { ++ return -1; ++ } ++ return 0; ++} ++static void zstd_load_cleanup(DecompressParam *param) ++{ ++ ZSTD_freeDStream(param->zstd_ds); ++ param->zstd_ds = NULL; ++} ++static int ++zstd_decompress_data(DecompressParam *param, uint8_t *dest, size_t size) ++{ ++ int ret; ++ param->out.dst = dest; ++ param->out.size = size; ++ param->out.pos = 0; ++ param->in.src = param->compbuf; ++ param->in.size = param->len; ++ param->in.pos = 0; ++ do { ++ ret = ZSTD_decompressStream(param->zstd_ds, ¶m->out, ¶m->in); ++ } while (ret > 0 && (param->in.size - param->in.pos > 0) ++ && (param->out.size - param->out.pos > 0)); ++ if (ret > 0 && (param->in.size - param->in.pos > 0)) { ++ return -1; ++ } ++ if (ZSTD_isError(ret)) { ++ return -1; ++ } ++ return ret; ++} ++static int zstd_check_len(int len) ++{ ++ return len < 0 || len > ZSTD_compressBound(TARGET_PAGE_SIZE); ++} ++#endif ++ + static int set_compress_ops(void) + { + compress_ops = g_new0(MigrationCompressOps, 1); +@@ -577,6 +689,13 @@ static int set_compress_ops(void) + compress_ops->save_cleanup = zlib_save_cleanup; + compress_ops->compress_data = zlib_compress_data; + break; ++#ifdef CONFIG_ZSTD ++ case COMPRESS_METHOD_ZSTD: ++ compress_ops->save_setup = zstd_save_setup; ++ compress_ops->save_cleanup = zstd_save_cleanup; ++ compress_ops->compress_data = zstd_compress_data; ++ break; ++#endif + default: + return -1; + } +@@ -595,6 +714,14 @@ static int set_decompress_ops(void) + decompress_ops->decompress_data = zlib_decompress_data; + decompress_ops->check_len = zlib_check_len; + break; ++#ifdef CONFIG_ZSTD ++ case COMPRESS_METHOD_ZSTD: ++ decompress_ops->load_setup = zstd_load_setup; ++ decompress_ops->load_cleanup = zstd_load_cleanup; ++ decompress_ops->decompress_data = zstd_decompress_data; ++ decompress_ops->check_len = zstd_check_len; ++ break; ++#endif + default: + return -1; + } +diff --git a/qapi/migration.json b/qapi/migration.json +index 3a76907ea9..d4ebc5f028 100644 +--- a/qapi/migration.json ++++ b/qapi/migration.json +@@ -602,12 +602,13 @@ + # An enumeration of multi-thread compression methods. + # + # @zlib: use zlib compression method. ++# @zstd: use zstd compression method. + # + # Since: 5.0 + # + ## + { 'enum': 'CompressMethod', +- 'data': [ 'zlib' ] } ++ 'data': [ 'zlib', { 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] } + + ## + # @MigrationParameter: +-- +2.27.0 + -- Gitee From 83f00ba81a7e547dda2d35242c7c90ca4bddb16a Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 30 Jan 2021 16:23:15 +0800 Subject: [PATCH 11/22] migration: Add compress_level sanity check Zlib compression has level from 1 to 9. However Zstd compression has level from 1 to 22 (level >= 20 not recommanded). Let's do sanity check here to make sure a vaild compress_level is given by user. Signed-off-by: Chuan Zheng Signed-off-by: Zeyu Jin Signed-off-by: Ying Fang --- ...tion-Add-compress_level-sanity-check.patch | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 migration-Add-compress_level-sanity-check.patch diff --git a/migration-Add-compress_level-sanity-check.patch b/migration-Add-compress_level-sanity-check.patch new file mode 100644 index 00000000..bcf2e73f --- /dev/null +++ b/migration-Add-compress_level-sanity-check.patch @@ -0,0 +1,66 @@ +From 84780210ac31e430d59b0c6d3d9f522c626b6380 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 16:23:15 +0800 +Subject: [PATCH] migration: Add compress_level sanity check + +Zlib compression has level from 1 to 9. However Zstd compression has level +from 1 to 22 (level >= 20 not recommanded). Let's do sanity check here +to make sure a vaild compress_level is given by user. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + migration/migration.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 07dc059251..f86dd8cccd 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1320,14 +1320,40 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, + } + } + ++static bool compress_level_check(MigrationParameters *params, Error **errp) ++{ ++ switch (params->compress_method) { ++ case COMPRESS_METHOD_ZLIB: ++ if (params->compress_level > 9 || params->compress_level < 1) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", ++ "a value in the range of 0 to 9 for Zlib method"); ++ return false; ++ } ++ break; ++#ifdef CONFIG_ZSTD ++ case COMPRESS_METHOD_ZSTD: ++ if (params->compress_level > 19 || params->compress_level < 1) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", ++ "a value in the range of 1 to 19 for Zstd method"); ++ return false; ++ } ++ break; ++#endif ++ default: ++ error_setg(errp, "Checking compress_level failed for unknown reason"); ++ return false; ++ } ++ ++ return true; ++} ++ + /* + * Check whether the parameters are valid. Error will be put into errp + * (if provided). Return true if valid, otherwise false. + */ + static bool migrate_params_check(MigrationParameters *params, Error **errp) + { +- if (params->has_compress_level && +- (params->compress_level > 9)) { ++ if (params->has_compress_level && !compress_level_check(params, errp)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", + "a value between 0 and 9"); + return false; +-- +2.27.0 + -- Gitee From 65f8feccd7f8e4dd54a1321c1dbd6144dda8ce8f Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 30 Jan 2021 16:36:47 +0800 Subject: [PATCH 12/22] doc: Update multi-thread compression doc Modify the doc to fit the previous changes. Signed-off-by: Chuan Zheng Signed-off-by: Zeyu Jin Signed-off-by: Ying Fang --- doc-Update-multi-thread-compression-doc.patch | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 doc-Update-multi-thread-compression-doc.patch diff --git a/doc-Update-multi-thread-compression-doc.patch b/doc-Update-multi-thread-compression-doc.patch new file mode 100644 index 00000000..ad47a0b8 --- /dev/null +++ b/doc-Update-multi-thread-compression-doc.patch @@ -0,0 +1,86 @@ +From 213bd45d2c5337f10216c69c13f0438dd40c58d8 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Sat, 30 Jan 2021 16:36:47 +0800 +Subject: [PATCH] doc: Update multi-thread compression doc + +Modify the doc to fit the previous changes. + +Signed-off-by: Chuan Zheng +Signed-off-by: Zeyu Jin +Signed-off-by: Ying Fang +--- + docs/multi-thread-compression.txt | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/docs/multi-thread-compression.txt b/docs/multi-thread-compression.txt +index bb88c6bdf1..d429963cb0 100644 +--- a/docs/multi-thread-compression.txt ++++ b/docs/multi-thread-compression.txt +@@ -33,14 +33,15 @@ thread compression can be used to accelerate the compression process. + + The decompression speed of Zlib is at least 4 times as quick as + compression, if the source and destination CPU have equal speed, +-keeping the compression thread count 4 times the decompression +-thread count can avoid resource waste. ++and you choose Zlib as compression method, keeping the compression ++thread count 4 times the decompression thread count can avoid resource waste. + + Compression level can be used to control the compression speed and the +-compression ratio. High compression ratio will take more time, level 0 +-stands for no compression, level 1 stands for the best compression +-speed, and level 9 stands for the best compression ratio. Users can +-select a level number between 0 and 9. ++compression ratio. High compression ratio will take more time, ++level 1 stands for the best compression speed, and higher level means higher ++compression ration. For Zlib, users can select a level number between 0 and 9, ++where level 0 stands for no compression. For Zstd, users can select a ++level number between 1 and 22. + + + When to use the multiple thread compression in live migration +@@ -116,16 +117,19 @@ to support the multiple thread compression migration: + 2. Activate compression on the source: + {qemu} migrate_set_capability compress on + +-3. Set the compression thread count on source: ++3. Set the compression method: ++ {qemu} migrate_set_parameter compress_method zstd ++ ++4. Set the compression thread count on source: + {qemu} migrate_set_parameter compress_threads 12 + +-4. Set the compression level on the source: ++5. Set the compression level on the source: + {qemu} migrate_set_parameter compress_level 1 + +-5. Set the decompression thread count on destination: ++6. Set the decompression thread count on destination: + {qemu} migrate_set_parameter decompress_threads 3 + +-6. Start outgoing migration: ++7. Start outgoing migration: + {qemu} migrate -d tcp:destination.host:4444 + {qemu} info migrate + Capabilities: ... compress: on +@@ -136,6 +140,7 @@ The following are the default settings: + compress_threads: 8 + decompress_threads: 2 + compress_level: 1 (which means best speed) ++ compress_method: zlib + + So, only the first two steps are required to use the multiple + thread compression in migration. You can do more if the default +@@ -143,7 +148,7 @@ settings are not appropriate. + + TODO + ==== +-Some faster (de)compression method such as LZ4 and Quicklz can help +-to reduce the CPU consumption when doing (de)compression. If using +-these faster (de)compression method, less (de)compression threads ++Comparing to Zlib, Some faster (de)compression method such as LZ4 ++and Quicklz can help to reduce the CPU consumption when doing (de)compression. ++If using these faster (de)compression method, less (de)compression threads + are needed when doing the migration. +-- +2.27.0 + -- Gitee From 56b9a8d178e10ee5738c7d0732cff8edb5363c98 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Wed, 9 Feb 2022 11:28:15 +0800 Subject: [PATCH 13/22] spec: Update patch and changelog with !221 migration: backport migration patches from qemu-4.1.0 Merge pull request !221 from Chuan/qemu-6.2.0 !221 vhost: cancel migration when vhost-user restarted during migraiton migration: Add multi-thread compress method migration: Refactoring multi-thread compress migration migration: Add multi-thread compress ops migration: Add zstd support in multi-thread compression migration: Add compress_level sanity check doc: Update multi-thread compression doc Signed-off-by: Chen Qun --- qemu.spec | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/qemu.spec b/qemu.spec index 91d7f5da..f4d94761 100644 --- a/qemu.spec +++ b/qemu.spec @@ -911,9 +911,25 @@ Patch0001: cpu-parse-feature-to-avoid-failure.patch Patch0001: cpu-parse-feature-to-avoid-failure.patch %changelog +* Wed Feb 09 2022 Chen Qun +- vhost: cancel migration when vhost-user restarted during migraiton +- migration: Add multi-thread compress method +- migration: Refactoring multi-thread compress migration +- migration: Add multi-thread compress ops +- migration: Add zstd support in multi-thread compression +- migration: Add compress_level sanity check +- doc: Update multi-thread compression doc + * Wed Feb 09 2022 Chen Qun Patch0001: cpu-parse-feature-to-avoid-failure.patch * Thu Jan 27 2022 Xiangdong Liu Patch0001: cpu-parse-feature-to-avoid-failure.patch - Package init Patch0001: cpu-parse-feature-to-avoid-failure.patch +Patch0008: doc-Update-multi-thread-compression-doc.patch +Patch0007: migration-Add-compress_level-sanity-check.patch +Patch0006: migration-Add-zstd-support-in-multi-thread-compressi.patch +Patch0005: migration-Add-multi-thread-compress-ops.patch +Patch0004: migration-Refactoring-multi-thread-compress-migratio.patch +Patch0003: migration-Add-multi-thread-compress-method.patch +Patch0002: vhost-cancel-migration-when-vhost-user-restarted-dur.patch -- Gitee From e5e76204bc7b09002c04521f13e0ba4bf3b126f8 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 21 Jan 2021 15:46:45 +0800 Subject: [PATCH 14/22] qapi/block-core: Add retry option for error action Add a new error action 'retry' to support retry on errors. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang Signed-off-by: Alex Chen --- ...re-Add-retry-option-for-error-action.patch | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 qapi-block-core-Add-retry-option-for-error-action.patch diff --git a/qapi-block-core-Add-retry-option-for-error-action.patch b/qapi-block-core-Add-retry-option-for-error-action.patch new file mode 100644 index 00000000..521b2acb --- /dev/null +++ b/qapi-block-core-Add-retry-option-for-error-action.patch @@ -0,0 +1,53 @@ +From 4c3d47e04886e072acc0e4fefdc49e9d1f6b4ad1 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:45 +0800 +Subject: [PATCH] qapi/block-core: Add retry option for error action + +Add a new error action 'retry' to support retry on errors. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + blockdev.c | 2 ++ + qapi/block-core.json | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/blockdev.c b/blockdev.c +index b35072644e..6f1981635b 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -333,6 +333,8 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp) + return BLOCKDEV_ON_ERROR_STOP; + } else if (!strcmp(buf, "report")) { + return BLOCKDEV_ON_ERROR_REPORT; ++ } else if (!strcmp(buf, "retry")) { ++ return BLOCKDEV_ON_ERROR_RETRY; + } else { + error_setg(errp, "'%s' invalid %s error action", + buf, is_read ? "read" : "write"); +diff --git a/qapi/block-core.json b/qapi/block-core.json +index 1d3dd9cb48..804beabfb0 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -1146,7 +1146,7 @@ + # Since: 1.3 + ## + { 'enum': 'BlockdevOnError', +- 'data': ['report', 'ignore', 'enospc', 'stop', 'auto'] } ++ 'data': ['report', 'ignore', 'enospc', 'stop', 'auto', 'retry'] } + + ## + # @MirrorSyncMode: +@@ -4952,7 +4952,7 @@ + # Since: 2.1 + ## + { 'enum': 'BlockErrorAction', +- 'data': [ 'ignore', 'report', 'stop' ] } ++ 'data': [ 'ignore', 'report', 'stop', 'retry' ] } + + + ## +-- +2.27.0 + -- Gitee From 50bde19049811ddd99f9eac2c10dbfd6b6e2ba77 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 21 Jan 2021 15:46:46 +0800 Subject: [PATCH 15/22] block-backend: Introduce retry timer Add a timer to regularly trigger retry on errors. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang Signed-off-by: Alex Chen --- block-backend-Introduce-retry-timer.patch | 70 +++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 block-backend-Introduce-retry-timer.patch diff --git a/block-backend-Introduce-retry-timer.patch b/block-backend-Introduce-retry-timer.patch new file mode 100644 index 00000000..adf955b9 --- /dev/null +++ b/block-backend-Introduce-retry-timer.patch @@ -0,0 +1,70 @@ +From 4dc180e87fb641f64fce7be3a0807488d0cc0a51 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:46 +0800 +Subject: [PATCH] block-backend: Introduce retry timer + +Add a timer to regularly trigger retry on errors. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 12ef80ea17..257cd775c0 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -35,6 +35,9 @@ + + static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); + ++/* block backend default retry interval */ ++#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 ++ + typedef struct BlockBackendAioNotifier { + void (*attached_aio_context)(AioContext *new_context, void *opaque); + void (*detach_aio_context)(void *opaque); +@@ -95,6 +98,15 @@ struct BlockBackend { + * Accessed with atomic ops. + */ + unsigned int in_flight; ++ ++ /* Timer for retry on errors. */ ++ QEMUTimer *retry_timer; ++ /* Interval in ms to trigger next retry. */ ++ int64_t retry_interval; ++ /* Start time of the first error. Used to check timeout. */ ++ int64_t retry_start_time; ++ /* Retry timeout. 0 represents infinite retry. */ ++ int64_t retry_timeout; + }; + + typedef struct BlockBackendAIOCB { +@@ -353,6 +365,11 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) + blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT; + blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; + ++ blk->retry_timer = NULL; ++ blk->retry_interval = BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL; ++ blk->retry_start_time = 0; ++ blk->retry_timeout = 0; ++ + block_acct_init(&blk->stats); + + qemu_co_queue_init(&blk->queued_requests); +@@ -471,6 +488,10 @@ static void blk_delete(BlockBackend *blk) + QTAILQ_REMOVE(&block_backends, blk, link); + drive_info_del(blk->legacy_dinfo); + block_acct_cleanup(&blk->stats); ++ if (blk->retry_timer) { ++ timer_del(blk->retry_timer); ++ timer_free(blk->retry_timer); ++ } + g_free(blk); + } + +-- +2.27.0 + -- Gitee From 53c1952ade7e923e677f323fd90551c4c0f51e35 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 21 Jan 2021 15:46:47 +0800 Subject: [PATCH 16/22] block-backend: Add device specific retry callback Add retry_request_cb in BlockDevOps to do device specific retry action. Backend's timer would be registered only when the backend is set 'retry' on errors and the device supports retry action. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang Signed-off-by: Alex Chen --- ...d-Add-device-specific-retry-callback.patch | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 block-backend-Add-device-specific-retry-callback.patch diff --git a/block-backend-Add-device-specific-retry-callback.patch b/block-backend-Add-device-specific-retry-callback.patch new file mode 100644 index 00000000..51981d9d --- /dev/null +++ b/block-backend-Add-device-specific-retry-callback.patch @@ -0,0 +1,54 @@ +From dfda8c57de71f2f10b57cf21b1e36f18d4ed37a3 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:47 +0800 +Subject: [PATCH] block-backend: Add device specific retry callback + +Add retry_request_cb in BlockDevOps to do device specific retry action. +Backend's timer would be registered only when the backend is set 'retry' +on errors and the device supports retry action. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 8 ++++++++ + include/sysemu/block-backend.h | 4 ++++ + 2 files changed, 12 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 257cd775c0..24003adf0b 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1018,6 +1018,14 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, + blk->dev_ops = ops; + blk->dev_opaque = opaque; + ++ if ((blk->on_read_error == BLOCKDEV_ON_ERROR_RETRY || ++ blk->on_write_error == BLOCKDEV_ON_ERROR_RETRY) && ++ ops->retry_request_cb) { ++ blk->retry_timer = aio_timer_new(blk->ctx, QEMU_CLOCK_REALTIME, ++ SCALE_MS, ops->retry_request_cb, ++ opaque); ++ } ++ + /* Are we currently quiesced? Should we enforce this right now? */ + if (blk->quiesce_counter && ops->drained_begin) { + ops->drained_begin(opaque); +diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h +index e5e1524f06..a7a13d47de 100644 +--- a/include/sysemu/block-backend.h ++++ b/include/sysemu/block-backend.h +@@ -70,6 +70,10 @@ typedef struct BlockDevOps { + * Is the device still busy? + */ + bool (*drained_poll)(void *opaque); ++ /* ++ * Runs when retrying failed requests. ++ */ ++ void (*retry_request_cb)(void *opaque); + } BlockDevOps; + + /* This struct is embedded in (the private) BlockBackend struct and contains +-- +2.27.0 + -- Gitee From 4ef6c1024f9e740d56b465a62058c376559b9dc9 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 21 Jan 2021 15:46:48 +0800 Subject: [PATCH 17/22] block-backend: Enable retry action on errors Enable retry action when backend's retry timer is available. It would trigger the timer to do device specific retry action. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang Signed-off-by: Alex Chen --- ...ackend-Enable-retry-action-on-errors.patch | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 block-backend-Enable-retry-action-on-errors.patch diff --git a/block-backend-Enable-retry-action-on-errors.patch b/block-backend-Enable-retry-action-on-errors.patch new file mode 100644 index 00000000..a1f274dc --- /dev/null +++ b/block-backend-Enable-retry-action-on-errors.patch @@ -0,0 +1,43 @@ +From 2e1c75e5a0339d2bf417e5a4437d8e627a303286 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:48 +0800 +Subject: [PATCH] block-backend: Enable retry action on errors + +Enable retry action when backend's retry timer is available. It would +trigger the timer to do device specific retry action. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 24003adf0b..5a016d32fa 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1793,6 +1793,9 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, + return BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_IGNORE: + return BLOCK_ERROR_ACTION_IGNORE; ++ case BLOCKDEV_ON_ERROR_RETRY: ++ return (blk->retry_timer) ? ++ BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_AUTO: + default: + abort(); +@@ -1840,6 +1843,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action, + qemu_system_vmstop_request_prepare(); + send_qmp_error_event(blk, action, is_read, error); + qemu_system_vmstop_request(RUN_STATE_IO_ERROR); ++ } else if (action == BLOCK_ERROR_ACTION_RETRY) { ++ timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ++ blk->retry_interval); ++ send_qmp_error_event(blk, action, is_read, error); + } else { + send_qmp_error_event(blk, action, is_read, error); + } +-- +2.27.0 + -- Gitee From 717f74ff05aefd6ee93b8c83782e0b18a2ef5141 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 21 Jan 2021 15:46:49 +0800 Subject: [PATCH 18/22] block-backend: Add timeout support for retry Retry should only be triggered when timeout is not reached, so let's check timeout before retry. Device should also reset retry_start_time after successful retry. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang Signed-off-by: Alex Chen --- ...ackend-Add-timeout-support-for-retry.patch | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 block-backend-Add-timeout-support-for-retry.patch diff --git a/block-backend-Add-timeout-support-for-retry.patch b/block-backend-Add-timeout-support-for-retry.patch new file mode 100644 index 00000000..b1fb6c91 --- /dev/null +++ b/block-backend-Add-timeout-support-for-retry.patch @@ -0,0 +1,75 @@ +From 953590f4854d75e6051237f668c9fb393235f471 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:49 +0800 +Subject: [PATCH] block-backend: Add timeout support for retry + +Retry should only be triggered when timeout is not reached, so let's check +timeout before retry. Device should also reset retry_start_time after +successful retry. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 25 ++++++++++++++++++++++++- + include/sysemu/block-backend.h | 1 + + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 5a016d32fa..37e21c473e 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1766,6 +1766,29 @@ void blk_drain_all(void) + bdrv_drain_all_end(); + } + ++static bool blk_error_retry_timeout(BlockBackend *blk) ++{ ++ /* No timeout set, infinite retries. */ ++ if (!blk->retry_timeout) { ++ return false; ++ } ++ ++ /* The first time an error occurs. */ ++ if (!blk->retry_start_time) { ++ blk->retry_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); ++ return false; ++ } ++ ++ return qemu_clock_get_ms(QEMU_CLOCK_REALTIME) > (blk->retry_start_time + ++ blk->retry_timeout); ++} ++ ++void blk_error_retry_reset_timeout(BlockBackend *blk) ++{ ++ if (blk->retry_timer && blk->retry_start_time) ++ blk->retry_start_time = 0; ++} ++ + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error) + { +@@ -1794,7 +1817,7 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, + case BLOCKDEV_ON_ERROR_IGNORE: + return BLOCK_ERROR_ACTION_IGNORE; + case BLOCKDEV_ON_ERROR_RETRY: +- return (blk->retry_timer) ? ++ return (blk->retry_timer && !blk_error_retry_timeout(blk)) ? + BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; + case BLOCKDEV_ON_ERROR_AUTO: + default: +diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h +index a7a13d47de..56a403883d 100644 +--- a/include/sysemu/block-backend.h ++++ b/include/sysemu/block-backend.h +@@ -198,6 +198,7 @@ void blk_inc_in_flight(BlockBackend *blk); + void blk_dec_in_flight(BlockBackend *blk); + void blk_drain(BlockBackend *blk); + void blk_drain_all(void); ++void blk_error_retry_reset_timeout(BlockBackend *blk); + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error); + BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read); +-- +2.27.0 + -- Gitee From c453c3f8086e1c5a87ea8303f1a537497020aeb7 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 21 Jan 2021 15:46:50 +0800 Subject: [PATCH 19/22] block: Add error retry param setting Add "retry_interval" and "retry_timeout" parameter for drive and device option. These parameter are valid only when werror/rerror=retry. eg. --drive file=image,rerror=retry,retry_interval=1000,retry_timeout=5000 Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang Signed-off-by: Alex Chen --- block-Add-error-retry-param-setting.patch | 227 ++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 block-Add-error-retry-param-setting.patch diff --git a/block-Add-error-retry-param-setting.patch b/block-Add-error-retry-param-setting.patch new file mode 100644 index 00000000..7dcdebee --- /dev/null +++ b/block-Add-error-retry-param-setting.patch @@ -0,0 +1,227 @@ +From a58fda7b158441c645e143bf658d12914ffbc7b8 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:50 +0800 +Subject: [PATCH] block: Add error retry param setting + +Add "retry_interval" and "retry_timeout" parameter for drive and device +option. These parameter are valid only when werror/rerror=retry. + +eg. --drive file=image,rerror=retry,retry_interval=1000,retry_timeout=5000 + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 13 +++++++-- + blockdev.c | 50 ++++++++++++++++++++++++++++++++++ + hw/block/block.c | 10 +++++++ + include/hw/block/block.h | 7 ++++- + include/sysemu/block-backend.h | 5 ++++ + 5 files changed, 81 insertions(+), 4 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 37e21c473e..d3d90a95a5 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -35,9 +35,6 @@ + + static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); + +-/* block backend default retry interval */ +-#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 +- + typedef struct BlockBackendAioNotifier { + void (*attached_aio_context)(AioContext *new_context, void *opaque); + void (*detach_aio_context)(void *opaque); +@@ -1766,6 +1763,16 @@ void blk_drain_all(void) + bdrv_drain_all_end(); + } + ++void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval) ++{ ++ blk->retry_interval = interval; ++} ++ ++void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout) ++{ ++ blk->retry_timeout = timeout; ++} ++ + static bool blk_error_retry_timeout(BlockBackend *blk) + { + /* No timeout set, infinite retries. */ +diff --git a/blockdev.c b/blockdev.c +index 6f1981635b..10a73fa423 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -480,6 +480,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + const char *buf; + int bdrv_flags = 0; + int on_read_error, on_write_error; ++ int64_t retry_interval, retry_timeout; + bool account_invalid, account_failed; + bool writethrough, read_only; + BlockBackend *blk; +@@ -572,6 +573,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + } + } + ++ retry_interval = qemu_opt_get_number(opts, "retry_interval", ++ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); ++ retry_timeout = qemu_opt_get_number(opts, "retry_timeout", 0); ++ + if (snapshot) { + bdrv_flags |= BDRV_O_SNAPSHOT; + } +@@ -635,6 +640,11 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + + blk_set_enable_write_cache(blk, !writethrough); + blk_set_on_error(blk, on_read_error, on_write_error); ++ if (on_read_error == BLOCKDEV_ON_ERROR_RETRY || ++ on_write_error == BLOCKDEV_ON_ERROR_RETRY) { ++ blk_set_on_error_retry_interval(blk, retry_interval); ++ blk_set_on_error_retry_timeout(blk, retry_timeout); ++ } + + if (!monitor_add_blk(blk, id, errp)) { + blk_unref(blk); +@@ -761,6 +771,14 @@ QemuOptsList qemu_legacy_drive_opts = { + .name = "werror", + .type = QEMU_OPT_STRING, + .help = "write error action", ++ },{ ++ .name = "retry_interval", ++ .type = QEMU_OPT_NUMBER, ++ .help = "interval for retry action in millisecond", ++ },{ ++ .name = "retry_timeout", ++ .type = QEMU_OPT_NUMBER, ++ .help = "timeout for retry action in millisecond", + },{ + .name = "copy-on-read", + .type = QEMU_OPT_BOOL, +@@ -783,6 +801,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, + BlockInterfaceType type; + int max_devs, bus_id, unit_id, index; + const char *werror, *rerror; ++ int64_t retry_interval, retry_timeout; + bool read_only = false; + bool copy_on_read; + const char *filename; +@@ -990,6 +1009,29 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, + qdict_put_str(bs_opts, "rerror", rerror); + } + ++ if (qemu_opt_find(legacy_opts, "retry_interval")) { ++ if ((werror == NULL || strcmp(werror, "retry")) && ++ (rerror == NULL || strcmp(rerror, "retry"))) { ++ error_setg(errp, "retry_interval is only supported " ++ "by werror/rerror=retry"); ++ goto fail; ++ } ++ retry_interval = qemu_opt_get_number(legacy_opts, "retry_interval", ++ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); ++ qdict_put_int(bs_opts, "retry_interval", retry_interval); ++ } ++ ++ if (qemu_opt_find(legacy_opts, "retry_timeout")) { ++ if ((werror == NULL || strcmp(werror, "retry")) && ++ (rerror == NULL || strcmp(rerror, "retry"))) { ++ error_setg(errp, "retry_timeout is only supported " ++ "by werror/rerror=retry"); ++ goto fail; ++ } ++ retry_timeout = qemu_opt_get_number(legacy_opts, "retry_timeout", 0); ++ qdict_put_int(bs_opts, "retry_timeout", retry_timeout); ++ } ++ + /* Actual block device init: Functionality shared with blockdev-add */ + blk = blockdev_init(filename, bs_opts, errp); + bs_opts = NULL; +@@ -3806,6 +3848,14 @@ QemuOptsList qemu_common_drive_opts = { + .name = "werror", + .type = QEMU_OPT_STRING, + .help = "write error action", ++ },{ ++ .name = "retry_interval", ++ .type = QEMU_OPT_NUMBER, ++ .help = "interval for retry action in millisecond", ++ },{ ++ .name = "retry_timeout", ++ .type = QEMU_OPT_NUMBER, ++ .help = "timeout for retry action in millisecond", + },{ + .name = BDRV_OPT_READ_ONLY, + .type = QEMU_OPT_BOOL, +diff --git a/hw/block/block.c b/hw/block/block.c +index d47ebf005a..26c0767552 100644 +--- a/hw/block/block.c ++++ b/hw/block/block.c +@@ -206,6 +206,16 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, + blk_set_enable_write_cache(blk, wce); + blk_set_on_error(blk, rerror, werror); + ++ if (rerror == BLOCKDEV_ON_ERROR_RETRY || ++ werror == BLOCKDEV_ON_ERROR_RETRY) { ++ if (conf->retry_interval >= 0) { ++ blk_set_on_error_retry_interval(blk, conf->retry_interval); ++ } ++ if (conf->retry_timeout >= 0) { ++ blk_set_on_error_retry_timeout(blk, conf->retry_timeout); ++ } ++ } ++ + return true; + } + +diff --git a/include/hw/block/block.h b/include/hw/block/block.h +index 5902c0440a..24fb7d77af 100644 +--- a/include/hw/block/block.h ++++ b/include/hw/block/block.h +@@ -33,6 +33,8 @@ typedef struct BlockConf { + bool share_rw; + BlockdevOnError rerror; + BlockdevOnError werror; ++ int64_t retry_interval; ++ int64_t retry_timeout; + } BlockConf; + + static inline unsigned int get_physical_block_exp(BlockConf *conf) +@@ -79,7 +81,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) + DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \ + BLOCKDEV_ON_ERROR_AUTO), \ + DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ +- BLOCKDEV_ON_ERROR_AUTO) ++ BLOCKDEV_ON_ERROR_AUTO), \ ++ DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ ++ -1), \ ++ DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) + + /* Backend access helpers */ + +diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h +index 56a403883d..887c19ff5d 100644 +--- a/include/sysemu/block-backend.h ++++ b/include/sysemu/block-backend.h +@@ -25,6 +25,9 @@ + */ + #include "block/block.h" + ++/* block backend default retry interval */ ++#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 ++ + /* Callbacks for block device models */ + typedef struct BlockDevOps { + /* +@@ -198,6 +201,8 @@ void blk_inc_in_flight(BlockBackend *blk); + void blk_dec_in_flight(BlockBackend *blk); + void blk_drain(BlockBackend *blk); + void blk_drain_all(void); ++void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval); ++void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout); + void blk_error_retry_reset_timeout(BlockBackend *blk); + void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, + BlockdevOnError on_write_error); +-- +2.27.0 + -- Gitee From c701548b7c3d42ba274d5e186b8c2e6bee144c73 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 21 Jan 2021 15:46:53 +0800 Subject: [PATCH 20/22] virtio_blk: Add support for retry on errors Insert failed requests into device's list for later retry and handle queued requests to implement retry_request_cb. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang Signed-off-by: Alex Chen --- ..._blk-Add-support-for-retry-on-errors.patch | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 virtio_blk-Add-support-for-retry-on-errors.patch diff --git a/virtio_blk-Add-support-for-retry-on-errors.patch b/virtio_blk-Add-support-for-retry-on-errors.patch new file mode 100644 index 00000000..054e5006 --- /dev/null +++ b/virtio_blk-Add-support-for-retry-on-errors.patch @@ -0,0 +1,90 @@ +From a81122e37595fe1cc9eaa2adbbfccbfdf8f988b8 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:53 +0800 +Subject: [PATCH] virtio_blk: Add support for retry on errors + +Insert failed requests into device's list for later retry and handle +queued requests to implement retry_request_cb. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + hw/block/virtio-blk.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index f139cd7cc9..c8d94a3dfb 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -108,6 +108,10 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, + block_acct_failed(blk_get_stats(s->blk), &req->acct); + } + virtio_blk_free_request(req); ++ } else if (action == BLOCK_ERROR_ACTION_RETRY) { ++ req->mr_next = NULL; ++ req->next = s->rq; ++ s->rq = req; + } + + blk_error_action(s->blk, action, is_read, error); +@@ -149,6 +153,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + block_acct_done(blk_get_stats(s->blk), &req->acct); + virtio_blk_free_request(req); +@@ -168,6 +173,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + block_acct_done(blk_get_stats(s->blk), &req->acct); + virtio_blk_free_request(req); +@@ -190,6 +196,7 @@ static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) + } + } + ++ blk_error_retry_reset_timeout(s->blk); + virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + if (is_write_zeroes) { + block_acct_done(blk_get_stats(s->blk), &req->acct); +@@ -828,12 +835,12 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) + + void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh) + { +- VirtIOBlockReq *req = s->rq; ++ VirtIOBlockReq *req; + MultiReqBuffer mrb = {}; + +- s->rq = NULL; +- + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); ++ req = s->rq; ++ s->rq = NULL; + while (req) { + VirtIOBlockReq *next = req->next; + if (virtio_blk_handle_request(req, &mrb)) { +@@ -1138,8 +1145,16 @@ static void virtio_blk_resize(void *opaque) + aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev); + } + ++static void virtio_blk_retry_request(void *opaque) ++{ ++ VirtIOBlock *s = VIRTIO_BLK(opaque); ++ ++ virtio_blk_process_queued_requests(s, false); ++} ++ + static const BlockDevOps virtio_block_ops = { + .resize_cb = virtio_blk_resize, ++ .retry_request_cb = virtio_blk_retry_request, + }; + + static void virtio_blk_device_realize(DeviceState *dev, Error **errp) +-- +2.27.0 + -- Gitee From 8842fb7c3f67fdb1b89b622473308faec40574f9 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Wed, 9 Feb 2022 11:28:19 +0800 Subject: [PATCH 21/22] spec: Update patch and changelog with !222 block: Add retry for werror=/rerror= mechanism Merge pull request !222 from alexchen/qemu-6.2.0 !222 qapi/block-core: Add retry option for error action block-backend: Introduce retry timer block-backend: Add device specific retry callback block-backend: Enable retry action on errors block-backend: Add timeout support for retry block: Add error retry param setting virtio_blk: Add support for retry on errors Signed-off-by: Chen Qun --- qemu.spec | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/qemu.spec b/qemu.spec index f4d94761..116e6f09 100644 --- a/qemu.spec +++ b/qemu.spec @@ -911,6 +911,15 @@ Patch0001: cpu-parse-feature-to-avoid-failure.patch Patch0001: cpu-parse-feature-to-avoid-failure.patch %changelog +* Wed Feb 09 2022 Chen Qun +- qapi/block-core: Add retry option for error action +- block-backend: Introduce retry timer +- block-backend: Add device specific retry callback +- block-backend: Enable retry action on errors +- block-backend: Add timeout support for retry +- block: Add error retry param setting +- virtio_blk: Add support for retry on errors + * Wed Feb 09 2022 Chen Qun - vhost: cancel migration when vhost-user restarted during migraiton - migration: Add multi-thread compress method @@ -933,3 +942,10 @@ Patch0005: migration-Add-multi-thread-compress-ops.patch Patch0004: migration-Refactoring-multi-thread-compress-migratio.patch Patch0003: migration-Add-multi-thread-compress-method.patch Patch0002: vhost-cancel-migration-when-vhost-user-restarted-dur.patch +Patch0009: virtio_blk-Add-support-for-retry-on-errors.patch +Patch0008: block-Add-error-retry-param-setting.patch +Patch0007: block-backend-Add-timeout-support-for-retry.patch +Patch0006: block-backend-Enable-retry-action-on-errors.patch +Patch0005: block-backend-Add-device-specific-retry-callback.patch +Patch0004: block-backend-Introduce-retry-timer.patch +Patch0003: qapi-block-core-Add-retry-option-for-error-action.patch -- Gitee From d310d1630625a7d8e17843d66825d26d190cd60f Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Wed, 9 Feb 2022 11:28:27 +0800 Subject: [PATCH 22/22] spec: Update release version with !225 !221 !222 increase release verison by one Signed-off-by: Chen Qun --- qemu.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu.spec b/qemu.spec index 116e6f09..9211d522 100644 --- a/qemu.spec +++ b/qemu.spec @@ -5,7 +5,7 @@ Patch0004: add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch Patch0001: cpu-parse-feature-to-avoid-failure.patch Version: 6.2.0 Patch0001: cpu-parse-feature-to-avoid-failure.patch -Release: 1 +Release: 2 Patch0001: cpu-parse-feature-to-avoid-failure.patch Epoch: 2 Patch0001: cpu-parse-feature-to-avoid-failure.patch -- Gitee