diff --git a/kvm-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch b/kvm-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch new file mode 100644 index 0000000..fbab82d --- /dev/null +++ b/kvm-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch @@ -0,0 +1,56 @@ +From dfa2811e88afaf996345552330e97f0513c1803c Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 4 May 2023 13:57:34 +0200 +Subject: [PATCH 53/56] block: Don't call no_coroutine_fns in + qmp_block_resize() + +RH-Author: Kevin Wolf +RH-MergeRequest: 164: block: Fix hangs in qmp_block_resize() +RH-Bugzilla: 2185688 +RH-Acked-by: Emanuele Giuseppe Esposito +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [2/4] 7ac7e34821cfc8bd5f0daadd7a1c4a5596bc60a6 (kmwolf/centos-qemu-kvm) + +This QMP handler runs in a coroutine, so it must use the corresponding +no_co_wrappers instead. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2185688 +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-Id: <20230504115750.54437-5-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 0c7d204f50c382c6baac8c94bd57af4a022b3888) +Signed-off-by: Kevin Wolf +--- + blockdev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/blockdev.c b/blockdev.c +index d7b5c18f0a..eb509cf964 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -2430,7 +2430,7 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name, + return; + } + +- blk = blk_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp); ++ blk = blk_co_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp); + if (!blk) { + return; + } +@@ -2445,7 +2445,7 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name, + + bdrv_co_lock(bs); + bdrv_drained_end(bs); +- blk_unref(blk); ++ blk_co_unref(blk); + bdrv_co_unlock(bs); + } + +-- +2.39.1 + diff --git a/kvm-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch b/kvm-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch new file mode 100644 index 0000000..0f0347b --- /dev/null +++ b/kvm-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch @@ -0,0 +1,386 @@ +From 7baea25be90e184175dd5a919ee5878cbd4970c2 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 4 May 2023 13:57:33 +0200 +Subject: [PATCH 52/56] block: bdrv/blk_co_unref() for calls in coroutine + context + +RH-Author: Kevin Wolf +RH-MergeRequest: 164: block: Fix hangs in qmp_block_resize() +RH-Bugzilla: 2185688 +RH-Acked-by: Emanuele Giuseppe Esposito +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/4] 8ebf8486b082c30ca1b39a6ede35e471eaaccfa3 (kmwolf/centos-qemu-kvm) + +These functions must not be called in coroutine context, because they +need write access to the graph. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-Id: <20230504115750.54437-4-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit b2ab5f545fa1eaaf2955dd617bee19a8b3279786) +Signed-off-by: Kevin Wolf +--- + block.c | 2 +- + block/crypto.c | 6 +++--- + block/parallels.c | 6 +++--- + block/qcow.c | 6 +++--- + block/qcow2.c | 14 +++++++------- + block/qed.c | 6 +++--- + block/vdi.c | 6 +++--- + block/vhdx.c | 6 +++--- + block/vmdk.c | 18 +++++++++--------- + block/vpc.c | 6 +++--- + include/block/block-global-state.h | 3 ++- + include/sysemu/block-backend-global-state.h | 5 ++++- + 12 files changed, 44 insertions(+), 40 deletions(-) + +diff --git a/block.c b/block.c +index d79a52ca74..a48112f945 100644 +--- a/block.c ++++ b/block.c +@@ -680,7 +680,7 @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv, + + ret = 0; + out: +- blk_unref(blk); ++ blk_co_unref(blk); + return ret; + } + +diff --git a/block/crypto.c b/block/crypto.c +index ca67289187..8fd3ad0054 100644 +--- a/block/crypto.c ++++ b/block/crypto.c +@@ -355,7 +355,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size, + ret = 0; + cleanup: + qcrypto_block_free(crypto); +- blk_unref(blk); ++ blk_co_unref(blk); + return ret; + } + +@@ -661,7 +661,7 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp) + + ret = 0; + fail: +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + return ret; + } + +@@ -730,7 +730,7 @@ fail: + bdrv_co_delete_file_noerr(bs); + } + +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + qapi_free_QCryptoBlockCreateOptions(create_opts); + qobject_unref(cryptoopts); + return ret; +diff --git a/block/parallels.c b/block/parallels.c +index 013684801a..b49c35929e 100644 +--- a/block/parallels.c ++++ b/block/parallels.c +@@ -613,8 +613,8 @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts, + + ret = 0; + out: +- blk_unref(blk); +- bdrv_unref(bs); ++ blk_co_unref(blk); ++ bdrv_co_unref(bs); + return ret; + + exit: +@@ -691,7 +691,7 @@ parallels_co_create_opts(BlockDriver *drv, const char *filename, + + done: + qobject_unref(qdict); +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + qapi_free_BlockdevCreateOptions(create_options); + return ret; + } +diff --git a/block/qcow.c b/block/qcow.c +index 490e4f819e..a0c701f578 100644 +--- a/block/qcow.c ++++ b/block/qcow.c +@@ -915,8 +915,8 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts, + g_free(tmp); + ret = 0; + exit: +- blk_unref(qcow_blk); +- bdrv_unref(bs); ++ blk_co_unref(qcow_blk); ++ bdrv_co_unref(bs); + qcrypto_block_free(crypto); + return ret; + } +@@ -1015,7 +1015,7 @@ qcow_co_create_opts(BlockDriver *drv, const char *filename, + fail: + g_free(backing_fmt); + qobject_unref(qdict); +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + qapi_free_BlockdevCreateOptions(create_options); + return ret; + } +diff --git a/block/qcow2.c b/block/qcow2.c +index 22084730f9..0b8beb8b47 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -3711,7 +3711,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) + goto out; + } + +- blk_unref(blk); ++ blk_co_unref(blk); + blk = NULL; + + /* +@@ -3791,7 +3791,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) + } + } + +- blk_unref(blk); ++ blk_co_unref(blk); + blk = NULL; + + /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning. +@@ -3816,9 +3816,9 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) + + ret = 0; + out: +- blk_unref(blk); +- bdrv_unref(bs); +- bdrv_unref(data_bs); ++ blk_co_unref(blk); ++ bdrv_co_unref(bs); ++ bdrv_co_unref(data_bs); + return ret; + } + +@@ -3949,8 +3949,8 @@ finish: + } + + qobject_unref(qdict); +- bdrv_unref(bs); +- bdrv_unref(data_bs); ++ bdrv_co_unref(bs); ++ bdrv_co_unref(data_bs); + qapi_free_BlockdevCreateOptions(create_options); + return ret; + } +diff --git a/block/qed.c b/block/qed.c +index 0705a7b4e2..aff2a2076e 100644 +--- a/block/qed.c ++++ b/block/qed.c +@@ -748,8 +748,8 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts, + ret = 0; /* success */ + out: + g_free(l1_table); +- blk_unref(blk); +- bdrv_unref(bs); ++ blk_co_unref(blk); ++ bdrv_co_unref(bs); + return ret; + } + +@@ -819,7 +819,7 @@ bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename, + + fail: + qobject_unref(qdict); +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + qapi_free_BlockdevCreateOptions(create_options); + return ret; + } +diff --git a/block/vdi.c b/block/vdi.c +index f2434d6153..08331d2dd7 100644 +--- a/block/vdi.c ++++ b/block/vdi.c +@@ -886,8 +886,8 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, + + ret = 0; + exit: +- blk_unref(blk); +- bdrv_unref(bs_file); ++ blk_co_unref(blk); ++ bdrv_co_unref(bs_file); + g_free(bmap); + return ret; + } +@@ -975,7 +975,7 @@ vdi_co_create_opts(BlockDriver *drv, const char *filename, + done: + qobject_unref(qdict); + qapi_free_BlockdevCreateOptions(create_options); +- bdrv_unref(bs_file); ++ bdrv_co_unref(bs_file); + return ret; + } + +diff --git a/block/vhdx.c b/block/vhdx.c +index 81420722a1..00777da91a 100644 +--- a/block/vhdx.c ++++ b/block/vhdx.c +@@ -2053,8 +2053,8 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts, + + ret = 0; + delete_and_exit: +- blk_unref(blk); +- bdrv_unref(bs); ++ blk_co_unref(blk); ++ bdrv_co_unref(bs); + g_free(creator); + return ret; + } +@@ -2144,7 +2144,7 @@ vhdx_co_create_opts(BlockDriver *drv, const char *filename, + + fail: + qobject_unref(qdict); +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + qapi_free_BlockdevCreateOptions(create_options); + return ret; + } +diff --git a/block/vmdk.c b/block/vmdk.c +index f5f49018fe..01ca13c82b 100644 +--- a/block/vmdk.c ++++ b/block/vmdk.c +@@ -2306,7 +2306,7 @@ exit: + if (pbb) { + *pbb = blk; + } else { +- blk_unref(blk); ++ blk_co_unref(blk); + blk = NULL; + } + } +@@ -2516,12 +2516,12 @@ vmdk_co_do_create(int64_t size, + if (strcmp(blk_bs(backing)->drv->format_name, "vmdk")) { + error_setg(errp, "Invalid backing file format: %s. Must be vmdk", + blk_bs(backing)->drv->format_name); +- blk_unref(backing); ++ blk_co_unref(backing); + ret = -EINVAL; + goto exit; + } + ret = vmdk_read_cid(blk_bs(backing), 0, &parent_cid); +- blk_unref(backing); ++ blk_co_unref(backing); + if (ret) { + error_setg(errp, "Failed to read parent CID"); + goto exit; +@@ -2542,14 +2542,14 @@ vmdk_co_do_create(int64_t size, + blk_bs(extent_blk)->filename); + created_size += cur_size; + extent_idx++; +- blk_unref(extent_blk); ++ blk_co_unref(extent_blk); + } + + /* Check whether we got excess extents */ + extent_blk = extent_fn(-1, extent_idx, flat, split, compress, zeroed_grain, + opaque, NULL); + if (extent_blk) { +- blk_unref(extent_blk); ++ blk_co_unref(extent_blk); + error_setg(errp, "List of extents contains unused extents"); + ret = -EINVAL; + goto exit; +@@ -2590,7 +2590,7 @@ vmdk_co_do_create(int64_t size, + ret = 0; + exit: + if (blk) { +- blk_unref(blk); ++ blk_co_unref(blk); + } + g_free(desc); + g_free(parent_desc_line); +@@ -2641,7 +2641,7 @@ vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split, + errp)) { + goto exit; + } +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + exit: + g_free(ext_filename); + return blk; +@@ -2797,12 +2797,12 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx, + return NULL; + } + blk_set_allow_write_beyond_eof(blk, true); +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + + if (size != -1) { + ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp); + if (ret) { +- blk_unref(blk); ++ blk_co_unref(blk); + blk = NULL; + } + } +diff --git a/block/vpc.c b/block/vpc.c +index b89b0ff8e2..07ddda5b99 100644 +--- a/block/vpc.c ++++ b/block/vpc.c +@@ -1082,8 +1082,8 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts, + } + + out: +- blk_unref(blk); +- bdrv_unref(bs); ++ blk_co_unref(blk); ++ bdrv_co_unref(bs); + return ret; + } + +@@ -1162,7 +1162,7 @@ vpc_co_create_opts(BlockDriver *drv, const char *filename, + + fail: + qobject_unref(qdict); +- bdrv_unref(bs); ++ bdrv_co_unref(bs); + qapi_free_BlockdevCreateOptions(create_options); + return ret; + } +diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h +index 399200a9a3..cd4ea554bf 100644 +--- a/include/block/block-global-state.h ++++ b/include/block/block-global-state.h +@@ -214,7 +214,8 @@ void bdrv_img_create(const char *filename, const char *fmt, + bool quiet, Error **errp); + + void bdrv_ref(BlockDriverState *bs); +-void bdrv_unref(BlockDriverState *bs); ++void no_coroutine_fn bdrv_unref(BlockDriverState *bs); ++void coroutine_fn no_co_wrapper bdrv_co_unref(BlockDriverState *bs); + void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child); + BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, + BlockDriverState *child_bs, +diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h +index 2b6d27db7c..fa83f9389c 100644 +--- a/include/sysemu/block-backend-global-state.h ++++ b/include/sysemu/block-backend-global-state.h +@@ -42,7 +42,10 @@ blk_co_new_open(const char *filename, const char *reference, QDict *options, + + int blk_get_refcnt(BlockBackend *blk); + void blk_ref(BlockBackend *blk); +-void blk_unref(BlockBackend *blk); ++ ++void no_coroutine_fn blk_unref(BlockBackend *blk); ++void coroutine_fn no_co_wrapper blk_co_unref(BlockBackend *blk); ++ + void blk_remove_all_bs(void); + BlockBackend *blk_by_name(const char *name); + BlockBackend *blk_next(BlockBackend *blk); +-- +2.39.1 + diff --git a/kvm-iotests-Test-resizing-image-attached-to-an-iothread.patch b/kvm-iotests-Test-resizing-image-attached-to-an-iothread.patch new file mode 100644 index 0000000..4e91505 --- /dev/null +++ b/kvm-iotests-Test-resizing-image-attached-to-an-iothread.patch @@ -0,0 +1,132 @@ +From 2c9e6892369ff99decd4030642b8dcf3875e9ebf Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 9 May 2023 15:41:33 +0200 +Subject: [PATCH 55/56] iotests: Test resizing image attached to an iothread + +RH-Author: Kevin Wolf +RH-MergeRequest: 164: block: Fix hangs in qmp_block_resize() +RH-Bugzilla: 2185688 +RH-Acked-by: Emanuele Giuseppe Esposito +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [4/4] 8d31752d1e6e8c6a422d68d9cb2251fbc34b7aef (kmwolf/centos-qemu-kvm) + +This tests that trying to resize an image with QMP block_resize doesn't +hang or otherwise fail when the image is attached to a device running in +an iothread. + +This is a regression test for the recent fix that changed +qmp_block_resize, which is a coroutine based QMP handler, to avoid +calling no_coroutine_fns directly. + +Signed-off-by: Kevin Wolf +Message-Id: <20230509134133.373408-1-kwolf@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit e113362e4cdfdcfe1d497e569527f70a0021333a) +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/tests/iothreads-resize | 71 +++++++++++++++++++ + tests/qemu-iotests/tests/iothreads-resize.out | 11 +++ + 2 files changed, 82 insertions(+) + create mode 100755 tests/qemu-iotests/tests/iothreads-resize + create mode 100644 tests/qemu-iotests/tests/iothreads-resize.out + +diff --git a/tests/qemu-iotests/tests/iothreads-resize b/tests/qemu-iotests/tests/iothreads-resize +new file mode 100755 +index 0000000000..36e4598c62 +--- /dev/null ++++ b/tests/qemu-iotests/tests/iothreads-resize +@@ -0,0 +1,71 @@ ++#!/usr/bin/env bash ++# group: rw auto quick ++# ++# Test resizing an image that is attached to a separate iothread ++# ++# Copyright (C) 2023 Red Hat, Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++# creator ++owner=kwolf@redhat.com ++ ++seq=`basename $0` ++echo "QA output created by $seq" ++ ++status=1 # failure is the default! ++ ++_cleanup() ++{ ++ _cleanup_test_img ++} ++trap "_cleanup; exit \$status" 0 1 2 3 15 ++ ++# get standard environment, filters and checks ++cd .. ++. ./common.rc ++. ./common.filter ++ ++# Resizing images is only supported by a few block drivers ++_supported_fmt raw qcow2 qed ++_supported_proto file ++_require_devices virtio-scsi-pci ++ ++size=64M ++_make_test_img $size ++ ++qmp() { ++cat < +Date: Thu, 11 May 2023 13:03:22 +0200 +Subject: [PATCH 54/56] iotests: Use alternative CPU type that is not + deprecated in RHEL + +RH-Author: Kevin Wolf +RH-MergeRequest: 164: block: Fix hangs in qmp_block_resize() +RH-Bugzilla: 2185688 +RH-Acked-by: Emanuele Giuseppe Esposito +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [3/4] 038d4718c0ee7a17ff5e6f4af8fc04d07e452f8d (kmwolf/centos-qemu-kvm) + +This is a downstream-only patch that is necessary because the default +CPU in RHEL is marked as deprecated. This makes test cases fail due to +the warning in the output: + +qemu-system-x86_64: warning: CPU model qemu64-x86_64-cpu is deprecated -- use at least 'Nehalem' / 'Opteron_G4', or 'host' / 'max' + +Fixes: 318178778db60b6475d1484509bee136317156d3 +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/testenv.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py +index 9a37ad9152..963514aab3 100644 +--- a/tests/qemu-iotests/testenv.py ++++ b/tests/qemu-iotests/testenv.py +@@ -244,6 +244,9 @@ def __init__(self, source_dir: str, build_dir: str, + if self.qemu_prog.endswith(f'qemu-system-{suffix}'): + self.qemu_options += f' -machine {machine}' + ++ if self.qemu_prog.endswith('qemu-system-x86_64'): ++ self.qemu_options += ' -cpu Nehalem' ++ + # QEMU_DEFAULT_MACHINE + self.qemu_default_machine = get_default_machine(self.qemu_prog) + +-- +2.39.1 + diff --git a/kvm-migration-Allow-postcopy_ram_supported_by_host-to-re.patch b/kvm-migration-Allow-postcopy_ram_supported_by_host-to-re.patch new file mode 100644 index 0000000..7c9748b --- /dev/null +++ b/kvm-migration-Allow-postcopy_ram_supported_by_host-to-re.patch @@ -0,0 +1,308 @@ +From e2c2910edf90186ca0d7d13c9943caa284e95ea9 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Tue, 25 Apr 2023 21:15:14 -0400 +Subject: [PATCH 51/56] migration: Allow postcopy_ram_supported_by_host() to + report err +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [50/50] 08c44affc11c27ddf1aa7ce0dfacbaf5effb80cb (peterx/qemu-kvm) + +Instead of print it to STDERR, bring the error upwards so that it can be +reported via QMP responses. + +E.g.: + +{ "execute": "migrate-set-capabilities" , + "arguments": { "capabilities": + [ { "capability": "postcopy-ram", "state": true } ] } } + +{ "error": + { "class": "GenericError", + "desc": "Postcopy is not supported: Host backend files need to be TMPFS + or HUGETLBFS only" } } + +Signed-off-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit 74c38cf7fd24c60e4f0a90585d17250478260877) +Signed-off-by: Peter Xu +--- + migration/options.c | 8 ++---- + migration/postcopy-ram.c | 60 +++++++++++++++++++++------------------- + migration/postcopy-ram.h | 3 +- + migration/savevm.c | 3 +- + 4 files changed, 39 insertions(+), 35 deletions(-) + +diff --git a/migration/options.c b/migration/options.c +index 4701c75a4d..e51d667e14 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -302,6 +302,7 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) + { + MigrationIncomingState *mis = migration_incoming_get_current(); + ++ ERRP_GUARD(); + #ifndef CONFIG_LIVE_BLOCK_MIGRATION + if (new_caps[MIGRATION_CAPABILITY_BLOCK]) { + error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) " +@@ -327,11 +328,8 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) + */ + if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] && + runstate_check(RUN_STATE_INMIGRATE) && +- !postcopy_ram_supported_by_host(mis)) { +- /* postcopy_ram_supported_by_host will have emitted a more +- * detailed message +- */ +- error_setg(errp, "Postcopy is not supported"); ++ !postcopy_ram_supported_by_host(mis, errp)) { ++ error_prepend(errp, "Postcopy is not supported: "); + return false; + } + +diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c +index 0711500036..75aa276bb1 100644 +--- a/migration/postcopy-ram.c ++++ b/migration/postcopy-ram.c +@@ -283,11 +283,13 @@ static bool request_ufd_features(int ufd, uint64_t features) + return true; + } + +-static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis) ++static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis, ++ Error **errp) + { + uint64_t asked_features = 0; + static uint64_t supported_features; + ++ ERRP_GUARD(); + /* + * it's not possible to + * request UFFD_API twice per one fd +@@ -295,7 +297,7 @@ static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis) + */ + if (!supported_features) { + if (!receive_ufd_features(&supported_features)) { +- error_report("%s failed", __func__); ++ error_setg(errp, "Userfault feature detection failed"); + return false; + } + } +@@ -317,8 +319,7 @@ static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis) + * userfault file descriptor + */ + if (!request_ufd_features(ufd, asked_features)) { +- error_report("%s failed: features %" PRIu64, __func__, +- asked_features); ++ error_setg(errp, "Failed features %" PRIu64, asked_features); + return false; + } + +@@ -329,7 +330,8 @@ static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis) + have_hp = supported_features & UFFD_FEATURE_MISSING_HUGETLBFS; + #endif + if (!have_hp) { +- error_report("Userfault on this host does not support huge pages"); ++ error_setg(errp, ++ "Userfault on this host does not support huge pages"); + return false; + } + } +@@ -338,7 +340,7 @@ static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis) + + /* Callback from postcopy_ram_supported_by_host block iterator. + */ +-static int test_ramblock_postcopiable(RAMBlock *rb) ++static int test_ramblock_postcopiable(RAMBlock *rb, Error **errp) + { + const char *block_name = qemu_ram_get_idstr(rb); + ram_addr_t length = qemu_ram_get_used_length(rb); +@@ -346,16 +348,18 @@ static int test_ramblock_postcopiable(RAMBlock *rb) + QemuFsType fs; + + if (length % pagesize) { +- error_report("Postcopy requires RAM blocks to be a page size multiple," +- " block %s is 0x" RAM_ADDR_FMT " bytes with a " +- "page size of 0x%zx", block_name, length, pagesize); ++ error_setg(errp, ++ "Postcopy requires RAM blocks to be a page size multiple," ++ " block %s is 0x" RAM_ADDR_FMT " bytes with a " ++ "page size of 0x%zx", block_name, length, pagesize); + return 1; + } + + if (rb->fd >= 0) { + fs = qemu_fd_getfs(rb->fd); + if (fs != QEMU_FS_TYPE_TMPFS && fs != QEMU_FS_TYPE_HUGETLBFS) { +- error_report("Host backend files need to be TMPFS or HUGETLBFS only"); ++ error_setg(errp, ++ "Host backend files need to be TMPFS or HUGETLBFS only"); + return 1; + } + } +@@ -368,7 +372,7 @@ static int test_ramblock_postcopiable(RAMBlock *rb) + * normally fine since if the postcopy succeeds it gets turned back on at the + * end. + */ +-bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) ++bool postcopy_ram_supported_by_host(MigrationIncomingState *mis, Error **errp) + { + long pagesize = qemu_real_host_page_size(); + int ufd = -1; +@@ -377,29 +381,27 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + struct uffdio_register reg_struct; + struct uffdio_range range_struct; + uint64_t feature_mask; +- Error *local_err = NULL; + RAMBlock *block; + ++ ERRP_GUARD(); + if (qemu_target_page_size() > pagesize) { +- error_report("Target page size bigger than host page size"); ++ error_setg(errp, "Target page size bigger than host page size"); + goto out; + } + + ufd = uffd_open(O_CLOEXEC); + if (ufd == -1) { +- error_report("%s: userfaultfd not available: %s", __func__, +- strerror(errno)); ++ error_setg(errp, "Userfaultfd not available: %s", strerror(errno)); + goto out; + } + + /* Give devices a chance to object */ +- if (postcopy_notify(POSTCOPY_NOTIFY_PROBE, &local_err)) { +- error_report_err(local_err); ++ if (postcopy_notify(POSTCOPY_NOTIFY_PROBE, errp)) { + goto out; + } + + /* Version and features check */ +- if (!ufd_check_and_apply(ufd, mis)) { ++ if (!ufd_check_and_apply(ufd, mis, errp)) { + goto out; + } + +@@ -417,7 +419,7 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + * affect in reality, or we can revisit. + */ + RAMBLOCK_FOREACH(block) { +- if (test_ramblock_postcopiable(block)) { ++ if (test_ramblock_postcopiable(block, errp)) { + goto out; + } + } +@@ -427,7 +429,7 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + * it was enabled. + */ + if (munlockall()) { +- error_report("%s: munlockall: %s", __func__, strerror(errno)); ++ error_setg(errp, "munlockall() failed: %s", strerror(errno)); + goto out; + } + +@@ -439,8 +441,7 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + testarea = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | + MAP_ANONYMOUS, -1, 0); + if (testarea == MAP_FAILED) { +- error_report("%s: Failed to map test area: %s", __func__, +- strerror(errno)); ++ error_setg(errp, "Failed to map test area: %s", strerror(errno)); + goto out; + } + g_assert(QEMU_PTR_IS_ALIGNED(testarea, pagesize)); +@@ -450,14 +451,14 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING; + + if (ioctl(ufd, UFFDIO_REGISTER, ®_struct)) { +- error_report("%s userfault register: %s", __func__, strerror(errno)); ++ error_setg(errp, "UFFDIO_REGISTER failed: %s", strerror(errno)); + goto out; + } + + range_struct.start = (uintptr_t)testarea; + range_struct.len = pagesize; + if (ioctl(ufd, UFFDIO_UNREGISTER, &range_struct)) { +- error_report("%s userfault unregister: %s", __func__, strerror(errno)); ++ error_setg(errp, "UFFDIO_UNREGISTER failed: %s", strerror(errno)); + goto out; + } + +@@ -465,8 +466,8 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + (__u64)1 << _UFFDIO_COPY | + (__u64)1 << _UFFDIO_ZEROPAGE; + if ((reg_struct.ioctls & feature_mask) != feature_mask) { +- error_report("Missing userfault map features: %" PRIx64, +- (uint64_t)(~reg_struct.ioctls & feature_mask)); ++ error_setg(errp, "Missing userfault map features: %" PRIx64, ++ (uint64_t)(~reg_struct.ioctls & feature_mask)); + goto out; + } + +@@ -1188,6 +1189,8 @@ static int postcopy_temp_pages_setup(MigrationIncomingState *mis) + + int postcopy_ram_incoming_setup(MigrationIncomingState *mis) + { ++ Error *local_err = NULL; ++ + /* Open the fd for the kernel to give us userfaults */ + mis->userfault_fd = uffd_open(O_CLOEXEC | O_NONBLOCK); + if (mis->userfault_fd == -1) { +@@ -1200,7 +1203,8 @@ int postcopy_ram_incoming_setup(MigrationIncomingState *mis) + * Although the host check already tested the API, we need to + * do the check again as an ABI handshake on the new fd. + */ +- if (!ufd_check_and_apply(mis->userfault_fd, mis)) { ++ if (!ufd_check_and_apply(mis->userfault_fd, mis, &local_err)) { ++ error_report_err(local_err); + return -1; + } + +@@ -1360,7 +1364,7 @@ void fill_destination_postcopy_migration_info(MigrationInfo *info) + { + } + +-bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) ++bool postcopy_ram_supported_by_host(MigrationIncomingState *mis, Error **errp) + { + error_report("%s: No OS support", __func__); + return false; +diff --git a/migration/postcopy-ram.h b/migration/postcopy-ram.h +index b4867a32d5..442ab89752 100644 +--- a/migration/postcopy-ram.h ++++ b/migration/postcopy-ram.h +@@ -14,7 +14,8 @@ + #define QEMU_POSTCOPY_RAM_H + + /* Return true if the host supports everything we need to do postcopy-ram */ +-bool postcopy_ram_supported_by_host(MigrationIncomingState *mis); ++bool postcopy_ram_supported_by_host(MigrationIncomingState *mis, ++ Error **errp); + + /* + * Make all of RAM sensitive to accesses to areas that haven't yet been written +diff --git a/migration/savevm.c b/migration/savevm.c +index 9671211339..211eff3a8b 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -1753,7 +1753,8 @@ static int loadvm_postcopy_handle_advise(MigrationIncomingState *mis, + return -EINVAL; + } + +- if (!postcopy_ram_supported_by_host(mis)) { ++ if (!postcopy_ram_supported_by_host(mis, &local_err)) { ++ error_report_err(local_err); + postcopy_state_set(POSTCOPY_INCOMING_NONE); + return -1; + } +-- +2.39.1 + diff --git a/kvm-migration-Attempt-disk-reactivation-in-more-failure-.patch b/kvm-migration-Attempt-disk-reactivation-in-more-failure-.patch new file mode 100644 index 0000000..d1620f0 --- /dev/null +++ b/kvm-migration-Attempt-disk-reactivation-in-more-failure-.patch @@ -0,0 +1,111 @@ +From 3691bb5f956e3c60dbf6de183011b31dbc7a7801 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Tue, 2 May 2023 15:52:12 -0500 +Subject: [PATCH 01/56] migration: Attempt disk reactivation in more failure + scenarios + +RH-Author: Eric Blake +RH-MergeRequest: 161: Avoid migration assertion from failed NFS server. +RH-Bugzilla: 2058982 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Acked-by: Kevin Wolf +RH-Commit: [1/1] 5999b747b314641259d3b8809033b057805eed3f (ebblake/centos-qemu-kvm) + +Commit fe904ea824 added a fail_inactivate label, which tries to +reactivate disks on the source after a failure while s->state == +MIGRATION_STATUS_ACTIVE, but didn't actually use the label if +qemu_savevm_state_complete_precopy() failed. This failure to +reactivate is also present in commit 6039dd5b1c (also covering the new +s->state == MIGRATION_STATUS_DEVICE state) and 403d18ae (ensuring +s->block_inactive is set more reliably). + +Consolidate the two labels back into one - no matter HOW migration is +failed, if there is any chance we can reach vm_start() after having +attempted inactivation, it is essential that we have tried to restart +disks before then. This also makes the cleanup more like +migrate_fd_cancel(). + +Suggested-by: Kevin Wolf +Signed-off-by: Eric Blake +Message-Id: <20230502205212.134680-1-eblake@redhat.com> +Acked-by: Peter Xu +Reviewed-by: Juan Quintela +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 6dab4c93ecfae48e2e67b984d1032c1e988d3005) +[eblake: downstream migrate_colo() => migrate_colo_enabled()] +Signed-off-by: Eric Blake +--- + migration/migration.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 08007cef4e..99f86bd6c2 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -3443,6 +3443,11 @@ static void migration_completion(MigrationState *s) + MIGRATION_STATUS_DEVICE); + } + if (ret >= 0) { ++ /* ++ * Inactivate disks except in COLO, and track that we ++ * have done so in order to remember to reactivate ++ * them if migration fails or is cancelled. ++ */ + s->block_inactive = !migrate_colo_enabled(); + qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX); + ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false, +@@ -3487,13 +3492,13 @@ static void migration_completion(MigrationState *s) + rp_error = await_return_path_close_on_source(s); + trace_migration_return_path_end_after(rp_error); + if (rp_error) { +- goto fail_invalidate; ++ goto fail; + } + } + + if (qemu_file_get_error(s->to_dst_file)) { + trace_migration_completion_file_err(); +- goto fail_invalidate; ++ goto fail; + } + + if (migrate_colo_enabled() && s->state == MIGRATION_STATUS_ACTIVE) { +@@ -3507,26 +3512,25 @@ static void migration_completion(MigrationState *s) + + return; + +-fail_invalidate: +- /* If not doing postcopy, vm_start() will be called: let's regain +- * control on images. +- */ +- if (s->state == MIGRATION_STATUS_ACTIVE || +- s->state == MIGRATION_STATUS_DEVICE) { ++fail: ++ if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE || ++ s->state == MIGRATION_STATUS_DEVICE)) { ++ /* ++ * If not doing postcopy, vm_start() will be called: let's ++ * regain control on images. ++ */ + Error *local_err = NULL; + + qemu_mutex_lock_iothread(); + bdrv_activate_all(&local_err); + if (local_err) { + error_report_err(local_err); +- s->block_inactive = true; + } else { + s->block_inactive = false; + } + qemu_mutex_unlock_iothread(); + } + +-fail: + migrate_set_state(&s->state, current_active_state, + MIGRATION_STATUS_FAILED); + } +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_cap_set.patch b/kvm-migration-Create-migrate_cap_set.patch new file mode 100644 index 0000000..33268bb --- /dev/null +++ b/kvm-migration-Create-migrate_cap_set.patch @@ -0,0 +1,93 @@ +From d772464e9a51a085e10864b2dc7ffd49991fc23b Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 21:02:42 +0100 +Subject: [PATCH 22/56] migration: Create migrate_cap_set() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [21/50] 5b12f04013cf2d374a869134bb67c938c789e24d (peterx/qemu-kvm) + +And remove the convoluted use of qmp_migrate_set_capabilities() to +enable disable MIGRATION_CAPABILITY_BLOCK. + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit 9eb1109cfba5415dd0b0cb82e80fc5e42fe861b7) +Signed-off-by: Peter Xu +--- + migration/migration.c | 34 ++++++++++++++++------------------ + 1 file changed, 16 insertions(+), 18 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index b745d829a4..18058fb597 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1912,25 +1912,24 @@ void migrate_set_state(int *state, int old_state, int new_state) + } + } + +-static MigrationCapabilityStatus *migrate_cap_add(MigrationCapability index, +- bool state) ++static bool migrate_cap_set(int cap, bool value, Error **errp) + { +- MigrationCapabilityStatus *cap; +- +- cap = g_new0(MigrationCapabilityStatus, 1); +- cap->capability = index; +- cap->state = state; ++ MigrationState *s = migrate_get_current(); ++ bool new_caps[MIGRATION_CAPABILITY__MAX]; + +- return cap; +-} ++ if (migration_is_running(s->state)) { ++ error_setg(errp, QERR_MIGRATION_ACTIVE); ++ return false; ++ } + +-void migrate_set_block_enabled(bool value, Error **errp) +-{ +- MigrationCapabilityStatusList *cap = NULL; ++ memcpy(new_caps, s->capabilities, sizeof(new_caps)); ++ new_caps[cap] = value; + +- QAPI_LIST_PREPEND(cap, migrate_cap_add(MIGRATION_CAPABILITY_BLOCK, value)); +- qmp_migrate_set_capabilities(cap, errp); +- qapi_free_MigrationCapabilityStatusList(cap); ++ if (!migrate_caps_check(s->capabilities, new_caps, errp)) { ++ return false; ++ } ++ s->capabilities[cap] = value; ++ return true; + } + + static void migrate_set_block_incremental(MigrationState *s, bool value) +@@ -1942,7 +1941,7 @@ static void block_cleanup_parameters(MigrationState *s) + { + if (s->must_remove_block_options) { + /* setting to false can never fail */ +- migrate_set_block_enabled(false, &error_abort); ++ migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, false, &error_abort); + migrate_set_block_incremental(s, false); + s->must_remove_block_options = false; + } +@@ -2429,8 +2428,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc, + "current migration capabilities"); + return false; + } +- migrate_set_block_enabled(true, &local_err); +- if (local_err) { ++ if (!migrate_cap_set(MIGRATION_CAPABILITY_BLOCK, true, &local_err)) { + error_propagate(errp, local_err); + return false; + } +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_checkpoint_delay.patch b/kvm-migration-Create-migrate_checkpoint_delay.patch new file mode 100644 index 0000000..408d258 --- /dev/null +++ b/kvm-migration-Create-migrate_checkpoint_delay.patch @@ -0,0 +1,84 @@ +From a17bee3c8ab48daa471ec53bed0e2cb0bb41fc76 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 01:04:55 +0100 +Subject: [PATCH 41/56] migration: Create migrate_checkpoint_delay() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [40/50] b972d3f12e49dc27aa78eb723ca6d0fac4d174d8 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit f94a858fa3e72ba954a338c01ae9fecc15fcce5c) +Signed-off-by: Peter Xu +--- + migration/colo.c | 5 ++--- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/migration/colo.c b/migration/colo.c +index 93b78c9270..07bfa21fea 100644 +--- a/migration/colo.c ++++ b/migration/colo.c +@@ -576,7 +576,7 @@ static void colo_process_checkpoint(MigrationState *s) + trace_colo_vm_state_change("stop", "run"); + + timer_mod(s->colo_delay_timer, qemu_clock_get_ms(QEMU_CLOCK_HOST) + +- s->parameters.x_checkpoint_delay); ++ migrate_checkpoint_delay()); + + while (s->state == MIGRATION_STATUS_COLO) { + if (failover_get_state() != FAILOVER_STATUS_NONE) { +@@ -651,8 +651,7 @@ void colo_checkpoint_notify(void *opaque) + + qemu_event_set(&s->colo_checkpoint_event); + s->colo_checkpoint_time = qemu_clock_get_ms(QEMU_CLOCK_HOST); +- next_notify_time = s->colo_checkpoint_time + +- s->parameters.x_checkpoint_delay; ++ next_notify_time = s->colo_checkpoint_time + migrate_checkpoint_delay(); + timer_mod(s->colo_delay_timer, next_notify_time); + } + +diff --git a/migration/options.c b/migration/options.c +index b9f3815f7e..0e102e5700 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -472,6 +472,15 @@ bool migrate_block_incremental(void) + return s->parameters.block_incremental; + } + ++uint32_t migrate_checkpoint_delay(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.x_checkpoint_delay; ++} ++ + int migrate_compress_level(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index aa54443353..adc2879bbb 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -46,6 +46,7 @@ bool migrate_cap_set(int cap, bool value, Error **errp); + /* parameters */ + + bool migrate_block_incremental(void); ++uint32_t migrate_checkpoint_delay(void); + int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_cpu_throttle_increment-func.patch b/kvm-migration-Create-migrate_cpu_throttle_increment-func.patch new file mode 100644 index 0000000..65bad3c --- /dev/null +++ b/kvm-migration-Create-migrate_cpu_throttle_increment-func.patch @@ -0,0 +1,75 @@ +From 7ff430e011780dad00e5ebaad0318c5fa3aec102 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 10:20:49 +0100 +Subject: [PATCH 45/56] migration: Create migrate_cpu_throttle_increment() + function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [44/50] aec990a106a0347b265f5c056a516e0b91e8183c (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit 9605c2ac282c565bb00b5f344217161bef29eff8) +Signed-off-by: Peter Xu +--- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 2 +- + 3 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/migration/options.c b/migration/options.c +index f7fb6999f7..31435d2b45 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -509,6 +509,15 @@ int migrate_compress_wait_thread(void) + return s->parameters.compress_wait_thread; + } + ++uint8_t migrate_cpu_throttle_increment(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.cpu_throttle_increment; ++} ++ + uint8_t migrate_cpu_throttle_initial(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index fd8b91d767..49b29bdafd 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -50,6 +50,7 @@ uint32_t migrate_checkpoint_delay(void); + int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); ++uint8_t migrate_cpu_throttle_increment(void); + uint8_t migrate_cpu_throttle_initial(void); + int migrate_decompress_threads(void); + uint8_t migrate_max_cpu_throttle(void); +diff --git a/migration/ram.c b/migration/ram.c +index 5e855d5c22..5645745a42 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -713,7 +713,7 @@ static void mig_throttle_guest_down(uint64_t bytes_dirty_period, + { + MigrationState *s = migrate_get_current(); + uint64_t pct_initial = migrate_cpu_throttle_initial(); +- uint64_t pct_increment = s->parameters.cpu_throttle_increment; ++ uint64_t pct_increment = migrate_cpu_throttle_increment(); + bool pct_tailslow = s->parameters.cpu_throttle_tailslow; + int pct_max = migrate_max_cpu_throttle(); + +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_cpu_throttle_initial-to-opt.patch b/kvm-migration-Create-migrate_cpu_throttle_initial-to-opt.patch new file mode 100644 index 0000000..aab2013 --- /dev/null +++ b/kvm-migration-Create-migrate_cpu_throttle_initial-to-opt.patch @@ -0,0 +1,75 @@ +From fdc2f14bfb3ef8897310a7db63287a9bab1fb858 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 01:22:44 +0100 +Subject: [PATCH 44/56] migration: Create migrate_cpu_throttle_initial() to + option.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [43/50] e0e0db7218f28aefd4bd022edbaec236e2030cb1 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit 2a8ec38082f8098f2693bb3632175453c0c84a51) +Signed-off-by: Peter Xu +--- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 2 +- + 3 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/migration/options.c b/migration/options.c +index 418aafac64..f7fb6999f7 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -509,6 +509,15 @@ int migrate_compress_wait_thread(void) + return s->parameters.compress_wait_thread; + } + ++uint8_t migrate_cpu_throttle_initial(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.cpu_throttle_initial; ++} ++ + int migrate_decompress_threads(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index 72b1a320b7..fd8b91d767 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -50,6 +50,7 @@ uint32_t migrate_checkpoint_delay(void); + int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); ++uint8_t migrate_cpu_throttle_initial(void); + int migrate_decompress_threads(void); + uint8_t migrate_max_cpu_throttle(void); + int64_t migrate_max_postcopy_bandwidth(void); +diff --git a/migration/ram.c b/migration/ram.c +index 5c786513ef..5e855d5c22 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -712,7 +712,7 @@ static void mig_throttle_guest_down(uint64_t bytes_dirty_period, + uint64_t bytes_dirty_threshold) + { + MigrationState *s = migrate_get_current(); +- uint64_t pct_initial = s->parameters.cpu_throttle_initial; ++ uint64_t pct_initial = migrate_cpu_throttle_initial(); + uint64_t pct_increment = s->parameters.cpu_throttle_increment; + bool pct_tailslow = s->parameters.cpu_throttle_tailslow; + int pct_max = migrate_max_cpu_throttle(); +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_cpu_throttle_tailslow-funct.patch b/kvm-migration-Create-migrate_cpu_throttle_tailslow-funct.patch new file mode 100644 index 0000000..e36f003 --- /dev/null +++ b/kvm-migration-Create-migrate_cpu_throttle_tailslow-funct.patch @@ -0,0 +1,78 @@ +From b88c51c4b02639e28da73143b1da7bd3d6706ce5 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 10:29:51 +0100 +Subject: [PATCH 46/56] migration: Create migrate_cpu_throttle_tailslow() + function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [45/50] e93e96392405c60f75abbf288e4fddb191bbc996 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit 873f674c559e3162a6e6e92994301d400c5cc873) +Signed-off-by: Peter Xu +--- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 3 +-- + 3 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/migration/options.c b/migration/options.c +index 31435d2b45..615534c151 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -527,6 +527,15 @@ uint8_t migrate_cpu_throttle_initial(void) + return s->parameters.cpu_throttle_initial; + } + ++bool migrate_cpu_throttle_tailslow(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.cpu_throttle_tailslow; ++} ++ + int migrate_decompress_threads(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index 49b29bdafd..99f6bbd7a1 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -52,6 +52,7 @@ int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); + uint8_t migrate_cpu_throttle_increment(void); + uint8_t migrate_cpu_throttle_initial(void); ++bool migrate_cpu_throttle_tailslow(void); + int migrate_decompress_threads(void); + uint8_t migrate_max_cpu_throttle(void); + int64_t migrate_max_postcopy_bandwidth(void); +diff --git a/migration/ram.c b/migration/ram.c +index 5645745a42..01356f60a4 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -711,10 +711,9 @@ static size_t save_page_header(PageSearchStatus *pss, QEMUFile *f, + static void mig_throttle_guest_down(uint64_t bytes_dirty_period, + uint64_t bytes_dirty_threshold) + { +- MigrationState *s = migrate_get_current(); + uint64_t pct_initial = migrate_cpu_throttle_initial(); + uint64_t pct_increment = migrate_cpu_throttle_increment(); +- bool pct_tailslow = s->parameters.cpu_throttle_tailslow; ++ bool pct_tailslow = migrate_cpu_throttle_tailslow(); + int pct_max = migrate_max_cpu_throttle(); + + uint64_t throttle_now = cpu_throttle_get_percentage(); +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_max_bandwidth-function.patch b/kvm-migration-Create-migrate_max_bandwidth-function.patch new file mode 100644 index 0000000..ba1d34c --- /dev/null +++ b/kvm-migration-Create-migrate_max_bandwidth-function.patch @@ -0,0 +1,232 @@ +From b6228b3122f5c1f220f92042277ab1bfbb5ba086 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 11:00:12 +0100 +Subject: [PATCH 48/56] migration: Create migrate_max_bandwidth() function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [47/50] 3874656f70cb9c2a30f4d63e146539480d422326 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit 9c894df3a37d675652390f7dbbe2f65b7bad7efa) +Signed-off-by: Peter Xu +--- + migration/migration.c | 70 +------------------------------------- + migration/options.c | 79 +++++++++++++++++++++++++++++++++++++++++++ + migration/options.h | 1 + + 3 files changed, 81 insertions(+), 69 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 46a5ea4d42..c2e109329d 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -886,74 +886,6 @@ void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value) + migrate_send_rp_message(mis, MIG_RP_MSG_RESUME_ACK, sizeof(buf), &buf); + } + +-MigrationParameters *qmp_query_migrate_parameters(Error **errp) +-{ +- MigrationParameters *params; +- MigrationState *s = migrate_get_current(); +- +- /* TODO use QAPI_CLONE() instead of duplicating it inline */ +- params = g_malloc0(sizeof(*params)); +- params->has_compress_level = true; +- params->compress_level = s->parameters.compress_level; +- params->has_compress_threads = true; +- params->compress_threads = s->parameters.compress_threads; +- params->has_compress_wait_thread = true; +- params->compress_wait_thread = s->parameters.compress_wait_thread; +- params->has_decompress_threads = true; +- params->decompress_threads = s->parameters.decompress_threads; +- params->has_throttle_trigger_threshold = true; +- params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; +- params->has_cpu_throttle_initial = true; +- params->cpu_throttle_initial = s->parameters.cpu_throttle_initial; +- params->has_cpu_throttle_increment = true; +- params->cpu_throttle_increment = s->parameters.cpu_throttle_increment; +- params->has_cpu_throttle_tailslow = true; +- params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow; +- params->tls_creds = g_strdup(s->parameters.tls_creds); +- params->tls_hostname = g_strdup(s->parameters.tls_hostname); +- params->tls_authz = g_strdup(s->parameters.tls_authz ? +- s->parameters.tls_authz : ""); +- params->has_max_bandwidth = true; +- params->max_bandwidth = s->parameters.max_bandwidth; +- params->has_downtime_limit = true; +- params->downtime_limit = s->parameters.downtime_limit; +- params->has_x_checkpoint_delay = true; +- params->x_checkpoint_delay = s->parameters.x_checkpoint_delay; +- params->has_block_incremental = true; +- params->block_incremental = s->parameters.block_incremental; +- params->has_multifd_channels = true; +- params->multifd_channels = s->parameters.multifd_channels; +- params->has_multifd_compression = true; +- params->multifd_compression = s->parameters.multifd_compression; +- params->has_multifd_zlib_level = true; +- params->multifd_zlib_level = s->parameters.multifd_zlib_level; +- params->has_multifd_zstd_level = true; +- params->multifd_zstd_level = s->parameters.multifd_zstd_level; +- params->has_xbzrle_cache_size = true; +- params->xbzrle_cache_size = s->parameters.xbzrle_cache_size; +- params->has_max_postcopy_bandwidth = true; +- params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth; +- params->has_max_cpu_throttle = true; +- params->max_cpu_throttle = s->parameters.max_cpu_throttle; +- params->has_announce_initial = true; +- params->announce_initial = s->parameters.announce_initial; +- params->has_announce_max = true; +- params->announce_max = s->parameters.announce_max; +- params->has_announce_rounds = true; +- params->announce_rounds = s->parameters.announce_rounds; +- params->has_announce_step = true; +- params->announce_step = s->parameters.announce_step; +- +- if (s->parameters.has_block_bitmap_mapping) { +- params->has_block_bitmap_mapping = true; +- params->block_bitmap_mapping = +- QAPI_CLONE(BitmapMigrationNodeAliasList, +- s->parameters.block_bitmap_mapping); +- } +- +- return params; +-} +- + /* + * Return true if we're already in the middle of a migration + * (i.e. any of the active or setup states) +@@ -3775,7 +3707,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) + XFER_LIMIT_RATIO; + } else { + /* This is a fresh new migration */ +- rate_limit = s->parameters.max_bandwidth / XFER_LIMIT_RATIO; ++ rate_limit = migrate_max_bandwidth() / XFER_LIMIT_RATIO; + + /* Notify before starting migration thread */ + notifier_list_notify(&migration_state_notifiers, s); +diff --git a/migration/options.c b/migration/options.c +index 8bd2d949ae..8e8753d9be 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -12,8 +12,10 @@ + */ + + #include "qemu/osdep.h" ++#include "qapi/clone-visitor.h" + #include "qapi/error.h" + #include "qapi/qapi-commands-migration.h" ++#include "qapi/qapi-visit-migration.h" + #include "qapi/qmp/qerror.h" + #include "sysemu/runstate.h" + #include "migration/misc.h" +@@ -562,6 +564,15 @@ uint8_t migrate_max_cpu_throttle(void) + return s->parameters.max_cpu_throttle; + } + ++uint64_t migrate_max_bandwidth(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.max_bandwidth; ++} ++ + int64_t migrate_max_postcopy_bandwidth(void) + { + MigrationState *s; +@@ -641,3 +652,71 @@ AnnounceParameters *migrate_announce_params(void) + + return ≈ + } ++ ++MigrationParameters *qmp_query_migrate_parameters(Error **errp) ++{ ++ MigrationParameters *params; ++ MigrationState *s = migrate_get_current(); ++ ++ /* TODO use QAPI_CLONE() instead of duplicating it inline */ ++ params = g_malloc0(sizeof(*params)); ++ params->has_compress_level = true; ++ params->compress_level = s->parameters.compress_level; ++ params->has_compress_threads = true; ++ params->compress_threads = s->parameters.compress_threads; ++ params->has_compress_wait_thread = true; ++ params->compress_wait_thread = s->parameters.compress_wait_thread; ++ params->has_decompress_threads = true; ++ params->decompress_threads = s->parameters.decompress_threads; ++ params->has_throttle_trigger_threshold = true; ++ params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; ++ params->has_cpu_throttle_initial = true; ++ params->cpu_throttle_initial = s->parameters.cpu_throttle_initial; ++ params->has_cpu_throttle_increment = true; ++ params->cpu_throttle_increment = s->parameters.cpu_throttle_increment; ++ params->has_cpu_throttle_tailslow = true; ++ params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow; ++ params->tls_creds = g_strdup(s->parameters.tls_creds); ++ params->tls_hostname = g_strdup(s->parameters.tls_hostname); ++ params->tls_authz = g_strdup(s->parameters.tls_authz ? ++ s->parameters.tls_authz : ""); ++ params->has_max_bandwidth = true; ++ params->max_bandwidth = s->parameters.max_bandwidth; ++ params->has_downtime_limit = true; ++ params->downtime_limit = s->parameters.downtime_limit; ++ params->has_x_checkpoint_delay = true; ++ params->x_checkpoint_delay = s->parameters.x_checkpoint_delay; ++ params->has_block_incremental = true; ++ params->block_incremental = s->parameters.block_incremental; ++ params->has_multifd_channels = true; ++ params->multifd_channels = s->parameters.multifd_channels; ++ params->has_multifd_compression = true; ++ params->multifd_compression = s->parameters.multifd_compression; ++ params->has_multifd_zlib_level = true; ++ params->multifd_zlib_level = s->parameters.multifd_zlib_level; ++ params->has_multifd_zstd_level = true; ++ params->multifd_zstd_level = s->parameters.multifd_zstd_level; ++ params->has_xbzrle_cache_size = true; ++ params->xbzrle_cache_size = s->parameters.xbzrle_cache_size; ++ params->has_max_postcopy_bandwidth = true; ++ params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth; ++ params->has_max_cpu_throttle = true; ++ params->max_cpu_throttle = s->parameters.max_cpu_throttle; ++ params->has_announce_initial = true; ++ params->announce_initial = s->parameters.announce_initial; ++ params->has_announce_max = true; ++ params->announce_max = s->parameters.announce_max; ++ params->has_announce_rounds = true; ++ params->announce_rounds = s->parameters.announce_rounds; ++ params->has_announce_step = true; ++ params->announce_step = s->parameters.announce_step; ++ ++ if (s->parameters.has_block_bitmap_mapping) { ++ params->has_block_bitmap_mapping = true; ++ params->block_bitmap_mapping = ++ QAPI_CLONE(BitmapMigrationNodeAliasList, ++ s->parameters.block_bitmap_mapping); ++ } ++ ++ return params; ++} +diff --git a/migration/options.h b/migration/options.h +index 093bc907a1..1b78fa9f3d 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -64,6 +64,7 @@ uint8_t migrate_cpu_throttle_initial(void); + bool migrate_cpu_throttle_tailslow(void); + int migrate_decompress_threads(void); + uint8_t migrate_max_cpu_throttle(void); ++uint64_t migrate_max_bandwidth(void); + int64_t migrate_max_postcopy_bandwidth(void); + int migrate_multifd_channels(void); + MultiFDCompression migrate_multifd_compression(void); +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_max_cpu_throttle.patch b/kvm-migration-Create-migrate_max_cpu_throttle.patch new file mode 100644 index 0000000..6628b80 --- /dev/null +++ b/kvm-migration-Create-migrate_max_cpu_throttle.patch @@ -0,0 +1,88 @@ +From f0d4e34b00f66d2336b755a34a1ba226571641c4 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 01:13:01 +0100 +Subject: [PATCH 42/56] migration: Create migrate_max_cpu_throttle() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [41/50] fc7537c06d8e1f53d7bb552661f6ddb0133a978d (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit 24155bd0520035d5148c0af5b925932c4d8064a8) +Signed-off-by: Peter Xu +--- + migration/migration.h | 2 -- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 2 +- + 4 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/migration/migration.h b/migration/migration.h +index 86051af132..3ae938b19c 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -451,8 +451,6 @@ bool migrate_postcopy(void); + + int migrate_use_tls(void); + +-int migrate_max_cpu_throttle(void); +- + uint64_t ram_get_total_transferred_pages(void); + + /* Sending on the return path - generic and then for each message type */ +diff --git a/migration/options.c b/migration/options.c +index 0e102e5700..2cb04fbbd1 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -517,6 +517,15 @@ int migrate_decompress_threads(void) + return s->parameters.decompress_threads; + } + ++uint8_t migrate_max_cpu_throttle(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.max_cpu_throttle; ++} ++ + int64_t migrate_max_postcopy_bandwidth(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index adc2879bbb..72b1a320b7 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -51,6 +51,7 @@ int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); + int migrate_decompress_threads(void); ++uint8_t migrate_max_cpu_throttle(void); + int64_t migrate_max_postcopy_bandwidth(void); + int migrate_multifd_channels(void); + MultiFDCompression migrate_multifd_compression(void); +diff --git a/migration/ram.c b/migration/ram.c +index e82cee97c3..5c786513ef 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -715,7 +715,7 @@ static void mig_throttle_guest_down(uint64_t bytes_dirty_period, + uint64_t pct_initial = s->parameters.cpu_throttle_initial; + uint64_t pct_increment = s->parameters.cpu_throttle_increment; + bool pct_tailslow = s->parameters.cpu_throttle_tailslow; +- int pct_max = s->parameters.max_cpu_throttle; ++ int pct_max = migrate_max_cpu_throttle(); + + uint64_t throttle_now = cpu_throttle_get_percentage(); + uint64_t cpu_now, cpu_ideal, throttle_inc; +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_rdma_pin_all-function.patch b/kvm-migration-Create-migrate_rdma_pin_all-function.patch new file mode 100644 index 0000000..c7799f1 --- /dev/null +++ b/kvm-migration-Create-migrate_rdma_pin_all-function.patch @@ -0,0 +1,95 @@ +From e4ef0f2cee6cdf2cf4bd225ac9e610f41d66dfcb Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:41:55 +0100 +Subject: [PATCH 32/56] migration: Create migrate_rdma_pin_all() function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [31/50] 206d96d47d9ee73ddc89dd01186560bf62ea5295 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy + +--- + +Fixed missing space after comma (fabiano) + +(cherry picked from commit 17cba690cdd42108369fafe6b07bff09872fbea6) +Signed-off-by: Peter Xu +--- + migration/options.c | 7 +++++++ + migration/options.h | 1 + + migration/rdma.c | 6 +++--- + 3 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/migration/options.c b/migration/options.c +index 2003e413da..9c9b8e5863 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -138,6 +138,13 @@ bool migrate_postcopy_ram(void) + return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; + } + ++bool migrate_rdma_pin_all(void) ++{ ++ MigrationState *s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]; ++} ++ + bool migrate_release_ram(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index 316efd1063..25c002b37a 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -30,6 +30,7 @@ bool migrate_pause_before_switchover(void); + bool migrate_postcopy_blocktime(void); + bool migrate_postcopy_preempt(void); + bool migrate_postcopy_ram(void); ++bool migrate_rdma_pin_all(void); + bool migrate_release_ram(void); + bool migrate_return_path(void); + bool migrate_validate_uuid(void); +diff --git a/migration/rdma.c b/migration/rdma.c +index bf55e2f163..0af5e944f0 100644 +--- a/migration/rdma.c ++++ b/migration/rdma.c +@@ -35,6 +35,7 @@ + #include + #include "trace.h" + #include "qom/object.h" ++#include "options.h" + #include + + /* +@@ -4178,8 +4179,7 @@ void rdma_start_outgoing_migration(void *opaque, + goto err; + } + +- ret = qemu_rdma_source_init(rdma, +- s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); ++ ret = qemu_rdma_source_init(rdma, migrate_rdma_pin_all(), errp); + + if (ret) { + goto err; +@@ -4201,7 +4201,7 @@ void rdma_start_outgoing_migration(void *opaque, + } + + ret = qemu_rdma_source_init(rdma_return_path, +- s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); ++ migrate_rdma_pin_all(), errp); + + if (ret) { + goto return_path_err; +-- +2.39.1 + diff --git a/kvm-migration-Create-migrate_throttle_trigger_threshold.patch b/kvm-migration-Create-migrate_throttle_trigger_threshold.patch new file mode 100644 index 0000000..5fc1072 --- /dev/null +++ b/kvm-migration-Create-migrate_throttle_trigger_threshold.patch @@ -0,0 +1,75 @@ +From 27862b9d31da6447b60f185cdad95764018c6bc6 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 00:59:13 +0100 +Subject: [PATCH 40/56] migration: Create migrate_throttle_trigger_threshold() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [39/50] b8af9080c49be3d38bd2784d61289be89c03db3e (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit 6499efdb16e5c1288b4c8390d3bf68b313329b8b) +Signed-off-by: Peter Xu +--- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 3 +-- + 3 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/migration/options.c b/migration/options.c +index 2b6d88b4b9..b9f3815f7e 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -554,6 +554,15 @@ int migrate_multifd_zstd_level(void) + return s->parameters.multifd_zstd_level; + } + ++uint8_t migrate_throttle_trigger_threshold(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.throttle_trigger_threshold; ++} ++ + uint64_t migrate_xbzrle_cache_size(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index 96d5a8e6e4..aa54443353 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -55,6 +55,7 @@ int migrate_multifd_channels(void); + MultiFDCompression migrate_multifd_compression(void); + int migrate_multifd_zlib_level(void); + int migrate_multifd_zstd_level(void); ++uint8_t migrate_throttle_trigger_threshold(void); + uint64_t migrate_xbzrle_cache_size(void); + + #endif +diff --git a/migration/ram.c b/migration/ram.c +index 4576d0d849..e82cee97c3 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1178,8 +1178,7 @@ static void migration_update_rates(RAMState *rs, int64_t end_time) + + static void migration_trigger_throttle(RAMState *rs) + { +- MigrationState *s = migrate_get_current(); +- uint64_t threshold = s->parameters.throttle_trigger_threshold; ++ uint64_t threshold = migrate_throttle_trigger_threshold(); + uint64_t bytes_xfer_period = + stat64_get(&ram_counters.transferred) - rs->bytes_xfer_prev; + uint64_t bytes_dirty_period = rs->num_dirty_pages_period * TARGET_PAGE_SIZE; +-- +2.39.1 + diff --git a/kvm-migration-Create-options.c.patch b/kvm-migration-Create-options.c.patch new file mode 100644 index 0000000..ea60202 --- /dev/null +++ b/kvm-migration-Create-options.c.patch @@ -0,0 +1,524 @@ +From 282634a835f4711c8b501dd76c344058bc399fbd Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 21:18:45 +0100 +Subject: [PATCH 23/56] migration: Create options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [22/50] 10c9be528b9fcfae93f1a12fcd09db1a69e58f64 (peterx/qemu-kvm) + +We move there all capabilities helpers from migration.c. + +Signed-off-by: Juan Quintela +Reviewed-by: Dr. David Alan Gilbert + +--- + +Following David advise: +- looked through the history, capabilities are newer than 2012, so we + can remove that bit of the header. +- This part is posterior to Anthony. + Original Author is Orit. Once there, + I put myself. Peter Xu also did quite a bit of work here. + Anyone else wants/needs to be there? I didn't search too hard + because nobody asked before to be added. + +What do you think? + +(cherry picked from commit 1f0776f1c03312aad5d6a5f98871240bc3af01e5) +Signed-off-by: Peter Xu +--- + hw/virtio/virtio-balloon.c | 1 + + migration/block-dirty-bitmap.c | 1 + + migration/block.c | 1 + + migration/colo.c | 1 + + migration/meson.build | 1 + + migration/migration.c | 109 +---------------------------- + migration/migration.h | 12 ---- + migration/options.c | 124 +++++++++++++++++++++++++++++++++ + migration/options.h | 32 +++++++++ + migration/postcopy-ram.c | 1 + + migration/ram.c | 1 + + migration/savevm.c | 1 + + migration/socket.c | 1 + + 13 files changed, 166 insertions(+), 120 deletions(-) + create mode 100644 migration/options.c + create mode 100644 migration/options.h + +diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c +index 746f07c4d2..43092aa634 100644 +--- a/hw/virtio/virtio-balloon.c ++++ b/hw/virtio/virtio-balloon.c +@@ -32,6 +32,7 @@ + #include "qemu/error-report.h" + #include "migration/misc.h" + #include "migration/migration.h" ++#include "migration/options.h" + + #include "hw/virtio/virtio-bus.h" + #include "hw/virtio/virtio-access.h" +diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c +index fe73aa94b1..a6ffae0002 100644 +--- a/migration/block-dirty-bitmap.c ++++ b/migration/block-dirty-bitmap.c +@@ -79,6 +79,7 @@ + #include "qapi/qapi-visit-migration.h" + #include "qapi/clone-visitor.h" + #include "trace.h" ++#include "options.h" + + #define CHUNK_SIZE (1 << 10) + +diff --git a/migration/block.c b/migration/block.c +index b2497bbd32..4b167fa5cf 100644 +--- a/migration/block.c ++++ b/migration/block.c +@@ -28,6 +28,7 @@ + #include "migration/vmstate.h" + #include "sysemu/block-backend.h" + #include "trace.h" ++#include "options.h" + + #define BLK_MIG_BLOCK_SIZE (1ULL << 20) + #define BDRV_SECTORS_PER_DIRTY_CHUNK (BLK_MIG_BLOCK_SIZE >> BDRV_SECTOR_BITS) +diff --git a/migration/colo.c b/migration/colo.c +index 0716e64689..93b78c9270 100644 +--- a/migration/colo.c ++++ b/migration/colo.c +@@ -36,6 +36,7 @@ + #include "sysemu/cpus.h" + #include "sysemu/runstate.h" + #include "net/filter.h" ++#include "options.h" + + static bool vmstate_loading; + static Notifier packets_compare_notifier; +diff --git a/migration/meson.build b/migration/meson.build +index 0d1bb9f96e..480ff6854a 100644 +--- a/migration/meson.build ++++ b/migration/meson.build +@@ -22,6 +22,7 @@ softmmu_ss.add(files( + 'migration.c', + 'multifd.c', + 'multifd-zlib.c', ++ 'options.c', + 'postcopy-ram.c', + 'savevm.c', + 'socket.c', +diff --git a/migration/migration.c b/migration/migration.c +index 18058fb597..66ea55be06 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -63,6 +63,7 @@ + #include "sysemu/cpus.h" + #include "yank_functions.h" + #include "sysemu/qtest.h" ++#include "options.h" + + #define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ + +@@ -357,15 +358,6 @@ static void migrate_generate_event(int new_state) + } + } + +-static bool migrate_late_block_activate(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; +-} +- + /* + * Send a message on the return channel back to the source + * of the migration. +@@ -2525,56 +2517,11 @@ void qmp_migrate_continue(MigrationStatus state, Error **errp) + qemu_sem_post(&s->pause_sem); + } + +-bool migrate_release_ram(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; +-} +- +-bool migrate_postcopy_ram(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; +-} +- + bool migrate_postcopy(void) + { + return migrate_postcopy_ram() || migrate_dirty_bitmaps(); + } + +-bool migrate_auto_converge(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; +-} +- +-bool migrate_zero_blocks(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; +-} +- +-bool migrate_postcopy_blocktime(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; +-} +- + bool migrate_use_compression(void) + { + MigrationState *s; +@@ -2620,33 +2567,6 @@ int migrate_decompress_threads(void) + return s->parameters.decompress_threads; + } + +-bool migrate_dirty_bitmaps(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; +-} +- +-bool migrate_ignore_shared(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; +-} +- +-bool migrate_validate_uuid(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; +-} +- + bool migrate_use_events(void) + { + MigrationState *s; +@@ -2665,15 +2585,6 @@ bool migrate_use_multifd(void) + return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; + } + +-bool migrate_pause_before_switchover(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; +-} +- + int migrate_multifd_channels(void) + { + MigrationState *s; +@@ -2785,24 +2696,6 @@ bool migrate_use_block_incremental(void) + return s->parameters.block_incremental; + } + +-bool migrate_background_snapshot(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; +-} +- +-bool migrate_postcopy_preempt(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; +-} +- + /* migration thread support */ + /* + * Something bad happened to the RP stream, mark an error +diff --git a/migration/migration.h b/migration/migration.h +index 04e0860b4e..a25fed6ef0 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -449,16 +449,7 @@ MigrationState *migrate_get_current(void); + + bool migrate_postcopy(void); + +-bool migrate_release_ram(void); +-bool migrate_postcopy_ram(void); +-bool migrate_zero_blocks(void); +-bool migrate_dirty_bitmaps(void); +-bool migrate_ignore_shared(void); +-bool migrate_validate_uuid(void); +- +-bool migrate_auto_converge(void); + bool migrate_use_multifd(void); +-bool migrate_pause_before_switchover(void); + int migrate_multifd_channels(void); + MultiFDCompression migrate_multifd_compression(void); + int migrate_multifd_zlib_level(void); +@@ -487,9 +478,6 @@ int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); + int migrate_decompress_threads(void); + bool migrate_use_events(void); +-bool migrate_postcopy_blocktime(void); +-bool migrate_background_snapshot(void); +-bool migrate_postcopy_preempt(void); + + /* Sending on the return path - generic and then for each message type */ + void migrate_send_rp_shut(MigrationIncomingState *mis, +diff --git a/migration/options.c b/migration/options.c +new file mode 100644 +index 0000000000..88a9a45913 +--- /dev/null ++++ b/migration/options.c +@@ -0,0 +1,124 @@ ++/* ++ * QEMU migration capabilities ++ * ++ * Copyright (c) 2012-2023 Red Hat Inc ++ * ++ * Authors: ++ * Orit Wasserman ++ * Juan Quintela ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#include "qemu/osdep.h" ++#include "migration.h" ++#include "options.h" ++ ++bool migrate_auto_converge(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; ++} ++ ++bool migrate_background_snapshot(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; ++} ++ ++bool migrate_dirty_bitmaps(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; ++} ++ ++bool migrate_ignore_shared(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; ++} ++ ++bool migrate_late_block_activate(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; ++} ++ ++bool migrate_pause_before_switchover(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; ++} ++ ++bool migrate_postcopy_blocktime(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; ++} ++ ++bool migrate_postcopy_preempt(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; ++} ++ ++bool migrate_postcopy_ram(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; ++} ++ ++bool migrate_release_ram(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; ++} ++ ++bool migrate_validate_uuid(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; ++} ++ ++bool migrate_zero_blocks(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; ++} +diff --git a/migration/options.h b/migration/options.h +new file mode 100644 +index 0000000000..0dfa0af245 +--- /dev/null ++++ b/migration/options.h +@@ -0,0 +1,32 @@ ++/* ++ * QEMU migration capabilities ++ * ++ * Copyright (c) 2012-2023 Red Hat Inc ++ * ++ * Authors: ++ * Orit Wasserman ++ * Juan Quintela ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#ifndef QEMU_MIGRATION_OPTIONS_H ++#define QEMU_MIGRATION_OPTIONS_H ++ ++/* capabilities */ ++ ++bool migrate_auto_converge(void); ++bool migrate_background_snapshot(void); ++bool migrate_dirty_bitmaps(void); ++bool migrate_ignore_shared(void); ++bool migrate_late_block_activate(void); ++bool migrate_pause_before_switchover(void); ++bool migrate_postcopy_blocktime(void); ++bool migrate_postcopy_preempt(void); ++bool migrate_postcopy_ram(void); ++bool migrate_release_ram(void); ++bool migrate_validate_uuid(void); ++bool migrate_zero_blocks(void); ++ ++#endif +diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c +index d7b48dd920..0711500036 100644 +--- a/migration/postcopy-ram.c ++++ b/migration/postcopy-ram.c +@@ -37,6 +37,7 @@ + #include "tls.h" + #include "qemu/userfaultfd.h" + #include "qemu/mmap-alloc.h" ++#include "options.h" + + /* Arbitrary limit on size of each discard command, + * keeps them around ~200 bytes +diff --git a/migration/ram.c b/migration/ram.c +index 229714045a..912ccd89fa 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -57,6 +57,7 @@ + #include "qemu/iov.h" + #include "multifd.h" + #include "sysemu/runstate.h" ++#include "options.h" + + #include "hw/boards.h" /* for machine_dump_guest_core() */ + +diff --git a/migration/savevm.c b/migration/savevm.c +index 589ef926ab..ebcf571e37 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -67,6 +67,7 @@ + #include "qemu/yank.h" + #include "yank_functions.h" + #include "sysemu/qtest.h" ++#include "options.h" + + const unsigned int postcopy_ram_discard_version; + +diff --git a/migration/socket.c b/migration/socket.c +index e6fdf3c5e1..ebf9ac41af 100644 +--- a/migration/socket.c ++++ b/migration/socket.c +@@ -27,6 +27,7 @@ + #include "io/net-listener.h" + #include "trace.h" + #include "postcopy-ram.h" ++#include "options.h" + + struct SocketOutgoingArgs { + SocketAddress *saddr; +-- +2.39.1 + diff --git a/kvm-migration-Make-dirty_sync_count-atomic.patch b/kvm-migration-Make-dirty_sync_count-atomic.patch new file mode 100644 index 0000000..ad1de7b --- /dev/null +++ b/kvm-migration-Make-dirty_sync_count-atomic.patch @@ -0,0 +1,105 @@ +From 886b511e0a225b1c4428c646534d7bcc65bd9e2a Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Tue, 11 Apr 2023 18:02:34 +0200 +Subject: [PATCH 14/56] migration: Make dirty_sync_count atomic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [13/50] ef3ae8cdd960e944ba9e73a53d54c9a5a55bb1ce (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +(cherry picked from commit 536b5a4e56ec67c958f46e7d46cbd5ac34e5a239) +Signed-off-by: Peter Xu +--- + migration/migration.c | 3 ++- + migration/ram.c | 13 +++++++------ + migration/ram.h | 2 +- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 8f2847d298..8fca751050 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1148,7 +1148,8 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram->normal = stat64_get(&ram_counters.normal); + info->ram->normal_bytes = info->ram->normal * page_size; + info->ram->mbps = s->mbps; +- info->ram->dirty_sync_count = ram_counters.dirty_sync_count; ++ info->ram->dirty_sync_count = ++ stat64_get(&ram_counters.dirty_sync_count); + info->ram->dirty_sync_missed_zero_copy = + stat64_get(&ram_counters.dirty_sync_missed_zero_copy); + info->ram->postcopy_requests = ram_counters.postcopy_requests; +diff --git a/migration/ram.c b/migration/ram.c +index b1722b6071..3c13136559 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -764,7 +764,7 @@ static void xbzrle_cache_zero_page(RAMState *rs, ram_addr_t current_addr) + /* We don't care if this fails to allocate a new cache page + * as long as it updated an old one */ + cache_insert(XBZRLE.cache, current_addr, XBZRLE.zero_target_page, +- ram_counters.dirty_sync_count); ++ stat64_get(&ram_counters.dirty_sync_count)); + } + + #define ENCODING_FLAG_XBZRLE 0x1 +@@ -790,13 +790,13 @@ static int save_xbzrle_page(RAMState *rs, PageSearchStatus *pss, + int encoded_len = 0, bytes_xbzrle; + uint8_t *prev_cached_page; + QEMUFile *file = pss->pss_channel; ++ uint64_t generation = stat64_get(&ram_counters.dirty_sync_count); + +- if (!cache_is_cached(XBZRLE.cache, current_addr, +- ram_counters.dirty_sync_count)) { ++ if (!cache_is_cached(XBZRLE.cache, current_addr, generation)) { + xbzrle_counters.cache_miss++; + if (!rs->last_stage) { + if (cache_insert(XBZRLE.cache, current_addr, *current_data, +- ram_counters.dirty_sync_count) == -1) { ++ generation) == -1) { + return -1; + } else { + /* update *current_data when the page has been +@@ -1209,7 +1209,7 @@ static void migration_bitmap_sync(RAMState *rs) + RAMBlock *block; + int64_t end_time; + +- ram_counters.dirty_sync_count++; ++ stat64_add(&ram_counters.dirty_sync_count, 1); + + if (!rs->time_last_bitmap_sync) { + rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); +@@ -1246,7 +1246,8 @@ static void migration_bitmap_sync(RAMState *rs) + rs->bytes_xfer_prev = stat64_get(&ram_counters.transferred); + } + if (migrate_use_events()) { +- qapi_event_send_migration_pass(ram_counters.dirty_sync_count); ++ uint64_t generation = stat64_get(&ram_counters.dirty_sync_count); ++ qapi_event_send_migration_pass(generation); + } + } + +diff --git a/migration/ram.h b/migration/ram.h +index bb52632424..8c0d07c43a 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -42,7 +42,7 @@ + */ + typedef struct { + int64_t dirty_pages_rate; +- int64_t dirty_sync_count; ++ Stat64 dirty_sync_count; + Stat64 dirty_sync_missed_zero_copy; + Stat64 downtime_bytes; + Stat64 duplicate; +-- +2.39.1 + diff --git a/kvm-migration-Make-dirty_sync_missed_zero_copy-atomic.patch b/kvm-migration-Make-dirty_sync_missed_zero_copy-atomic.patch new file mode 100644 index 0000000..b7b0f60 --- /dev/null +++ b/kvm-migration-Make-dirty_sync_missed_zero_copy-atomic.patch @@ -0,0 +1,92 @@ +From e9ff20d7f7e6c2354f3696e8bca265e535eeb801 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Tue, 11 Apr 2023 17:33:56 +0200 +Subject: [PATCH 11/56] migration: Make dirty_sync_missed_zero_copy atomic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [10/50] 041230abb087db0e7ffae02b4f85772490b805a0 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +(cherry picked from commit 4291823694fd8507831d26e2558d9cd0030841f7) +Signed-off-by: Peter Xu +--- + migration/migration.c | 2 +- + migration/multifd.c | 2 +- + migration/ram.c | 5 ----- + migration/ram.h | 4 +--- + 4 files changed, 3 insertions(+), 10 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index ca68808b5c..645fb4b3c5 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1150,7 +1150,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram->mbps = s->mbps; + info->ram->dirty_sync_count = ram_counters.dirty_sync_count; + info->ram->dirty_sync_missed_zero_copy = +- ram_counters.dirty_sync_missed_zero_copy; ++ stat64_get(&ram_counters.dirty_sync_missed_zero_copy); + info->ram->postcopy_requests = ram_counters.postcopy_requests; + info->ram->page_size = page_size; + info->ram->multifd_bytes = stat64_get(&ram_counters.multifd_bytes); +diff --git a/migration/multifd.c b/migration/multifd.c +index 1c992abf53..903df2117b 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -576,7 +576,7 @@ static int multifd_zero_copy_flush(QIOChannel *c) + return -1; + } + if (ret == 1) { +- dirty_sync_missed_zero_copy(); ++ stat64_add(&ram_counters.dirty_sync_missed_zero_copy, 1); + } + + return ret; +diff --git a/migration/ram.c b/migration/ram.c +index 71320ed27a..93e0a48af4 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -472,11 +472,6 @@ void ram_transferred_add(uint64_t bytes) + stat64_add(&ram_counters.transferred, bytes); + } + +-void dirty_sync_missed_zero_copy(void) +-{ +- ram_counters.dirty_sync_missed_zero_copy++; +-} +- + struct MigrationOps { + int (*ram_save_target_page)(RAMState *rs, PageSearchStatus *pss); + }; +diff --git a/migration/ram.h b/migration/ram.h +index ed70391317..2170c55e67 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -43,7 +43,7 @@ + typedef struct { + int64_t dirty_pages_rate; + int64_t dirty_sync_count; +- uint64_t dirty_sync_missed_zero_copy; ++ Stat64 dirty_sync_missed_zero_copy; + uint64_t downtime_bytes; + Stat64 duplicate; + Stat64 multifd_bytes; +@@ -114,6 +114,4 @@ void ram_write_tracking_prepare(void); + int ram_write_tracking_start(void); + void ram_write_tracking_stop(void); + +-void dirty_sync_missed_zero_copy(void); +- + #endif +-- +2.39.1 + diff --git a/kvm-migration-Make-downtime_bytes-atomic.patch b/kvm-migration-Make-downtime_bytes-atomic.patch new file mode 100644 index 0000000..9b206bc --- /dev/null +++ b/kvm-migration-Make-downtime_bytes-atomic.patch @@ -0,0 +1,68 @@ +From 4c6af064277b5445b31db4a598e1c4402ba56452 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Tue, 11 Apr 2023 17:38:11 +0200 +Subject: [PATCH 13/56] migration: Make downtime_bytes atomic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [12/50] ebfc16aae8bc4a8c1fec431780a062950e6f50c4 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +(cherry picked from commit 296a4ac2aa63038b6b702f2ee8f0f93ae26727ae) +Signed-off-by: Peter Xu +--- + migration/migration.c | 2 +- + migration/ram.c | 2 +- + migration/ram.h | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 3a68d93d69..8f2847d298 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1156,7 +1156,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram->multifd_bytes = stat64_get(&ram_counters.multifd_bytes); + info->ram->pages_per_second = s->pages_per_second; + info->ram->precopy_bytes = stat64_get(&ram_counters.precopy_bytes); +- info->ram->downtime_bytes = ram_counters.downtime_bytes; ++ info->ram->downtime_bytes = stat64_get(&ram_counters.downtime_bytes); + info->ram->postcopy_bytes = stat64_get(&ram_counters.postcopy_bytes); + + if (migrate_use_xbzrle()) { +diff --git a/migration/ram.c b/migration/ram.c +index 0b4693215e..b1722b6071 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -467,7 +467,7 @@ void ram_transferred_add(uint64_t bytes) + } else if (migration_in_postcopy()) { + stat64_add(&ram_counters.postcopy_bytes, bytes); + } else { +- ram_counters.downtime_bytes += bytes; ++ stat64_add(&ram_counters.downtime_bytes, bytes); + } + stat64_add(&ram_counters.transferred, bytes); + } +diff --git a/migration/ram.h b/migration/ram.h +index a766b895fa..bb52632424 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -44,7 +44,7 @@ typedef struct { + int64_t dirty_pages_rate; + int64_t dirty_sync_count; + Stat64 dirty_sync_missed_zero_copy; +- uint64_t downtime_bytes; ++ Stat64 downtime_bytes; + Stat64 duplicate; + Stat64 multifd_bytes; + Stat64 normal; +-- +2.39.1 + diff --git a/kvm-migration-Make-multifd_bytes-atomic.patch b/kvm-migration-Make-multifd_bytes-atomic.patch new file mode 100644 index 0000000..b315fdc --- /dev/null +++ b/kvm-migration-Make-multifd_bytes-atomic.patch @@ -0,0 +1,99 @@ +From bfcc4bc8f60b541d545f1ea27b1ff156d8092d33 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 23 Nov 2022 20:36:56 +0100 +Subject: [PATCH 10/56] migration: Make multifd_bytes atomic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [9/50] c2bc6b173770a0ea81c3f9d850c583c651647070 (peterx/qemu-kvm) + +In the spirit of: + +commit 394d323bc3451e4d07f13341cb8817fac8dfbadd +Author: Peter Xu +Date: Tue Oct 11 17:55:51 2022 -0400 + + migration: Use atomic ops properly for page accountings + +Reviewed-by: David Edmondson +Reviewed-by: Peter Xu +Signed-off-by: Juan Quintela +(cherry picked from commit cf671116facf4e29d91fce9c9ffb535385ffac81) +Signed-off-by: Peter Xu +--- + migration/migration.c | 4 ++-- + migration/multifd.c | 4 ++-- + migration/ram.h | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index a91704d35c..ca68808b5c 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1153,7 +1153,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + ram_counters.dirty_sync_missed_zero_copy; + info->ram->postcopy_requests = ram_counters.postcopy_requests; + info->ram->page_size = page_size; +- info->ram->multifd_bytes = ram_counters.multifd_bytes; ++ info->ram->multifd_bytes = stat64_get(&ram_counters.multifd_bytes); + info->ram->pages_per_second = s->pages_per_second; + info->ram->precopy_bytes = ram_counters.precopy_bytes; + info->ram->downtime_bytes = ram_counters.downtime_bytes; +@@ -3780,7 +3780,7 @@ static MigThrError migration_detect_error(MigrationState *s) + static uint64_t migration_total_bytes(MigrationState *s) + { + return qemu_file_total_transferred(s->to_dst_file) + +- ram_counters.multifd_bytes; ++ stat64_get(&ram_counters.multifd_bytes); + } + + static void migration_calculate_complete(MigrationState *s) +diff --git a/migration/multifd.c b/migration/multifd.c +index 6ef3a27938..1c992abf53 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -432,9 +432,9 @@ static int multifd_send_pages(QEMUFile *f) + p->pages = pages; + transferred = ((uint64_t) pages->num) * p->page_size + p->packet_len; + qemu_file_acct_rate_limit(f, transferred); +- ram_counters.multifd_bytes += transferred; + qemu_mutex_unlock(&p->mutex); + stat64_add(&ram_counters.transferred, transferred); ++ stat64_add(&ram_counters.multifd_bytes, transferred); + qemu_sem_post(&p->sem); + + return 1; +@@ -627,9 +627,9 @@ int multifd_send_sync_main(QEMUFile *f) + p->flags |= MULTIFD_FLAG_SYNC; + p->pending_job++; + qemu_file_acct_rate_limit(f, p->packet_len); +- ram_counters.multifd_bytes += p->packet_len; + qemu_mutex_unlock(&p->mutex); + stat64_add(&ram_counters.transferred, p->packet_len); ++ stat64_add(&ram_counters.multifd_bytes, p->packet_len); + qemu_sem_post(&p->sem); + } + for (i = 0; i < migrate_multifd_channels(); i++) { +diff --git a/migration/ram.h b/migration/ram.h +index 7c026b5242..ed70391317 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -46,7 +46,7 @@ typedef struct { + uint64_t dirty_sync_missed_zero_copy; + uint64_t downtime_bytes; + Stat64 duplicate; +- uint64_t multifd_bytes; ++ Stat64 multifd_bytes; + Stat64 normal; + Stat64 postcopy_bytes; + int64_t postcopy_requests; +-- +2.39.1 + diff --git a/kvm-migration-Make-postcopy_requests-atomic.patch b/kvm-migration-Make-postcopy_requests-atomic.patch new file mode 100644 index 0000000..894419a --- /dev/null +++ b/kvm-migration-Make-postcopy_requests-atomic.patch @@ -0,0 +1,69 @@ +From e6ff4536a5e5f5bbfda370ecb525d0e066c3ab1c Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Tue, 11 Apr 2023 18:04:59 +0200 +Subject: [PATCH 15/56] migration: Make postcopy_requests atomic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [14/50] d15c6052b77e7ded7bf34c66caa11bf86b75f2e8 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +(cherry picked from commit 3c764f9b2bc3e5eb5ed93ab45c2de6d599fef00f) +Signed-off-by: Peter Xu +--- + migration/migration.c | 3 ++- + migration/ram.c | 2 +- + migration/ram.h | 2 +- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 8fca751050..39501a0ed8 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1152,7 +1152,8 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + stat64_get(&ram_counters.dirty_sync_count); + info->ram->dirty_sync_missed_zero_copy = + stat64_get(&ram_counters.dirty_sync_missed_zero_copy); +- info->ram->postcopy_requests = ram_counters.postcopy_requests; ++ info->ram->postcopy_requests = ++ stat64_get(&ram_counters.postcopy_requests); + info->ram->page_size = page_size; + info->ram->multifd_bytes = stat64_get(&ram_counters.multifd_bytes); + info->ram->pages_per_second = s->pages_per_second; +diff --git a/migration/ram.c b/migration/ram.c +index 3c13136559..fe69ecaef4 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -2169,7 +2169,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len) + RAMBlock *ramblock; + RAMState *rs = ram_state; + +- ram_counters.postcopy_requests++; ++ stat64_add(&ram_counters.postcopy_requests, 1); + RCU_READ_LOCK_GUARD(); + + if (!rbname) { +diff --git a/migration/ram.h b/migration/ram.h +index 8c0d07c43a..afa68521d7 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -49,7 +49,7 @@ typedef struct { + Stat64 multifd_bytes; + Stat64 normal; + Stat64 postcopy_bytes; +- int64_t postcopy_requests; ++ Stat64 postcopy_requests; + Stat64 precopy_bytes; + int64_t remaining; + Stat64 transferred; +-- +2.39.1 + diff --git a/kvm-migration-Make-precopy_bytes-atomic.patch b/kvm-migration-Make-precopy_bytes-atomic.patch new file mode 100644 index 0000000..8e6c177 --- /dev/null +++ b/kvm-migration-Make-precopy_bytes-atomic.patch @@ -0,0 +1,68 @@ +From 7e4d4316855f7f6556364eb16828f925b61c80d4 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Tue, 11 Apr 2023 17:36:48 +0200 +Subject: [PATCH 12/56] migration: Make precopy_bytes atomic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [11/50] 23bec49b4b8f4d23c2192b401416139e3ca13626 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +(cherry picked from commit b013b5d1f32ef88457e66c7ce576f6475238f97f) +Signed-off-by: Peter Xu +--- + migration/migration.c | 2 +- + migration/ram.c | 2 +- + migration/ram.h | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 645fb4b3c5..3a68d93d69 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1155,7 +1155,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram->page_size = page_size; + info->ram->multifd_bytes = stat64_get(&ram_counters.multifd_bytes); + info->ram->pages_per_second = s->pages_per_second; +- info->ram->precopy_bytes = ram_counters.precopy_bytes; ++ info->ram->precopy_bytes = stat64_get(&ram_counters.precopy_bytes); + info->ram->downtime_bytes = ram_counters.downtime_bytes; + info->ram->postcopy_bytes = stat64_get(&ram_counters.postcopy_bytes); + +diff --git a/migration/ram.c b/migration/ram.c +index 93e0a48af4..0b4693215e 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -463,7 +463,7 @@ RAMStats ram_counters; + void ram_transferred_add(uint64_t bytes) + { + if (runstate_is_running()) { +- ram_counters.precopy_bytes += bytes; ++ stat64_add(&ram_counters.precopy_bytes, bytes); + } else if (migration_in_postcopy()) { + stat64_add(&ram_counters.postcopy_bytes, bytes); + } else { +diff --git a/migration/ram.h b/migration/ram.h +index 2170c55e67..a766b895fa 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -50,7 +50,7 @@ typedef struct { + Stat64 normal; + Stat64 postcopy_bytes; + int64_t postcopy_requests; +- uint64_t precopy_bytes; ++ Stat64 precopy_bytes; + int64_t remaining; + Stat64 transferred; + } RAMStats; +-- +2.39.1 + diff --git a/kvm-migration-Merge-ram_counters-and-ram_atomic_counters.patch b/kvm-migration-Merge-ram_counters-and-ram_atomic_counters.patch new file mode 100644 index 0000000..0679e89 --- /dev/null +++ b/kvm-migration-Merge-ram_counters-and-ram_atomic_counters.patch @@ -0,0 +1,270 @@ +From 5a87058eea6ee56f37fb454486c35baaf693d691 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 22 Feb 2023 15:56:45 +0100 +Subject: [PATCH 08/56] migration: Merge ram_counters and ram_atomic_counters +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [7/50] 90e395de66aa32b886cf151f7996a680190471f5 (peterx/qemu-kvm) + +Using MgrationStats as type for ram_counters mean that we didn't have +to re-declare each value in another struct. The need of atomic +counters have make us to create MigrationAtomicStats for this atomic +counters. + +Create RAMStats type which is a merge of MigrationStats and +MigrationAtomicStats removing unused members. + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu + +--- + +Fix typos found by David Edmondson + +(cherry picked from commit abce5fa16d126ed085ccf8a5b3fe61a1efa20994) +Signed-off-by: Peter Xu +--- + migration/migration.c | 8 ++++---- + migration/multifd.c | 4 ++-- + migration/ram.c | 39 ++++++++++++++++----------------------- + migration/ram.h | 28 +++++++++++++++------------- + 4 files changed, 37 insertions(+), 42 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 99f86bd6c2..a91704d35c 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1140,12 +1140,12 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + size_t page_size = qemu_target_page_size(); + + info->ram = g_malloc0(sizeof(*info->ram)); +- info->ram->transferred = stat64_get(&ram_atomic_counters.transferred); ++ info->ram->transferred = stat64_get(&ram_counters.transferred); + info->ram->total = ram_bytes_total(); +- info->ram->duplicate = stat64_get(&ram_atomic_counters.duplicate); ++ info->ram->duplicate = stat64_get(&ram_counters.duplicate); + /* legacy value. It is not used anymore */ + info->ram->skipped = 0; +- info->ram->normal = stat64_get(&ram_atomic_counters.normal); ++ info->ram->normal = stat64_get(&ram_counters.normal); + info->ram->normal_bytes = info->ram->normal * page_size; + info->ram->mbps = s->mbps; + info->ram->dirty_sync_count = ram_counters.dirty_sync_count; +@@ -1157,7 +1157,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram->pages_per_second = s->pages_per_second; + info->ram->precopy_bytes = ram_counters.precopy_bytes; + info->ram->downtime_bytes = ram_counters.downtime_bytes; +- info->ram->postcopy_bytes = stat64_get(&ram_atomic_counters.postcopy_bytes); ++ info->ram->postcopy_bytes = stat64_get(&ram_counters.postcopy_bytes); + + if (migrate_use_xbzrle()) { + info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache)); +diff --git a/migration/multifd.c b/migration/multifd.c +index cbc0dfe39b..01fab01a92 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -433,7 +433,7 @@ static int multifd_send_pages(QEMUFile *f) + transferred = ((uint64_t) pages->num) * p->page_size + p->packet_len; + qemu_file_acct_rate_limit(f, transferred); + ram_counters.multifd_bytes += transferred; +- stat64_add(&ram_atomic_counters.transferred, transferred); ++ stat64_add(&ram_counters.transferred, transferred); + qemu_mutex_unlock(&p->mutex); + qemu_sem_post(&p->sem); + +@@ -628,7 +628,7 @@ int multifd_send_sync_main(QEMUFile *f) + p->pending_job++; + qemu_file_acct_rate_limit(f, p->packet_len); + ram_counters.multifd_bytes += p->packet_len; +- stat64_add(&ram_atomic_counters.transferred, p->packet_len); ++ stat64_add(&ram_counters.transferred, p->packet_len); + qemu_mutex_unlock(&p->mutex); + qemu_sem_post(&p->sem); + } +diff --git a/migration/ram.c b/migration/ram.c +index 0e68099bf9..71320ed27a 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -458,25 +458,18 @@ uint64_t ram_bytes_remaining(void) + 0; + } + +-/* +- * NOTE: not all stats in ram_counters are used in reality. See comments +- * for struct MigrationAtomicStats. The ultimate result of ram migration +- * counters will be a merged version with both ram_counters and the atomic +- * fields in ram_atomic_counters. +- */ +-MigrationStats ram_counters; +-MigrationAtomicStats ram_atomic_counters; ++RAMStats ram_counters; + + void ram_transferred_add(uint64_t bytes) + { + if (runstate_is_running()) { + ram_counters.precopy_bytes += bytes; + } else if (migration_in_postcopy()) { +- stat64_add(&ram_atomic_counters.postcopy_bytes, bytes); ++ stat64_add(&ram_counters.postcopy_bytes, bytes); + } else { + ram_counters.downtime_bytes += bytes; + } +- stat64_add(&ram_atomic_counters.transferred, bytes); ++ stat64_add(&ram_counters.transferred, bytes); + } + + void dirty_sync_missed_zero_copy(void) +@@ -756,7 +749,7 @@ void mig_throttle_counter_reset(void) + + rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + rs->num_dirty_pages_period = 0; +- rs->bytes_xfer_prev = stat64_get(&ram_atomic_counters.transferred); ++ rs->bytes_xfer_prev = stat64_get(&ram_counters.transferred); + } + + /** +@@ -1130,8 +1123,8 @@ uint64_t ram_pagesize_summary(void) + + uint64_t ram_get_total_transferred_pages(void) + { +- return stat64_get(&ram_atomic_counters.normal) + +- stat64_get(&ram_atomic_counters.duplicate) + ++ return stat64_get(&ram_counters.normal) + ++ stat64_get(&ram_counters.duplicate) + + compression_counters.pages + xbzrle_counters.pages; + } + +@@ -1192,7 +1185,7 @@ static void migration_trigger_throttle(RAMState *rs) + MigrationState *s = migrate_get_current(); + uint64_t threshold = s->parameters.throttle_trigger_threshold; + uint64_t bytes_xfer_period = +- stat64_get(&ram_atomic_counters.transferred) - rs->bytes_xfer_prev; ++ stat64_get(&ram_counters.transferred) - rs->bytes_xfer_prev; + uint64_t bytes_dirty_period = rs->num_dirty_pages_period * TARGET_PAGE_SIZE; + uint64_t bytes_dirty_threshold = bytes_xfer_period * threshold / 100; + +@@ -1255,7 +1248,7 @@ static void migration_bitmap_sync(RAMState *rs) + /* reset period counters */ + rs->time_last_bitmap_sync = end_time; + rs->num_dirty_pages_period = 0; +- rs->bytes_xfer_prev = stat64_get(&ram_atomic_counters.transferred); ++ rs->bytes_xfer_prev = stat64_get(&ram_counters.transferred); + } + if (migrate_use_events()) { + qapi_event_send_migration_pass(ram_counters.dirty_sync_count); +@@ -1331,7 +1324,7 @@ static int save_zero_page(PageSearchStatus *pss, QEMUFile *f, RAMBlock *block, + int len = save_zero_page_to_file(pss, f, block, offset); + + if (len) { +- stat64_add(&ram_atomic_counters.duplicate, 1); ++ stat64_add(&ram_counters.duplicate, 1); + ram_transferred_add(len); + return 1; + } +@@ -1368,9 +1361,9 @@ static bool control_save_page(PageSearchStatus *pss, RAMBlock *block, + } + + if (bytes_xmit > 0) { +- stat64_add(&ram_atomic_counters.normal, 1); ++ stat64_add(&ram_counters.normal, 1); + } else if (bytes_xmit == 0) { +- stat64_add(&ram_atomic_counters.duplicate, 1); ++ stat64_add(&ram_counters.duplicate, 1); + } + + return true; +@@ -1402,7 +1395,7 @@ static int save_normal_page(PageSearchStatus *pss, RAMBlock *block, + qemu_put_buffer(file, buf, TARGET_PAGE_SIZE); + } + ram_transferred_add(TARGET_PAGE_SIZE); +- stat64_add(&ram_atomic_counters.normal, 1); ++ stat64_add(&ram_counters.normal, 1); + return 1; + } + +@@ -1458,7 +1451,7 @@ static int ram_save_multifd_page(QEMUFile *file, RAMBlock *block, + if (multifd_queue_page(file, block, offset) < 0) { + return -1; + } +- stat64_add(&ram_atomic_counters.normal, 1); ++ stat64_add(&ram_counters.normal, 1); + + return 1; + } +@@ -1497,7 +1490,7 @@ update_compress_thread_counts(const CompressParam *param, int bytes_xmit) + ram_transferred_add(bytes_xmit); + + if (param->zero_page) { +- stat64_add(&ram_atomic_counters.duplicate, 1); ++ stat64_add(&ram_counters.duplicate, 1); + return; + } + +@@ -2632,9 +2625,9 @@ void acct_update_position(QEMUFile *f, size_t size, bool zero) + uint64_t pages = size / TARGET_PAGE_SIZE; + + if (zero) { +- stat64_add(&ram_atomic_counters.duplicate, pages); ++ stat64_add(&ram_counters.duplicate, pages); + } else { +- stat64_add(&ram_atomic_counters.normal, pages); ++ stat64_add(&ram_counters.normal, pages); + ram_transferred_add(size); + qemu_file_credit_transfer(f, size); + } +diff --git a/migration/ram.h b/migration/ram.h +index 81cbb0947c..7c026b5242 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -35,25 +35,27 @@ + #include "qemu/stats64.h" + + /* +- * These are the migration statistic counters that need to be updated using +- * atomic ops (can be accessed by more than one thread). Here since we +- * cannot modify MigrationStats directly to use Stat64 as it was defined in +- * the QAPI scheme, we define an internal structure to hold them, and we +- * propagate the real values when QMP queries happen. +- * +- * IOW, the corresponding fields within ram_counters on these specific +- * fields will be always zero and not being used at all; they're just +- * placeholders to make it QAPI-compatible. ++ * These are the ram migration statistic counters. It is loosely ++ * based on MigrationStats. We change to Stat64 any counter that ++ * needs to be updated using atomic ops (can be accessed by more than ++ * one thread). + */ + typedef struct { +- Stat64 transferred; ++ int64_t dirty_pages_rate; ++ int64_t dirty_sync_count; ++ uint64_t dirty_sync_missed_zero_copy; ++ uint64_t downtime_bytes; + Stat64 duplicate; ++ uint64_t multifd_bytes; + Stat64 normal; + Stat64 postcopy_bytes; +-} MigrationAtomicStats; ++ int64_t postcopy_requests; ++ uint64_t precopy_bytes; ++ int64_t remaining; ++ Stat64 transferred; ++} RAMStats; + +-extern MigrationAtomicStats ram_atomic_counters; +-extern MigrationStats ram_counters; ++extern RAMStats ram_counters; + extern XBZRLECacheStats xbzrle_counters; + extern CompressionStats compression_counters; + +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_announce_params-to-option.c.patch b/kvm-migration-Move-migrate_announce_params-to-option.c.patch new file mode 100644 index 0000000..24dcb16 --- /dev/null +++ b/kvm-migration-Move-migrate_announce_params-to-option.c.patch @@ -0,0 +1,90 @@ +From 1f5232d611ecaaf61bcac151e7d90b8b452ac161 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 01:17:23 +0100 +Subject: [PATCH 43/56] migration: Move migrate_announce_params() to option.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [42/50] 541be7adc7f81c269058485aef5b14e787b2efe6 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas + +--- + +Fix extra whitespace (fabiano) + +(cherry picked from commit 2682c4eea72c621dfd0fb0151cbd758e81d1bdff) +Signed-off-by: Peter Xu +--- + migration/migration.c | 14 -------------- + migration/options.c | 17 +++++++++++++++++ + 2 files changed, 17 insertions(+), 14 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 724e841eb9..f27ce30be2 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -954,20 +954,6 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) + return params; + } + +-AnnounceParameters *migrate_announce_params(void) +-{ +- static AnnounceParameters ap; +- +- MigrationState *s = migrate_get_current(); +- +- ap.initial = s->parameters.announce_initial; +- ap.max = s->parameters.announce_max; +- ap.rounds = s->parameters.announce_rounds; +- ap.step = s->parameters.announce_step; +- +- return ≈ +-} +- + /* + * Return true if we're already in the middle of a migration + * (i.e. any of the active or setup states) +diff --git a/migration/options.c b/migration/options.c +index 2cb04fbbd1..418aafac64 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -16,6 +16,7 @@ + #include "qapi/qapi-commands-migration.h" + #include "qapi/qmp/qerror.h" + #include "sysemu/runstate.h" ++#include "migration/misc.h" + #include "migration.h" + #include "ram.h" + #include "options.h" +@@ -589,3 +590,19 @@ uint64_t migrate_xbzrle_cache_size(void) + + return s->parameters.xbzrle_cache_size; + } ++ ++/* parameters helpers */ ++ ++AnnounceParameters *migrate_announce_params(void) ++{ ++ static AnnounceParameters ap; ++ ++ MigrationState *s = migrate_get_current(); ++ ++ ap.initial = s->parameters.announce_initial; ++ ap.max = s->parameters.announce_max; ++ ap.rounds = s->parameters.announce_rounds; ++ ap.step = s->parameters.announce_step; ++ ++ return ≈ ++} +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_cap_set-to-options.c.patch b/kvm-migration-Move-migrate_cap_set-to-options.c.patch new file mode 100644 index 0000000..0e33c4c --- /dev/null +++ b/kvm-migration-Move-migrate_cap_set-to-options.c.patch @@ -0,0 +1,110 @@ +From 9c4f8d869f5bbdd07381f6baad2ed755b07d03f4 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 23:25:44 +0100 +Subject: [PATCH 36/56] migration: Move migrate_cap_set() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [35/50] d0cd6b8e9cf0534a56795d94c3da18622fa10ad7 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit f80196b772ddeeb07d3d80d5c8382cb5d1063fa2) +Signed-off-by: Peter Xu +--- + migration/migration.c | 20 -------------------- + migration/options.c | 21 +++++++++++++++++++++ + migration/options.h | 1 + + 3 files changed, 22 insertions(+), 20 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 369cd91796..880a51210e 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1666,26 +1666,6 @@ void migrate_set_state(int *state, int old_state, int new_state) + } + } + +-static bool migrate_cap_set(int cap, bool value, Error **errp) +-{ +- MigrationState *s = migrate_get_current(); +- bool new_caps[MIGRATION_CAPABILITY__MAX]; +- +- if (migration_is_running(s->state)) { +- error_setg(errp, QERR_MIGRATION_ACTIVE); +- return false; +- } +- +- memcpy(new_caps, s->capabilities, sizeof(new_caps)); +- new_caps[cap] = value; +- +- if (!migrate_caps_check(s->capabilities, new_caps, errp)) { +- return false; +- } +- s->capabilities[cap] = value; +- return true; +-} +- + static void migrate_set_block_incremental(MigrationState *s, bool value) + { + s->parameters.block_incremental = value; +diff --git a/migration/options.c b/migration/options.c +index 4cbe77e35a..f3b2d6e482 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -14,6 +14,7 @@ + #include "qemu/osdep.h" + #include "qapi/error.h" + #include "qapi/qapi-commands-migration.h" ++#include "qapi/qmp/qerror.h" + #include "sysemu/runstate.h" + #include "migration.h" + #include "ram.h" +@@ -392,6 +393,26 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) + return true; + } + ++bool migrate_cap_set(int cap, bool value, Error **errp) ++{ ++ MigrationState *s = migrate_get_current(); ++ bool new_caps[MIGRATION_CAPABILITY__MAX]; ++ ++ if (migration_is_running(s->state)) { ++ error_setg(errp, QERR_MIGRATION_ACTIVE); ++ return false; ++ } ++ ++ memcpy(new_caps, s->capabilities, sizeof(new_caps)); ++ new_caps[cap] = value; ++ ++ if (!migrate_caps_check(s->capabilities, new_caps, errp)) { ++ return false; ++ } ++ s->capabilities[cap] = value; ++ return true; ++} ++ + MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) + { + MigrationCapabilityStatusList *head = NULL, **tail = &head; +diff --git a/migration/options.h b/migration/options.h +index e779f14161..5979e4ff90 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -41,5 +41,6 @@ bool migrate_zero_copy_send(void); + /* capabilities helpers */ + + bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp); ++bool migrate_cap_set(int cap, bool value, Error **errp); + + #endif +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_caps_check-to-options.c.patch b/kvm-migration-Move-migrate_caps_check-to-options.c.patch new file mode 100644 index 0000000..0d6fa08 --- /dev/null +++ b/kvm-migration-Move-migrate_caps_check-to-options.c.patch @@ -0,0 +1,458 @@ +From 3af7c7aaf7407ec14c19e54d52a2229ce4dbb7c5 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 23:05:53 +0100 +Subject: [PATCH 33/56] migration: Move migrate_caps_check() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [32/50] 12999471063d97fffb2b04c6dcb80083b902f963 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 77608706459bd197e25ac1ef54591b9f8a0b46f8) +Signed-off-by: Peter Xu +--- + migration/migration.c | 190 ----------------------------------------- + migration/options.c | 192 ++++++++++++++++++++++++++++++++++++++++++ + migration/options.h | 4 + + 3 files changed, 196 insertions(+), 190 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index f7facecd66..d9e30ca918 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -136,39 +136,6 @@ enum mig_rp_message_type { + MIG_RP_MSG_MAX + }; + +-/* Migration capabilities set */ +-struct MigrateCapsSet { +- int size; /* Capability set size */ +- MigrationCapability caps[]; /* Variadic array of capabilities */ +-}; +-typedef struct MigrateCapsSet MigrateCapsSet; +- +-/* Define and initialize MigrateCapsSet */ +-#define INITIALIZE_MIGRATE_CAPS_SET(_name, ...) \ +- MigrateCapsSet _name = { \ +- .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \ +- .caps = { __VA_ARGS__ } \ +- } +- +-/* Background-snapshot compatibility check list */ +-static const +-INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot, +- MIGRATION_CAPABILITY_POSTCOPY_RAM, +- MIGRATION_CAPABILITY_DIRTY_BITMAPS, +- MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME, +- MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE, +- MIGRATION_CAPABILITY_RETURN_PATH, +- MIGRATION_CAPABILITY_MULTIFD, +- MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER, +- MIGRATION_CAPABILITY_AUTO_CONVERGE, +- MIGRATION_CAPABILITY_RELEASE_RAM, +- MIGRATION_CAPABILITY_RDMA_PIN_ALL, +- MIGRATION_CAPABILITY_COMPRESS, +- MIGRATION_CAPABILITY_XBZRLE, +- MIGRATION_CAPABILITY_X_COLO, +- MIGRATION_CAPABILITY_VALIDATE_UUID, +- MIGRATION_CAPABILITY_ZERO_COPY_SEND); +- + /* When we add fault tolerance, we could have several + migrations at once. For now we don't need to add + dynamic creation of migration */ +@@ -1235,163 +1202,6 @@ static void fill_source_migration_info(MigrationInfo *info) + info->status = state; + } + +-typedef enum WriteTrackingSupport { +- WT_SUPPORT_UNKNOWN = 0, +- WT_SUPPORT_ABSENT, +- WT_SUPPORT_AVAILABLE, +- WT_SUPPORT_COMPATIBLE +-} WriteTrackingSupport; +- +-static +-WriteTrackingSupport migrate_query_write_tracking(void) +-{ +- /* Check if kernel supports required UFFD features */ +- if (!ram_write_tracking_available()) { +- return WT_SUPPORT_ABSENT; +- } +- /* +- * Check if current memory configuration is +- * compatible with required UFFD features. +- */ +- if (!ram_write_tracking_compatible()) { +- return WT_SUPPORT_AVAILABLE; +- } +- +- return WT_SUPPORT_COMPATIBLE; +-} +- +-/** +- * @migration_caps_check - check capability compatibility +- * +- * @old_caps: old capability list +- * @new_caps: new capability list +- * @errp: set *errp if the check failed, with reason +- * +- * Returns true if check passed, otherwise false. +- */ +-static bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) +-{ +- MigrationIncomingState *mis = migration_incoming_get_current(); +- +-#ifndef CONFIG_LIVE_BLOCK_MIGRATION +- if (new_caps[MIGRATION_CAPABILITY_BLOCK]) { +- error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) " +- "block migration"); +- error_append_hint(errp, "Use drive_mirror+NBD instead.\n"); +- return false; +- } +-#endif +- +-#ifndef CONFIG_REPLICATION +- if (new_caps[MIGRATION_CAPABILITY_X_COLO]) { +- error_setg(errp, "QEMU compiled without replication module" +- " can't enable COLO"); +- error_append_hint(errp, "Please enable replication before COLO.\n"); +- return false; +- } +-#endif +- +- if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { +- /* This check is reasonably expensive, so only when it's being +- * set the first time, also it's only the destination that needs +- * special support. +- */ +- if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] && +- runstate_check(RUN_STATE_INMIGRATE) && +- !postcopy_ram_supported_by_host(mis)) { +- /* postcopy_ram_supported_by_host will have emitted a more +- * detailed message +- */ +- error_setg(errp, "Postcopy is not supported"); +- return false; +- } +- +- if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) { +- error_setg(errp, "Postcopy is not compatible with ignore-shared"); +- return false; +- } +- } +- +- if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { +- WriteTrackingSupport wt_support; +- int idx; +- /* +- * Check if 'background-snapshot' capability is supported by +- * host kernel and compatible with guest memory configuration. +- */ +- wt_support = migrate_query_write_tracking(); +- if (wt_support < WT_SUPPORT_AVAILABLE) { +- error_setg(errp, "Background-snapshot is not supported by host kernel"); +- return false; +- } +- if (wt_support < WT_SUPPORT_COMPATIBLE) { +- error_setg(errp, "Background-snapshot is not compatible " +- "with guest memory configuration"); +- return false; +- } +- +- /* +- * Check if there are any migration capabilities +- * incompatible with 'background-snapshot'. +- */ +- for (idx = 0; idx < check_caps_background_snapshot.size; idx++) { +- int incomp_cap = check_caps_background_snapshot.caps[idx]; +- if (new_caps[incomp_cap]) { +- error_setg(errp, +- "Background-snapshot is not compatible with %s", +- MigrationCapability_str(incomp_cap)); +- return false; +- } +- } +- } +- +-#ifdef CONFIG_LINUX +- if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] && +- (!new_caps[MIGRATION_CAPABILITY_MULTIFD] || +- new_caps[MIGRATION_CAPABILITY_COMPRESS] || +- new_caps[MIGRATION_CAPABILITY_XBZRLE] || +- migrate_multifd_compression() || +- migrate_use_tls())) { +- error_setg(errp, +- "Zero copy only available for non-compressed non-TLS multifd migration"); +- return false; +- } +-#else +- if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) { +- error_setg(errp, +- "Zero copy currently only available on Linux"); +- return false; +- } +-#endif +- +- if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) { +- if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { +- error_setg(errp, "Postcopy preempt requires postcopy-ram"); +- return false; +- } +- +- /* +- * Preempt mode requires urgent pages to be sent in separate +- * channel, OTOH compression logic will disorder all pages into +- * different compression channels, which is not compatible with the +- * preempt assumptions on channel assignments. +- */ +- if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { +- error_setg(errp, "Postcopy preempt not compatible with compress"); +- return false; +- } +- } +- +- if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { +- if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { +- error_setg(errp, "Multifd is not compatible with compress"); +- return false; +- } +- } +- +- return true; +-} +- + static void fill_destination_migration_info(MigrationInfo *info) + { + MigrationIncomingState *mis = migration_incoming_get_current(); +diff --git a/migration/options.c b/migration/options.c +index 9c9b8e5863..367c930f46 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -12,7 +12,10 @@ + */ + + #include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "sysemu/runstate.h" + #include "migration.h" ++#include "ram.h" + #include "options.h" + + bool migrate_auto_converge(void) +@@ -198,3 +201,192 @@ bool migrate_zero_copy_send(void) + + return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; + } ++typedef enum WriteTrackingSupport { ++ WT_SUPPORT_UNKNOWN = 0, ++ WT_SUPPORT_ABSENT, ++ WT_SUPPORT_AVAILABLE, ++ WT_SUPPORT_COMPATIBLE ++} WriteTrackingSupport; ++ ++static ++WriteTrackingSupport migrate_query_write_tracking(void) ++{ ++ /* Check if kernel supports required UFFD features */ ++ if (!ram_write_tracking_available()) { ++ return WT_SUPPORT_ABSENT; ++ } ++ /* ++ * Check if current memory configuration is ++ * compatible with required UFFD features. ++ */ ++ if (!ram_write_tracking_compatible()) { ++ return WT_SUPPORT_AVAILABLE; ++ } ++ ++ return WT_SUPPORT_COMPATIBLE; ++} ++ ++/* Migration capabilities set */ ++struct MigrateCapsSet { ++ int size; /* Capability set size */ ++ MigrationCapability caps[]; /* Variadic array of capabilities */ ++}; ++typedef struct MigrateCapsSet MigrateCapsSet; ++ ++/* Define and initialize MigrateCapsSet */ ++#define INITIALIZE_MIGRATE_CAPS_SET(_name, ...) \ ++ MigrateCapsSet _name = { \ ++ .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \ ++ .caps = { __VA_ARGS__ } \ ++ } ++ ++/* Background-snapshot compatibility check list */ ++static const ++INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot, ++ MIGRATION_CAPABILITY_POSTCOPY_RAM, ++ MIGRATION_CAPABILITY_DIRTY_BITMAPS, ++ MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME, ++ MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE, ++ MIGRATION_CAPABILITY_RETURN_PATH, ++ MIGRATION_CAPABILITY_MULTIFD, ++ MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER, ++ MIGRATION_CAPABILITY_AUTO_CONVERGE, ++ MIGRATION_CAPABILITY_RELEASE_RAM, ++ MIGRATION_CAPABILITY_RDMA_PIN_ALL, ++ MIGRATION_CAPABILITY_COMPRESS, ++ MIGRATION_CAPABILITY_XBZRLE, ++ MIGRATION_CAPABILITY_X_COLO, ++ MIGRATION_CAPABILITY_VALIDATE_UUID, ++ MIGRATION_CAPABILITY_ZERO_COPY_SEND); ++ ++/** ++ * @migration_caps_check - check capability compatibility ++ * ++ * @old_caps: old capability list ++ * @new_caps: new capability list ++ * @errp: set *errp if the check failed, with reason ++ * ++ * Returns true if check passed, otherwise false. ++ */ ++bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) ++{ ++ MigrationIncomingState *mis = migration_incoming_get_current(); ++ ++#ifndef CONFIG_LIVE_BLOCK_MIGRATION ++ if (new_caps[MIGRATION_CAPABILITY_BLOCK]) { ++ error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) " ++ "block migration"); ++ error_append_hint(errp, "Use drive_mirror+NBD instead.\n"); ++ return false; ++ } ++#endif ++ ++#ifndef CONFIG_REPLICATION ++ if (new_caps[MIGRATION_CAPABILITY_X_COLO]) { ++ error_setg(errp, "QEMU compiled without replication module" ++ " can't enable COLO"); ++ error_append_hint(errp, "Please enable replication before COLO.\n"); ++ return false; ++ } ++#endif ++ ++ if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { ++ /* This check is reasonably expensive, so only when it's being ++ * set the first time, also it's only the destination that needs ++ * special support. ++ */ ++ if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] && ++ runstate_check(RUN_STATE_INMIGRATE) && ++ !postcopy_ram_supported_by_host(mis)) { ++ /* postcopy_ram_supported_by_host will have emitted a more ++ * detailed message ++ */ ++ error_setg(errp, "Postcopy is not supported"); ++ return false; ++ } ++ ++ if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) { ++ error_setg(errp, "Postcopy is not compatible with ignore-shared"); ++ return false; ++ } ++ } ++ ++ if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { ++ WriteTrackingSupport wt_support; ++ int idx; ++ /* ++ * Check if 'background-snapshot' capability is supported by ++ * host kernel and compatible with guest memory configuration. ++ */ ++ wt_support = migrate_query_write_tracking(); ++ if (wt_support < WT_SUPPORT_AVAILABLE) { ++ error_setg(errp, "Background-snapshot is not supported by host kernel"); ++ return false; ++ } ++ if (wt_support < WT_SUPPORT_COMPATIBLE) { ++ error_setg(errp, "Background-snapshot is not compatible " ++ "with guest memory configuration"); ++ return false; ++ } ++ ++ /* ++ * Check if there are any migration capabilities ++ * incompatible with 'background-snapshot'. ++ */ ++ for (idx = 0; idx < check_caps_background_snapshot.size; idx++) { ++ int incomp_cap = check_caps_background_snapshot.caps[idx]; ++ if (new_caps[incomp_cap]) { ++ error_setg(errp, ++ "Background-snapshot is not compatible with %s", ++ MigrationCapability_str(incomp_cap)); ++ return false; ++ } ++ } ++ } ++ ++#ifdef CONFIG_LINUX ++ if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] && ++ (!new_caps[MIGRATION_CAPABILITY_MULTIFD] || ++ new_caps[MIGRATION_CAPABILITY_COMPRESS] || ++ new_caps[MIGRATION_CAPABILITY_XBZRLE] || ++ migrate_multifd_compression() || ++ migrate_use_tls())) { ++ error_setg(errp, ++ "Zero copy only available for non-compressed non-TLS multifd migration"); ++ return false; ++ } ++#else ++ if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) { ++ error_setg(errp, ++ "Zero copy currently only available on Linux"); ++ return false; ++ } ++#endif ++ ++ if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) { ++ if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { ++ error_setg(errp, "Postcopy preempt requires postcopy-ram"); ++ return false; ++ } ++ ++ /* ++ * Preempt mode requires urgent pages to be sent in separate ++ * channel, OTOH compression logic will disorder all pages into ++ * different compression channels, which is not compatible with the ++ * preempt assumptions on channel assignments. ++ */ ++ if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { ++ error_setg(errp, "Postcopy preempt not compatible with compress"); ++ return false; ++ } ++ } ++ ++ if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { ++ if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { ++ error_setg(errp, "Multifd is not compatible with compress"); ++ return false; ++ } ++ } ++ ++ return true; ++} +diff --git a/migration/options.h b/migration/options.h +index 25c002b37a..e779f14161 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -38,4 +38,8 @@ bool migrate_xbzrle(void); + bool migrate_zero_blocks(void); + bool migrate_zero_copy_send(void); + ++/* capabilities helpers */ ++ ++bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp); ++ + #endif +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_colo_enabled-to-options.c.patch b/kvm-migration-Move-migrate_colo_enabled-to-options.c.patch new file mode 100644 index 0000000..47c6f83 --- /dev/null +++ b/kvm-migration-Move-migrate_colo_enabled-to-options.c.patch @@ -0,0 +1,136 @@ +From 13da9060fa2dfc666cd6f4b9bc85b7cee0fef45e Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:00:16 +0100 +Subject: [PATCH 24/56] migration: Move migrate_colo_enabled() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [23/50] 4809b1091edee38bd222af41b6313133705785c7 (peterx/qemu-kvm) + +Once that we are there, we rename the function to migrate_colo() to be +consistent with all other capabilities. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 5e8046445575dc5879e63c5d07af893d174813d0) +Signed-off-by: Peter Xu +--- + migration/migration.c | 16 +++++----------- + migration/migration.h | 1 - + migration/options.c | 6 ++++++ + migration/options.h | 1 + + 4 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 66ea55be06..59ee0ef82b 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2411,7 +2411,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc, + } + + if (blk || blk_inc) { +- if (migrate_colo_enabled()) { ++ if (migrate_colo()) { + error_setg(errp, "No disk migration is required in COLO mode"); + return false; + } +@@ -3304,7 +3304,7 @@ static void migration_completion(MigrationState *s) + * have done so in order to remember to reactivate + * them if migration fails or is cancelled. + */ +- s->block_inactive = !migrate_colo_enabled(); ++ s->block_inactive = !migrate_colo(); + qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX); + ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false, + s->block_inactive); +@@ -3357,7 +3357,7 @@ static void migration_completion(MigrationState *s) + goto fail; + } + +- if (migrate_colo_enabled() && s->state == MIGRATION_STATUS_ACTIVE) { ++ if (migrate_colo() && s->state == MIGRATION_STATUS_ACTIVE) { + /* COLO does not support postcopy */ + migrate_set_state(&s->state, MIGRATION_STATUS_ACTIVE, + MIGRATION_STATUS_COLO); +@@ -3435,12 +3435,6 @@ fail: + MIGRATION_STATUS_FAILED); + } + +-bool migrate_colo_enabled(void) +-{ +- MigrationState *s = migrate_get_current(); +- return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; +-} +- + typedef enum MigThrError { + /* No error detected */ + MIG_THR_ERR_NONE = 0, +@@ -3771,7 +3765,7 @@ static void migration_iteration_finish(MigrationState *s) + runstate_set(RUN_STATE_POSTMIGRATE); + break; + case MIGRATION_STATUS_COLO: +- if (!migrate_colo_enabled()) { ++ if (!migrate_colo()) { + error_report("%s: critical error: calling COLO code without " + "COLO enabled", __func__); + } +@@ -3967,7 +3961,7 @@ static void *migration_thread(void *opaque) + qemu_savevm_send_postcopy_advise(s->to_dst_file); + } + +- if (migrate_colo_enabled()) { ++ if (migrate_colo()) { + /* Notify migration destination that we enable COLO */ + qemu_savevm_send_colo_enable(s->to_dst_file); + } +diff --git a/migration/migration.h b/migration/migration.h +index a25fed6ef0..42f0c68b6f 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -463,7 +463,6 @@ bool migrate_use_zero_copy_send(void); + int migrate_use_tls(void); + int migrate_use_xbzrle(void); + uint64_t migrate_xbzrle_cache_size(void); +-bool migrate_colo_enabled(void); + + bool migrate_use_block(void); + bool migrate_use_block_incremental(void); +diff --git a/migration/options.c b/migration/options.c +index 88a9a45913..bd33c5da0a 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -33,6 +33,12 @@ bool migrate_background_snapshot(void) + return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; + } + ++bool migrate_colo(void) ++{ ++ MigrationState *s = migrate_get_current(); ++ return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; ++} ++ + bool migrate_dirty_bitmaps(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index 0dfa0af245..2a0ee61ff8 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -18,6 +18,7 @@ + + bool migrate_auto_converge(void); + bool migrate_background_snapshot(void); ++bool migrate_colo(void); + bool migrate_dirty_bitmaps(void); + bool migrate_ignore_shared(void); + bool migrate_late_block_activate(void); +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_postcopy-to-options.c.patch b/kvm-migration-Move-migrate_postcopy-to-options.c.patch new file mode 100644 index 0000000..892ec9e --- /dev/null +++ b/kvm-migration-Move-migrate_postcopy-to-options.c.patch @@ -0,0 +1,98 @@ +From 710fe195a3c13ffe96795a7a2b550c00319997ea Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 10:44:20 +0100 +Subject: [PATCH 47/56] migration: Move migrate_postcopy() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [46/50] a4f3455b3524a331f44b481bf7a79318aef5abaa (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Fabiano Rosas +(cherry picked from commit f774fde5d4e97cbfc64dab6622c2c53c5fe5c9fe) +Signed-off-by: Peter Xu +--- + migration/migration.c | 5 ----- + migration/migration.h | 2 -- + migration/options.c | 8 ++++++++ + migration/options.h | 9 +++++++++ + 4 files changed, 17 insertions(+), 7 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index f27ce30be2..46a5ea4d42 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2245,11 +2245,6 @@ void qmp_migrate_continue(MigrationStatus state, Error **errp) + qemu_sem_post(&s->pause_sem); + } + +-bool migrate_postcopy(void) +-{ +- return migrate_postcopy_ram() || migrate_dirty_bitmaps(); +-} +- + int migrate_use_tls(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index 3ae938b19c..dcf906868d 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -447,8 +447,6 @@ bool migration_is_blocked(Error **errp); + bool migration_in_postcopy(void); + MigrationState *migrate_get_current(void); + +-bool migrate_postcopy(void); +- + int migrate_use_tls(void); + + uint64_t ram_get_total_transferred_pages(void); +diff --git a/migration/options.c b/migration/options.c +index 615534c151..8bd2d949ae 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -204,6 +204,14 @@ bool migrate_zero_copy_send(void) + + return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; + } ++ ++/* pseudo capabilities */ ++ ++bool migrate_postcopy(void) ++{ ++ return migrate_postcopy_ram() || migrate_dirty_bitmaps(); ++} ++ + typedef enum WriteTrackingSupport { + WT_SUPPORT_UNKNOWN = 0, + WT_SUPPORT_ABSENT, +diff --git a/migration/options.h b/migration/options.h +index 99f6bbd7a1..093bc907a1 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -38,6 +38,15 @@ bool migrate_xbzrle(void); + bool migrate_zero_blocks(void); + bool migrate_zero_copy_send(void); + ++/* ++ * pseudo capabilities ++ * ++ * These are functions that are used in a similar way to capabilities ++ * check, but they are not a capability. ++ */ ++ ++bool migrate_postcopy(void); ++ + /* capabilities helpers */ + + bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp); +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_block-to-options.c.patch b/kvm-migration-Move-migrate_use_block-to-options.c.patch new file mode 100644 index 0000000..f7cb338 --- /dev/null +++ b/kvm-migration-Move-migrate_use_block-to-options.c.patch @@ -0,0 +1,134 @@ +From 276877a71778a5cef0dc5bc843e2679f0fdabb77 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:23:57 +0100 +Subject: [PATCH 30/56] migration: Move migrate_use_block() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [29/50] fcaeb0e07cf828f3cd0d115515b30d913525a0a2 (peterx/qemu-kvm) + +Once that we are there, we rename the function to migrate_block() +to be consistent with all other capabilities. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 9d4b1e5f22a838285ebeb8f0eb7cc8df1161998f) +Signed-off-by: Peter Xu +--- + migration/block.c | 2 +- + migration/migration.c | 11 +---------- + migration/migration.h | 1 - + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/savevm.c | 2 +- + 6 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/migration/block.c b/migration/block.c +index 4b167fa5cf..f0977217cf 100644 +--- a/migration/block.c ++++ b/migration/block.c +@@ -1001,7 +1001,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) + + static bool block_is_active(void *opaque) + { +- return migrate_use_block(); ++ return migrate_block(); + } + + static SaveVMHandlers savevm_block_handlers = { +diff --git a/migration/migration.c b/migration/migration.c +index a4ede4294e..96f82bd165 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2415,7 +2415,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc, + error_setg(errp, "No disk migration is required in COLO mode"); + return false; + } +- if (migrate_use_block() || migrate_use_block_incremental()) { ++ if (migrate_block() || migrate_use_block_incremental()) { + error_setg(errp, "Command options are incompatible with " + "current migration capabilities"); + return false; +@@ -2622,15 +2622,6 @@ static int64_t migrate_max_postcopy_bandwidth(void) + return s->parameters.max_postcopy_bandwidth; + } + +-bool migrate_use_block(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_BLOCK]; +-} +- + bool migrate_use_return_path(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index e2bb5b1e2f..d4b68b08a5 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -457,7 +457,6 @@ int migrate_multifd_zstd_level(void); + int migrate_use_tls(void); + uint64_t migrate_xbzrle_cache_size(void); + +-bool migrate_use_block(void); + bool migrate_use_block_incremental(void); + int migrate_max_cpu_throttle(void); + bool migrate_use_return_path(void); +diff --git a/migration/options.c b/migration/options.c +index 25264c500e..fe1eadeed6 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -33,6 +33,15 @@ bool migrate_background_snapshot(void) + return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; + } + ++bool migrate_block(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_BLOCK]; ++} ++ + bool migrate_colo(void) + { + MigrationState *s = migrate_get_current(); +diff --git a/migration/options.h b/migration/options.h +index 8f76a88329..e985a5233e 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -18,6 +18,7 @@ + + bool migrate_auto_converge(void); + bool migrate_background_snapshot(void); ++bool migrate_block(void); + bool migrate_colo(void); + bool migrate_compress(void); + bool migrate_dirty_bitmaps(void); +diff --git a/migration/savevm.c b/migration/savevm.c +index ebcf571e37..9671211339 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -1612,7 +1612,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp) + return -EINVAL; + } + +- if (migrate_use_block()) { ++ if (migrate_block()) { + error_setg(errp, "Block migration and snapshots are incompatible"); + return -EINVAL; + } +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_block_incremental-to-opti.patch b/kvm-migration-Move-migrate_use_block_incremental-to-opti.patch new file mode 100644 index 0000000..3f20289 --- /dev/null +++ b/kvm-migration-Move-migrate_use_block_incremental-to-opti.patch @@ -0,0 +1,121 @@ +From def66503f4ccb97cf8029f88efe8e955edc8d32f Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 00:49:47 +0100 +Subject: [PATCH 39/56] migration: Move migrate_use_block_incremental() to + option.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [38/50] 961fda6464df3384fbcee88c726b56a33c26e14e (peterx/qemu-kvm) + +To be consistent with every other parameter, rename to +migrate_block_incremental(). + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 6f8be7080a1f79bf3832cf798fba1697c409c597) +Signed-off-by: Peter Xu +--- + migration/block.c | 2 +- + migration/migration.c | 11 +---------- + migration/migration.h | 1 - + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + 5 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/migration/block.c b/migration/block.c +index f0977217cf..6d532ac7a2 100644 +--- a/migration/block.c ++++ b/migration/block.c +@@ -417,7 +417,7 @@ static int init_blk_migration(QEMUFile *f) + bmds->bulk_completed = 0; + bmds->total_sectors = sectors; + bmds->completed_sectors = 0; +- bmds->shared_base = migrate_use_block_incremental(); ++ bmds->shared_base = migrate_block_incremental(); + + assert(i < num_bs); + bmds_bs[i].bmds = bmds; +diff --git a/migration/migration.c b/migration/migration.c +index 78bca9a93f..724e841eb9 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2157,7 +2157,7 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc, + error_setg(errp, "No disk migration is required in COLO mode"); + return false; + } +- if (migrate_block() || migrate_use_block_incremental()) { ++ if (migrate_block() || migrate_block_incremental()) { + error_setg(errp, "Command options are incompatible with " + "current migration capabilities"); + return false; +@@ -2273,15 +2273,6 @@ int migrate_use_tls(void) + return s->parameters.tls_creds && *s->parameters.tls_creds; + } + +-bool migrate_use_block_incremental(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.block_incremental; +-} +- + /* migration thread support */ + /* + * Something bad happened to the RP stream, mark an error +diff --git a/migration/migration.h b/migration/migration.h +index 8451e5f2fe..86051af132 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -451,7 +451,6 @@ bool migrate_postcopy(void); + + int migrate_use_tls(void); + +-bool migrate_use_block_incremental(void); + int migrate_max_cpu_throttle(void); + + uint64_t ram_get_total_transferred_pages(void); +diff --git a/migration/options.c b/migration/options.c +index 8d15be858c..2b6d88b4b9 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -463,6 +463,15 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, + + /* parameters */ + ++bool migrate_block_incremental(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.block_incremental; ++} ++ + int migrate_compress_level(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index b24ee92283..96d5a8e6e4 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -45,6 +45,7 @@ bool migrate_cap_set(int cap, bool value, Error **errp); + + /* parameters */ + ++bool migrate_block_incremental(void); + int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_compression-to-options.c.patch b/kvm-migration-Move-migrate_use_compression-to-options.c.patch new file mode 100644 index 0000000..8b74183 --- /dev/null +++ b/kvm-migration-Move-migrate_use_compression-to-options.c.patch @@ -0,0 +1,183 @@ +From ae183bfc9d7b001d3c4929556b095a76203bc08d Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:03:48 +0100 +Subject: [PATCH 25/56] migration: Move migrate_use_compression() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [24/50] 126b865f51bd4a1ae3a46411fdcd59033bfc5376 (peterx/qemu-kvm) + +Once that we are there, we rename the function to migrate_compress() +to be consistent with all other capabilities. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit a7a94d14358dd7b445e20c2f26218ff987747642) +Signed-off-by: Peter Xu +--- + migration/migration.c | 11 +---------- + migration/migration.h | 1 - + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 16 ++++++++-------- + 5 files changed, 19 insertions(+), 19 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 59ee0ef82b..c6e32555a8 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1133,7 +1133,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->xbzrle_cache->overflow = xbzrle_counters.overflow; + } + +- if (migrate_use_compression()) { ++ if (migrate_compress()) { + info->compression = g_malloc0(sizeof(*info->compression)); + info->compression->pages = compression_counters.pages; + info->compression->busy = compression_counters.busy; +@@ -2522,15 +2522,6 @@ bool migrate_postcopy(void) + return migrate_postcopy_ram() || migrate_dirty_bitmaps(); + } + +-bool migrate_use_compression(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_COMPRESS]; +-} +- + int migrate_compress_level(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index 42f0c68b6f..77aa91c840 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -471,7 +471,6 @@ bool migrate_use_return_path(void); + + uint64_t ram_get_total_transferred_pages(void); + +-bool migrate_use_compression(void); + int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); +diff --git a/migration/options.c b/migration/options.c +index bd33c5da0a..fa7a13d3dc 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -39,6 +39,15 @@ bool migrate_colo(void) + return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; + } + ++bool migrate_compress(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_COMPRESS]; ++} ++ + bool migrate_dirty_bitmaps(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index 2a0ee61ff8..da2193fd94 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -19,6 +19,7 @@ + bool migrate_auto_converge(void); + bool migrate_background_snapshot(void); + bool migrate_colo(void); ++bool migrate_compress(void); + bool migrate_dirty_bitmaps(void); + bool migrate_ignore_shared(void); + bool migrate_late_block_activate(void); +diff --git a/migration/ram.c b/migration/ram.c +index 912ccd89fa..d050d0c5fd 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -586,7 +586,7 @@ static void compress_threads_save_cleanup(void) + { + int i, thread_count; + +- if (!migrate_use_compression() || !comp_param) { ++ if (!migrate_compress() || !comp_param) { + return; + } + +@@ -625,7 +625,7 @@ static int compress_threads_save_setup(void) + { + int i, thread_count; + +- if (!migrate_use_compression()) { ++ if (!migrate_compress()) { + return 0; + } + thread_count = migrate_compress_threads(); +@@ -1155,7 +1155,7 @@ static void migration_update_rates(RAMState *rs, int64_t end_time) + rs->xbzrle_bytes_prev = xbzrle_counters.bytes; + } + +- if (migrate_use_compression()) { ++ if (migrate_compress()) { + compression_counters.busy_rate = (double)(compression_counters.busy - + rs->compress_thread_busy_prev) / page_count; + rs->compress_thread_busy_prev = compression_counters.busy; +@@ -2270,7 +2270,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len) + + static bool save_page_use_compression(RAMState *rs) + { +- if (!migrate_use_compression()) { ++ if (!migrate_compress()) { + return false; + } + +@@ -3734,7 +3734,7 @@ static int wait_for_decompress_done(void) + { + int idx, thread_count; + +- if (!migrate_use_compression()) { ++ if (!migrate_compress()) { + return 0; + } + +@@ -3753,7 +3753,7 @@ static void compress_threads_load_cleanup(void) + { + int i, thread_count; + +- if (!migrate_use_compression()) { ++ if (!migrate_compress()) { + return; + } + thread_count = migrate_decompress_threads(); +@@ -3794,7 +3794,7 @@ static int compress_threads_load_setup(QEMUFile *f) + { + int i, thread_count; + +- if (!migrate_use_compression()) { ++ if (!migrate_compress()) { + return 0; + } + +@@ -4260,7 +4260,7 @@ static int ram_load_precopy(QEMUFile *f) + int flags = 0, ret = 0, invalid_flags = 0, len = 0, i = 0; + /* ADVISE is earlier, it shows the source has the postcopy capability on */ + bool postcopy_advised = migration_incoming_postcopy_advised(); +- if (!migrate_use_compression()) { ++ if (!migrate_compress()) { + invalid_flags |= RAM_SAVE_FLAG_COMPRESS_PAGE; + } + +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_events-to-options.c.patch b/kvm-migration-Move-migrate_use_events-to-options.c.patch new file mode 100644 index 0000000..41e05c3 --- /dev/null +++ b/kvm-migration-Move-migrate_use_events-to-options.c.patch @@ -0,0 +1,120 @@ +From 940f1eb4347c72edb3e1abc02c8d7e7c95753dcf Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:08:09 +0100 +Subject: [PATCH 26/56] migration: Move migrate_use_events() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [25/50] b3acd949af2a0fae18061d360e4f51dc12d32c6c (peterx/qemu-kvm) + +Once that we are there, we rename the function to migrate_events() +to be consistent with all other capabilities. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit b890902c9c025b87d02e718eec3090fd3525ab18) +Signed-off-by: Peter Xu +--- + migration/migration.c | 11 +---------- + migration/migration.h | 1 - + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 2 +- + 5 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index c6e32555a8..032cd5c050 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -353,7 +353,7 @@ void migration_incoming_state_destroy(void) + + static void migrate_generate_event(int new_state) + { +- if (migrate_use_events()) { ++ if (migrate_events()) { + qapi_event_send_migration(new_state); + } + } +@@ -2558,15 +2558,6 @@ int migrate_decompress_threads(void) + return s->parameters.decompress_threads; + } + +-bool migrate_use_events(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_EVENTS]; +-} +- + bool migrate_use_multifd(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index 77aa91c840..bd06520c19 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -475,7 +475,6 @@ int migrate_compress_level(void); + int migrate_compress_threads(void); + int migrate_compress_wait_thread(void); + int migrate_decompress_threads(void); +-bool migrate_use_events(void); + + /* Sending on the return path - generic and then for each message type */ + void migrate_send_rp_shut(MigrationIncomingState *mis, +diff --git a/migration/options.c b/migration/options.c +index fa7a13d3dc..d2219ee0e4 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -57,6 +57,15 @@ bool migrate_dirty_bitmaps(void) + return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; + } + ++bool migrate_events(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_EVENTS]; ++} ++ + bool migrate_ignore_shared(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index da2193fd94..b998024eba 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -21,6 +21,7 @@ bool migrate_background_snapshot(void); + bool migrate_colo(void); + bool migrate_compress(void); + bool migrate_dirty_bitmaps(void); ++bool migrate_events(void); + bool migrate_ignore_shared(void); + bool migrate_late_block_activate(void); + bool migrate_pause_before_switchover(void); +diff --git a/migration/ram.c b/migration/ram.c +index d050d0c5fd..ee454a3849 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1246,7 +1246,7 @@ static void migration_bitmap_sync(RAMState *rs) + rs->num_dirty_pages_period = 0; + rs->bytes_xfer_prev = stat64_get(&ram_counters.transferred); + } +- if (migrate_use_events()) { ++ if (migrate_events()) { + uint64_t generation = stat64_get(&ram_counters.dirty_sync_count); + qapi_event_send_migration_pass(generation); + } +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_multifd-to-options.c.patch b/kvm-migration-Move-migrate_use_multifd-to-options.c.patch new file mode 100644 index 0000000..97d6597 --- /dev/null +++ b/kvm-migration-Move-migrate_use_multifd-to-options.c.patch @@ -0,0 +1,247 @@ +From afd8fb766af2be5cff97753b026847b91b09a30e Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:10:29 +0100 +Subject: [PATCH 27/56] migration: Move migrate_use_multifd() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [26/50] f2d72eae9cc80b2402ef613e809b40aa296d2e4c (peterx/qemu-kvm) + +Once that we are there, we rename the function to migrate_multifd() +to be consistent with all other capabilities. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 51b07548f7c31793adc178c7460c5f4369733c61) +Signed-off-by: Peter Xu +--- + migration/migration.c | 19 +++++-------------- + migration/migration.h | 1 - + migration/multifd.c | 16 ++++++++-------- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 2 +- + migration/socket.c | 2 +- + 7 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 032cd5c050..e1d7f25786 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -186,7 +186,7 @@ static void migrate_fd_cancel(MigrationState *s); + + static bool migration_needs_multiple_sockets(void) + { +- return migrate_use_multifd() || migrate_postcopy_preempt(); ++ return migrate_multifd() || migrate_postcopy_preempt(); + } + + static bool uri_supports_multi_channels(const char *uri) +@@ -732,7 +732,7 @@ void migration_fd_process_incoming(QEMUFile *f, Error **errp) + static bool migration_should_start_incoming(bool main_channel) + { + /* Multifd doesn't start unless all channels are established */ +- if (migrate_use_multifd()) { ++ if (migrate_multifd()) { + return migration_has_all_channels(); + } + +@@ -759,7 +759,7 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp) + uint32_t channel_magic = 0; + int ret = 0; + +- if (migrate_use_multifd() && !migrate_postcopy_ram() && ++ if (migrate_multifd() && !migrate_postcopy_ram() && + qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) { + /* + * With multiple channels, it is possible that we receive channels +@@ -798,7 +798,7 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp) + } else { + /* Multiple connections */ + assert(migration_needs_multiple_sockets()); +- if (migrate_use_multifd()) { ++ if (migrate_multifd()) { + multifd_recv_new_channel(ioc, &local_err); + } else { + assert(migrate_postcopy_preempt()); +@@ -834,7 +834,7 @@ bool migration_has_all_channels(void) + return false; + } + +- if (migrate_use_multifd()) { ++ if (migrate_multifd()) { + return multifd_recv_all_channels_created(); + } + +@@ -2558,15 +2558,6 @@ int migrate_decompress_threads(void) + return s->parameters.decompress_threads; + } + +-bool migrate_use_multifd(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; +-} +- + int migrate_multifd_channels(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index bd06520c19..49c0e13f41 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -449,7 +449,6 @@ MigrationState *migrate_get_current(void); + + bool migrate_postcopy(void); + +-bool migrate_use_multifd(void); + int migrate_multifd_channels(void); + MultiFDCompression migrate_multifd_compression(void); + int migrate_multifd_zlib_level(void); +diff --git a/migration/multifd.c b/migration/multifd.c +index 903df2117b..6807328189 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -516,7 +516,7 @@ void multifd_save_cleanup(void) + { + int i; + +- if (!migrate_use_multifd()) { ++ if (!migrate_multifd()) { + return; + } + multifd_send_terminate_threads(NULL); +@@ -587,7 +587,7 @@ int multifd_send_sync_main(QEMUFile *f) + int i; + bool flush_zero_copy; + +- if (!migrate_use_multifd()) { ++ if (!migrate_multifd()) { + return 0; + } + if (multifd_send_state->pages->num) { +@@ -911,7 +911,7 @@ int multifd_save_setup(Error **errp) + uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size(); + uint8_t i; + +- if (!migrate_use_multifd()) { ++ if (!migrate_multifd()) { + return 0; + } + +@@ -1016,7 +1016,7 @@ static void multifd_recv_terminate_threads(Error *err) + + void multifd_load_shutdown(void) + { +- if (migrate_use_multifd()) { ++ if (migrate_multifd()) { + multifd_recv_terminate_threads(NULL); + } + } +@@ -1025,7 +1025,7 @@ void multifd_load_cleanup(void) + { + int i; + +- if (!migrate_use_multifd()) { ++ if (!migrate_multifd()) { + return; + } + multifd_recv_terminate_threads(NULL); +@@ -1072,7 +1072,7 @@ void multifd_recv_sync_main(void) + { + int i; + +- if (!migrate_use_multifd()) { ++ if (!migrate_multifd()) { + return; + } + for (i = 0; i < migrate_multifd_channels(); i++) { +@@ -1170,7 +1170,7 @@ int multifd_load_setup(Error **errp) + * Return successfully if multiFD recv state is already initialised + * or multiFD is not enabled. + */ +- if (multifd_recv_state || !migrate_use_multifd()) { ++ if (multifd_recv_state || !migrate_multifd()) { + return 0; + } + +@@ -1216,7 +1216,7 @@ bool multifd_recv_all_channels_created(void) + { + int thread_count = migrate_multifd_channels(); + +- if (!migrate_use_multifd()) { ++ if (!migrate_multifd()) { + return true; + } + +diff --git a/migration/options.c b/migration/options.c +index d2219ee0e4..58673fc101 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -84,6 +84,15 @@ bool migrate_late_block_activate(void) + return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; + } + ++bool migrate_multifd(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; ++} ++ + bool migrate_pause_before_switchover(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index b998024eba..d07269ee38 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -24,6 +24,7 @@ bool migrate_dirty_bitmaps(void); + bool migrate_events(void); + bool migrate_ignore_shared(void); + bool migrate_late_block_activate(void); ++bool migrate_multifd(void); + bool migrate_pause_before_switchover(void); + bool migrate_postcopy_blocktime(void); + bool migrate_postcopy_preempt(void); +diff --git a/migration/ram.c b/migration/ram.c +index ee454a3849..859dd7b63f 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -2362,7 +2362,7 @@ static int ram_save_target_page_legacy(RAMState *rs, PageSearchStatus *pss) + * if host page size == guest page size the dest guest during run may + * still see partially copied pages which is data corruption. + */ +- if (migrate_use_multifd() && !migration_in_postcopy()) { ++ if (migrate_multifd() && !migration_in_postcopy()) { + return ram_save_multifd_page(pss->pss_channel, block, offset); + } + +diff --git a/migration/socket.c b/migration/socket.c +index ebf9ac41af..f4835a256a 100644 +--- a/migration/socket.c ++++ b/migration/socket.c +@@ -183,7 +183,7 @@ socket_start_incoming_migration_internal(SocketAddress *saddr, + + qio_net_listener_set_name(listener, "migration-socket-listener"); + +- if (migrate_use_multifd()) { ++ if (migrate_multifd()) { + num = migrate_multifd_channels(); + } else if (migrate_postcopy_preempt()) { + num = RAM_CHANNEL_MAX; +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_return-to-options.c.patch b/kvm-migration-Move-migrate_use_return-to-options.c.patch new file mode 100644 index 0000000..b250d40 --- /dev/null +++ b/kvm-migration-Move-migrate_use_return-to-options.c.patch @@ -0,0 +1,138 @@ +From 145b630767dbc7020ddf39b20075f4691f71321a Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:25:47 +0100 +Subject: [PATCH 31/56] migration: Move migrate_use_return() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [30/50] 5cc150188bcc61b69ea0844253597594ab18fc13 (peterx/qemu-kvm) + +Once that we are there, we rename the function to migrate_return_path() +to be consistent with all other capabilities. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 38ad1110e368bf91453c0abbd657224d57b65d47) +Signed-off-by: Peter Xu +--- + migration/migration.c | 11 +---------- + migration/migration.h | 1 - + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/rdma.c | 6 +++--- + 5 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 96f82bd165..f7facecd66 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2622,15 +2622,6 @@ static int64_t migrate_max_postcopy_bandwidth(void) + return s->parameters.max_postcopy_bandwidth; + } + +-bool migrate_use_return_path(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; +-} +- + bool migrate_use_block_incremental(void) + { + MigrationState *s; +@@ -4175,7 +4166,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) + * precopy, only if user specified "return-path" capability would + * QEMU uses the return path. + */ +- if (migrate_postcopy_ram() || migrate_use_return_path()) { ++ if (migrate_postcopy_ram() || migrate_return_path()) { + if (open_return_path_on_source(s, !resume)) { + error_report("Unable to open return-path for postcopy"); + migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED); +diff --git a/migration/migration.h b/migration/migration.h +index d4b68b08a5..24184622a8 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -459,7 +459,6 @@ uint64_t migrate_xbzrle_cache_size(void); + + bool migrate_use_block_incremental(void); + int migrate_max_cpu_throttle(void); +-bool migrate_use_return_path(void); + + uint64_t ram_get_total_transferred_pages(void); + +diff --git a/migration/options.c b/migration/options.c +index fe1eadeed6..2003e413da 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -147,6 +147,15 @@ bool migrate_release_ram(void) + return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; + } + ++bool migrate_return_path(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; ++} ++ + bool migrate_validate_uuid(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index e985a5233e..316efd1063 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -31,6 +31,7 @@ bool migrate_postcopy_blocktime(void); + bool migrate_postcopy_preempt(void); + bool migrate_postcopy_ram(void); + bool migrate_release_ram(void); ++bool migrate_return_path(void); + bool migrate_validate_uuid(void); + bool migrate_xbzrle(void); + bool migrate_zero_blocks(void); +diff --git a/migration/rdma.c b/migration/rdma.c +index f35f021963..bf55e2f163 100644 +--- a/migration/rdma.c ++++ b/migration/rdma.c +@@ -3373,7 +3373,7 @@ static int qemu_rdma_accept(RDMAContext *rdma) + * initialize the RDMAContext for return path for postcopy after first + * connection request reached. + */ +- if ((migrate_postcopy() || migrate_use_return_path()) ++ if ((migrate_postcopy() || migrate_return_path()) + && !rdma->is_return_path) { + rdma_return_path = qemu_rdma_data_init(rdma->host_port, NULL); + if (rdma_return_path == NULL) { +@@ -3456,7 +3456,7 @@ static int qemu_rdma_accept(RDMAContext *rdma) + } + + /* Accept the second connection request for return path */ +- if ((migrate_postcopy() || migrate_use_return_path()) ++ if ((migrate_postcopy() || migrate_return_path()) + && !rdma->is_return_path) { + qemu_set_fd_handler(rdma->channel->fd, rdma_accept_incoming_migration, + NULL, +@@ -4193,7 +4193,7 @@ void rdma_start_outgoing_migration(void *opaque, + } + + /* RDMA postcopy need a separate queue pair for return path */ +- if (migrate_postcopy() || migrate_use_return_path()) { ++ if (migrate_postcopy() || migrate_return_path()) { + rdma_return_path = qemu_rdma_data_init(host_port, errp); + + if (rdma_return_path == NULL) { +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_tls-to-options.c.patch b/kvm-migration-Move-migrate_use_tls-to-options.c.patch new file mode 100644 index 0000000..84734af --- /dev/null +++ b/kvm-migration-Move-migrate_use_tls-to-options.c.patch @@ -0,0 +1,134 @@ +From 2e2df63892e191e91216b8253171162f69b93387 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 10:41:23 +0100 +Subject: [PATCH 49/56] migration: Move migrate_use_tls() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [48/50] 314431b0f5e92d2211e58a8161f32d7b67d69e38 (peterx/qemu-kvm) + +Once there, rename it to migrate_tls() and make it return bool for +consistency. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy + +--- + +Fix typos found by fabiano + +(cherry picked from commit 10d4703be5d884bbbb6ecafe0e8bb270ad6ea937) +Signed-off-by: Peter Xu +--- + migration/migration.c | 9 --------- + migration/migration.h | 2 -- + migration/options.c | 11 ++++++++++- + migration/options.h | 1 + + migration/tls.c | 3 ++- + 5 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index c2e109329d..22ef83c619 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2177,15 +2177,6 @@ void qmp_migrate_continue(MigrationStatus state, Error **errp) + qemu_sem_post(&s->pause_sem); + } + +-int migrate_use_tls(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.tls_creds && *s->parameters.tls_creds; +-} +- + /* migration thread support */ + /* + * Something bad happened to the RP stream, mark an error +diff --git a/migration/migration.h b/migration/migration.h +index dcf906868d..2b71df8617 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -447,8 +447,6 @@ bool migration_is_blocked(Error **errp); + bool migration_in_postcopy(void); + MigrationState *migrate_get_current(void); + +-int migrate_use_tls(void); +- + uint64_t ram_get_total_transferred_pages(void); + + /* Sending on the return path - generic and then for each message type */ +diff --git a/migration/options.c b/migration/options.c +index 8e8753d9be..d4c0714683 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -214,6 +214,15 @@ bool migrate_postcopy(void) + return migrate_postcopy_ram() || migrate_dirty_bitmaps(); + } + ++bool migrate_tls(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.tls_creds && *s->parameters.tls_creds; ++} ++ + typedef enum WriteTrackingSupport { + WT_SUPPORT_UNKNOWN = 0, + WT_SUPPORT_ABSENT, +@@ -363,7 +372,7 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) + new_caps[MIGRATION_CAPABILITY_COMPRESS] || + new_caps[MIGRATION_CAPABILITY_XBZRLE] || + migrate_multifd_compression() || +- migrate_use_tls())) { ++ migrate_tls())) { + error_setg(errp, + "Zero copy only available for non-compressed non-TLS multifd migration"); + return false; +diff --git a/migration/options.h b/migration/options.h +index 1b78fa9f3d..13318a16c7 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -46,6 +46,7 @@ bool migrate_zero_copy_send(void); + */ + + bool migrate_postcopy(void); ++bool migrate_tls(void); + + /* capabilities helpers */ + +diff --git a/migration/tls.c b/migration/tls.c +index 4d2166a209..acd38e0b62 100644 +--- a/migration/tls.c ++++ b/migration/tls.c +@@ -22,6 +22,7 @@ + #include "channel.h" + #include "migration.h" + #include "tls.h" ++#include "options.h" + #include "crypto/tlscreds.h" + #include "qemu/error-report.h" + #include "qapi/error.h" +@@ -165,7 +166,7 @@ void migration_tls_channel_connect(MigrationState *s, + + bool migrate_channel_requires_tls_upgrade(QIOChannel *ioc) + { +- if (!migrate_use_tls()) { ++ if (!migrate_tls()) { + return false; + } + +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_xbzrle-to-options.c.patch b/kvm-migration-Move-migrate_use_xbzrle-to-options.c.patch new file mode 100644 index 0000000..e3a8bab --- /dev/null +++ b/kvm-migration-Move-migrate_use_xbzrle-to-options.c.patch @@ -0,0 +1,156 @@ +From 2184f7dae0df5fa52deba2dc884e09c6bdbc7b5f Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:20:13 +0100 +Subject: [PATCH 29/56] migration: Move migrate_use_xbzrle() to options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [28/50] fc8bee0f691a96e6bd0b41f2511abe507b81fea5 (peterx/qemu-kvm) + +Once that we are there, we rename the function to migrate_xbzrle() +to be consistent with all other capabilities. +We change the type to return bool also for consistency. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 87dca0c9bb63014ef73ad82f7aedea1cb5a822e7) +Signed-off-by: Peter Xu +--- + migration/migration.c | 11 +---------- + migration/migration.h | 1 - + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/ram.c | 10 +++++----- + 5 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 1d63718e88..a4ede4294e 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1122,7 +1122,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram->downtime_bytes = stat64_get(&ram_counters.downtime_bytes); + info->ram->postcopy_bytes = stat64_get(&ram_counters.postcopy_bytes); + +- if (migrate_use_xbzrle()) { ++ if (migrate_xbzrle()) { + info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache)); + info->xbzrle_cache->cache_size = migrate_xbzrle_cache_size(); + info->xbzrle_cache->bytes = xbzrle_counters.bytes; +@@ -2604,15 +2604,6 @@ int migrate_use_tls(void) + return s->parameters.tls_creds && *s->parameters.tls_creds; + } + +-int migrate_use_xbzrle(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_XBZRLE]; +-} +- + uint64_t migrate_xbzrle_cache_size(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index c939f82d53..e2bb5b1e2f 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -455,7 +455,6 @@ int migrate_multifd_zlib_level(void); + int migrate_multifd_zstd_level(void); + + int migrate_use_tls(void); +-int migrate_use_xbzrle(void); + uint64_t migrate_xbzrle_cache_size(void); + + bool migrate_use_block(void); +diff --git a/migration/options.c b/migration/options.c +index f357c99996..25264c500e 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -147,6 +147,15 @@ bool migrate_validate_uuid(void) + return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; + } + ++bool migrate_xbzrle(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_XBZRLE]; ++} ++ + bool migrate_zero_blocks(void) + { + MigrationState *s; +diff --git a/migration/options.h b/migration/options.h +index ad22f4d24a..8f76a88329 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -31,6 +31,7 @@ bool migrate_postcopy_preempt(void); + bool migrate_postcopy_ram(void); + bool migrate_release_ram(void); + bool migrate_validate_uuid(void); ++bool migrate_xbzrle(void); + bool migrate_zero_blocks(void); + bool migrate_zero_copy_send(void); + +diff --git a/migration/ram.c b/migration/ram.c +index 859dd7b63f..4576d0d849 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -156,14 +156,14 @@ static struct { + + static void XBZRLE_cache_lock(void) + { +- if (migrate_use_xbzrle()) { ++ if (migrate_xbzrle()) { + qemu_mutex_lock(&XBZRLE.lock); + } + } + + static void XBZRLE_cache_unlock(void) + { +- if (migrate_use_xbzrle()) { ++ if (migrate_xbzrle()) { + qemu_mutex_unlock(&XBZRLE.lock); + } + } +@@ -1137,7 +1137,7 @@ static void migration_update_rates(RAMState *rs, int64_t end_time) + return; + } + +- if (migrate_use_xbzrle()) { ++ if (migrate_xbzrle()) { + double encoded_size, unencoded_size; + + xbzrle_counters.cache_miss_rate = (double)(xbzrle_counters.cache_miss - +@@ -1626,7 +1626,7 @@ static int find_dirty_block(RAMState *rs, PageSearchStatus *pss) + /* Flag that we've looped */ + pss->complete_round = true; + /* After the first round, enable XBZRLE. */ +- if (migrate_use_xbzrle()) { ++ if (migrate_xbzrle()) { + rs->xbzrle_enabled = true; + } + } +@@ -2979,7 +2979,7 @@ static int xbzrle_init(void) + { + Error *local_err = NULL; + +- if (!migrate_use_xbzrle()) { ++ if (!migrate_xbzrle()) { + return 0; + } + +-- +2.39.1 + diff --git a/kvm-migration-Move-migrate_use_zero_copy_send-to-options.patch b/kvm-migration-Move-migrate_use_zero_copy_send-to-options.patch new file mode 100644 index 0000000..90031df --- /dev/null +++ b/kvm-migration-Move-migrate_use_zero_copy_send-to-options.patch @@ -0,0 +1,167 @@ +From 6eb252887378d639ad2e90dd426a1812d4b72ca6 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 22:17:14 +0100 +Subject: [PATCH 28/56] migration: Move migrate_use_zero_copy_send() to + options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [27/50] 5a4c2b5e75c62e0f60f9c4121a2756bd140a60d9 (peterx/qemu-kvm) + +Once that we are there, we rename the function to +migrate_zero_copy_send() to be consistent with all other capabilities. + +We can remove the CONFIG_LINUX guard. We already check that we can't +setup this capability in migrate_caps_check(). + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit b4bc342c766640e0cb8a0b72f71e0ee5545fb790) +Signed-off-by: Peter Xu +--- + migration/migration.c | 13 +------------ + migration/migration.h | 5 ----- + migration/multifd.c | 8 ++++---- + migration/options.c | 9 +++++++++ + migration/options.h | 1 + + migration/socket.c | 2 +- + 6 files changed, 16 insertions(+), 22 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index e1d7f25786..1d63718e88 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1609,7 +1609,7 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp) + } + + #ifdef CONFIG_LINUX +- if (migrate_use_zero_copy_send() && ++ if (migrate_zero_copy_send() && + ((params->has_multifd_compression && params->multifd_compression) || + (params->tls_creds && *params->tls_creds))) { + error_setg(errp, +@@ -2595,17 +2595,6 @@ int migrate_multifd_zstd_level(void) + return s->parameters.multifd_zstd_level; + } + +-#ifdef CONFIG_LINUX +-bool migrate_use_zero_copy_send(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; +-} +-#endif +- + int migrate_use_tls(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index 49c0e13f41..c939f82d53 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -454,11 +454,6 @@ MultiFDCompression migrate_multifd_compression(void); + int migrate_multifd_zlib_level(void); + int migrate_multifd_zstd_level(void); + +-#ifdef CONFIG_LINUX +-bool migrate_use_zero_copy_send(void); +-#else +-#define migrate_use_zero_copy_send() (false) +-#endif + int migrate_use_tls(void); + int migrate_use_xbzrle(void); + uint64_t migrate_xbzrle_cache_size(void); +diff --git a/migration/multifd.c b/migration/multifd.c +index 6807328189..cce3ad6988 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -25,7 +25,7 @@ + #include "trace.h" + #include "multifd.h" + #include "threadinfo.h" +- ++#include "options.h" + #include "qemu/yank.h" + #include "io/channel-socket.h" + #include "yank_functions.h" +@@ -608,7 +608,7 @@ int multifd_send_sync_main(QEMUFile *f) + * all the dirty bitmaps. + */ + +- flush_zero_copy = migrate_use_zero_copy_send(); ++ flush_zero_copy = migrate_zero_copy_send(); + + for (i = 0; i < migrate_multifd_channels(); i++) { + MultiFDSendParams *p = &multifd_send_state->params[i]; +@@ -653,7 +653,7 @@ static void *multifd_send_thread(void *opaque) + MigrationThread *thread = NULL; + Error *local_err = NULL; + int ret = 0; +- bool use_zero_copy_send = migrate_use_zero_copy_send(); ++ bool use_zero_copy_send = migrate_zero_copy_send(); + + thread = MigrationThreadAdd(p->name, qemu_get_thread_id()); + +@@ -945,7 +945,7 @@ int multifd_save_setup(Error **errp) + p->page_size = qemu_target_page_size(); + p->page_count = page_count; + +- if (migrate_use_zero_copy_send()) { ++ if (migrate_zero_copy_send()) { + p->write_flags = QIO_CHANNEL_WRITE_FLAG_ZERO_COPY; + } else { + p->write_flags = 0; +diff --git a/migration/options.c b/migration/options.c +index 58673fc101..f357c99996 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -155,3 +155,12 @@ bool migrate_zero_blocks(void) + + return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; + } ++ ++bool migrate_zero_copy_send(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; ++} +diff --git a/migration/options.h b/migration/options.h +index d07269ee38..ad22f4d24a 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -32,5 +32,6 @@ bool migrate_postcopy_ram(void); + bool migrate_release_ram(void); + bool migrate_validate_uuid(void); + bool migrate_zero_blocks(void); ++bool migrate_zero_copy_send(void); + + #endif +diff --git a/migration/socket.c b/migration/socket.c +index f4835a256a..1b6f5baefb 100644 +--- a/migration/socket.c ++++ b/migration/socket.c +@@ -98,7 +98,7 @@ static void socket_outgoing_migration(QIOTask *task, + + trace_migration_socket_outgoing_connected(data->hostname); + +- if (migrate_use_zero_copy_send() && ++ if (migrate_zero_copy_send() && + !qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) { + error_setg(&err, "Zero copy send feature not detected in host kernel"); + } +-- +2.39.1 + diff --git a/kvm-migration-Move-parameters-functions-to-option.c.patch b/kvm-migration-Move-parameters-functions-to-option.c.patch new file mode 100644 index 0000000..ad4510b --- /dev/null +++ b/kvm-migration-Move-parameters-functions-to-option.c.patch @@ -0,0 +1,317 @@ +From d5ea4c82c44a59ac70313eb1eac77999ca5fde36 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 00:39:03 +0100 +Subject: [PATCH 37/56] migration: Move parameters functions to option.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [36/50] 2540921028025504723e762c0a1d2f295ac5a6d1 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 1dfc4b9e19bcf1ad41a1be9ac82db35b9647c3c1) +Signed-off-by: Peter Xu +--- + migration/migration.c | 91 --------------------------------------- + migration/migration.h | 11 ----- + migration/multifd-zlib.c | 1 + + migration/multifd-zstd.c | 1 + + migration/options.c | 93 ++++++++++++++++++++++++++++++++++++++++ + migration/options.h | 13 ++++++ + 6 files changed, 108 insertions(+), 102 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 880a51210e..7f2e770deb 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2264,79 +2264,6 @@ bool migrate_postcopy(void) + return migrate_postcopy_ram() || migrate_dirty_bitmaps(); + } + +-int migrate_compress_level(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.compress_level; +-} +- +-int migrate_compress_threads(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.compress_threads; +-} +- +-int migrate_compress_wait_thread(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.compress_wait_thread; +-} +- +-int migrate_decompress_threads(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.decompress_threads; +-} +- +-int migrate_multifd_channels(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.multifd_channels; +-} +- +-MultiFDCompression migrate_multifd_compression(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX); +- return s->parameters.multifd_compression; +-} +- +-int migrate_multifd_zlib_level(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.multifd_zlib_level; +-} +- +-int migrate_multifd_zstd_level(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.multifd_zstd_level; +-} +- + int migrate_use_tls(void) + { + MigrationState *s; +@@ -2346,24 +2273,6 @@ int migrate_use_tls(void) + return s->parameters.tls_creds && *s->parameters.tls_creds; + } + +-uint64_t migrate_xbzrle_cache_size(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.xbzrle_cache_size; +-} +- +-static int64_t migrate_max_postcopy_bandwidth(void) +-{ +- MigrationState *s; +- +- s = migrate_get_current(); +- +- return s->parameters.max_postcopy_bandwidth; +-} +- + bool migrate_use_block_incremental(void) + { + MigrationState *s; +diff --git a/migration/migration.h b/migration/migration.h +index 24184622a8..8451e5f2fe 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -449,24 +449,13 @@ MigrationState *migrate_get_current(void); + + bool migrate_postcopy(void); + +-int migrate_multifd_channels(void); +-MultiFDCompression migrate_multifd_compression(void); +-int migrate_multifd_zlib_level(void); +-int migrate_multifd_zstd_level(void); +- + int migrate_use_tls(void); +-uint64_t migrate_xbzrle_cache_size(void); + + bool migrate_use_block_incremental(void); + int migrate_max_cpu_throttle(void); + + uint64_t ram_get_total_transferred_pages(void); + +-int migrate_compress_level(void); +-int migrate_compress_threads(void); +-int migrate_compress_wait_thread(void); +-int migrate_decompress_threads(void); +- + /* Sending on the return path - generic and then for each message type */ + void migrate_send_rp_shut(MigrationIncomingState *mis, + uint32_t value); +diff --git a/migration/multifd-zlib.c b/migration/multifd-zlib.c +index 37770248e1..81701250ad 100644 +--- a/migration/multifd-zlib.c ++++ b/migration/multifd-zlib.c +@@ -18,6 +18,7 @@ + #include "qapi/error.h" + #include "migration.h" + #include "trace.h" ++#include "options.h" + #include "multifd.h" + + struct zlib_data { +diff --git a/migration/multifd-zstd.c b/migration/multifd-zstd.c +index f4a8e1ed1f..d1d29e76cc 100644 +--- a/migration/multifd-zstd.c ++++ b/migration/multifd-zstd.c +@@ -18,6 +18,7 @@ + #include "qapi/error.h" + #include "migration.h" + #include "trace.h" ++#include "options.h" + #include "multifd.h" + + struct zstd_data { +diff --git a/migration/options.c b/migration/options.c +index f3b2d6e482..8d15be858c 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -460,3 +460,96 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, + s->capabilities[cap->value->capability] = cap->value->state; + } + } ++ ++/* parameters */ ++ ++int migrate_compress_level(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.compress_level; ++} ++ ++int migrate_compress_threads(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.compress_threads; ++} ++ ++int migrate_compress_wait_thread(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.compress_wait_thread; ++} ++ ++int migrate_decompress_threads(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.decompress_threads; ++} ++ ++int64_t migrate_max_postcopy_bandwidth(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.max_postcopy_bandwidth; ++} ++ ++int migrate_multifd_channels(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.multifd_channels; ++} ++ ++MultiFDCompression migrate_multifd_compression(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX); ++ return s->parameters.multifd_compression; ++} ++ ++int migrate_multifd_zlib_level(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.multifd_zlib_level; ++} ++ ++int migrate_multifd_zstd_level(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.multifd_zstd_level; ++} ++ ++uint64_t migrate_xbzrle_cache_size(void) ++{ ++ MigrationState *s; ++ ++ s = migrate_get_current(); ++ ++ return s->parameters.xbzrle_cache_size; ++} +diff --git a/migration/options.h b/migration/options.h +index 5979e4ff90..b24ee92283 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -43,4 +43,17 @@ bool migrate_zero_copy_send(void); + bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp); + bool migrate_cap_set(int cap, bool value, Error **errp); + ++/* parameters */ ++ ++int migrate_compress_level(void); ++int migrate_compress_threads(void); ++int migrate_compress_wait_thread(void); ++int migrate_decompress_threads(void); ++int64_t migrate_max_postcopy_bandwidth(void); ++int migrate_multifd_channels(void); ++MultiFDCompression migrate_multifd_compression(void); ++int migrate_multifd_zlib_level(void); ++int migrate_multifd_zstd_level(void); ++uint64_t migrate_xbzrle_cache_size(void); ++ + #endif +-- +2.39.1 + diff --git a/kvm-migration-Move-qmp_migrate_set_capabilities-to-optio.patch b/kvm-migration-Move-qmp_migrate_set_capabilities-to-optio.patch new file mode 100644 index 0000000..10f185b --- /dev/null +++ b/kvm-migration-Move-qmp_migrate_set_capabilities-to-optio.patch @@ -0,0 +1,100 @@ +From d967ec22cdb20e0a846f050a2bc7bd4caa87940d Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 23:18:02 +0100 +Subject: [PATCH 35/56] migration: Move qmp_migrate_set_capabilities() to + options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [34/50] 16b62ca7e06c58d71389c449dc19c11939dd0882 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 45c1de13f09b1fd4ea26f54e6da12aae52f34cb8) +Signed-off-by: Peter Xu +--- + migration/migration.c | 26 -------------------------- + migration/options.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 26 insertions(+), 26 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 3dc8ee4875..369cd91796 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1222,32 +1222,6 @@ MigrationInfo *qmp_query_migrate(Error **errp) + return info; + } + +-void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, +- Error **errp) +-{ +- MigrationState *s = migrate_get_current(); +- MigrationCapabilityStatusList *cap; +- bool new_caps[MIGRATION_CAPABILITY__MAX]; +- +- if (migration_is_running(s->state)) { +- error_setg(errp, QERR_MIGRATION_ACTIVE); +- return; +- } +- +- memcpy(new_caps, s->capabilities, sizeof(new_caps)); +- for (cap = params; cap; cap = cap->next) { +- new_caps[cap->value->capability] = cap->value->state; +- } +- +- if (!migrate_caps_check(s->capabilities, new_caps, errp)) { +- return; +- } +- +- for (cap = params; cap; cap = cap->next) { +- s->capabilities[cap->value->capability] = cap->value->state; +- } +-} +- + /* + * Check whether the parameters are valid. Error will be put into errp + * (if provided). Return true if valid, otherwise false. +diff --git a/migration/options.c b/migration/options.c +index ff621bdeb3..4cbe77e35a 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -413,3 +413,29 @@ MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) + + return head; + } ++ ++void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, ++ Error **errp) ++{ ++ MigrationState *s = migrate_get_current(); ++ MigrationCapabilityStatusList *cap; ++ bool new_caps[MIGRATION_CAPABILITY__MAX]; ++ ++ if (migration_is_running(s->state)) { ++ error_setg(errp, QERR_MIGRATION_ACTIVE); ++ return; ++ } ++ ++ memcpy(new_caps, s->capabilities, sizeof(new_caps)); ++ for (cap = params; cap; cap = cap->next) { ++ new_caps[cap->value->capability] = cap->value->state; ++ } ++ ++ if (!migrate_caps_check(s->capabilities, new_caps, errp)) { ++ return; ++ } ++ ++ for (cap = params; cap; cap = cap->next) { ++ s->capabilities[cap->value->capability] = cap->value->state; ++ } ++} +-- +2.39.1 + diff --git a/kvm-migration-Move-qmp_migrate_set_parameters-to-options.patch b/kvm-migration-Move-qmp_migrate_set_parameters-to-options.patch new file mode 100644 index 0000000..3685a33 --- /dev/null +++ b/kvm-migration-Move-qmp_migrate_set_parameters-to-options.patch @@ -0,0 +1,943 @@ +From 944bf4759d1279c342ddd29c47d47c9670b64625 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 10:13:16 +0100 +Subject: [PATCH 50/56] migration: Move qmp_migrate_set_parameters() to + options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [49/50] b55f7afe868e117d4212f1518b9a37514cc99b33 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 09d6c9658474e8573c5ada58dca8b20fe47dd99e) +Signed-off-by: Peter Xu +--- + migration/migration.c | 420 ------------------------------------------ + migration/options.c | 418 +++++++++++++++++++++++++++++++++++++++++ + migration/options.h | 11 ++ + 3 files changed, 429 insertions(+), 420 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 22ef83c619..08f87f2b0e 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -67,19 +67,10 @@ + + #define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ + +-/* Amount of time to allocate to each "chunk" of bandwidth-throttled +- * data. */ +-#define BUFFER_DELAY 100 +-#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY) +- + /* Time in milliseconds we are allowed to stop the source, + * for sending the last part */ + #define DEFAULT_MIGRATE_SET_DOWNTIME 300 + +-/* Maximum migrate downtime set to 2000 seconds */ +-#define MAX_MIGRATE_DOWNTIME_SECONDS 2000 +-#define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000) +- + /* Default compression thread count */ + #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8 + /* Default decompression thread count, usually decompression is at +@@ -1140,417 +1131,6 @@ MigrationInfo *qmp_query_migrate(Error **errp) + return info; + } + +-/* +- * 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)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", +- "a value between 0 and 9"); +- return false; +- } +- +- if (params->has_compress_threads && (params->compress_threads < 1)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "compress_threads", +- "a value between 1 and 255"); +- return false; +- } +- +- if (params->has_decompress_threads && (params->decompress_threads < 1)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "decompress_threads", +- "a value between 1 and 255"); +- return false; +- } +- +- if (params->has_throttle_trigger_threshold && +- (params->throttle_trigger_threshold < 1 || +- params->throttle_trigger_threshold > 100)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "throttle_trigger_threshold", +- "an integer in the range of 1 to 100"); +- return false; +- } +- +- if (params->has_cpu_throttle_initial && +- (params->cpu_throttle_initial < 1 || +- params->cpu_throttle_initial > 99)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "cpu_throttle_initial", +- "an integer in the range of 1 to 99"); +- return false; +- } +- +- if (params->has_cpu_throttle_increment && +- (params->cpu_throttle_increment < 1 || +- params->cpu_throttle_increment > 99)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "cpu_throttle_increment", +- "an integer in the range of 1 to 99"); +- return false; +- } +- +- if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "max_bandwidth", +- "an integer in the range of 0 to "stringify(SIZE_MAX) +- " bytes/second"); +- return false; +- } +- +- if (params->has_downtime_limit && +- (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "downtime_limit", +- "an integer in the range of 0 to " +- stringify(MAX_MIGRATE_DOWNTIME)" ms"); +- return false; +- } +- +- /* x_checkpoint_delay is now always positive */ +- +- if (params->has_multifd_channels && (params->multifd_channels < 1)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "multifd_channels", +- "a value between 1 and 255"); +- return false; +- } +- +- if (params->has_multifd_zlib_level && +- (params->multifd_zlib_level > 9)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", +- "a value between 0 and 9"); +- return false; +- } +- +- if (params->has_multifd_zstd_level && +- (params->multifd_zstd_level > 20)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", +- "a value between 0 and 20"); +- return false; +- } +- +- if (params->has_xbzrle_cache_size && +- (params->xbzrle_cache_size < qemu_target_page_size() || +- !is_power_of_2(params->xbzrle_cache_size))) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "xbzrle_cache_size", +- "a power of two no less than the target page size"); +- return false; +- } +- +- if (params->has_max_cpu_throttle && +- (params->max_cpu_throttle < params->cpu_throttle_initial || +- params->max_cpu_throttle > 99)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "max_cpu_throttle", +- "an integer in the range of cpu_throttle_initial to 99"); +- return false; +- } +- +- if (params->has_announce_initial && +- params->announce_initial > 100000) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "announce_initial", +- "a value between 0 and 100000"); +- return false; +- } +- if (params->has_announce_max && +- params->announce_max > 100000) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "announce_max", +- "a value between 0 and 100000"); +- return false; +- } +- if (params->has_announce_rounds && +- params->announce_rounds > 1000) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "announce_rounds", +- "a value between 0 and 1000"); +- return false; +- } +- if (params->has_announce_step && +- (params->announce_step < 1 || +- params->announce_step > 10000)) { +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, +- "announce_step", +- "a value between 0 and 10000"); +- return false; +- } +- +- if (params->has_block_bitmap_mapping && +- !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { +- error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); +- return false; +- } +- +-#ifdef CONFIG_LINUX +- if (migrate_zero_copy_send() && +- ((params->has_multifd_compression && params->multifd_compression) || +- (params->tls_creds && *params->tls_creds))) { +- error_setg(errp, +- "Zero copy only available for non-compressed non-TLS multifd migration"); +- return false; +- } +-#endif +- +- return true; +-} +- +-static void migrate_params_test_apply(MigrateSetParameters *params, +- MigrationParameters *dest) +-{ +- *dest = migrate_get_current()->parameters; +- +- /* TODO use QAPI_CLONE() instead of duplicating it inline */ +- +- if (params->has_compress_level) { +- dest->compress_level = params->compress_level; +- } +- +- if (params->has_compress_threads) { +- dest->compress_threads = params->compress_threads; +- } +- +- if (params->has_compress_wait_thread) { +- dest->compress_wait_thread = params->compress_wait_thread; +- } +- +- if (params->has_decompress_threads) { +- dest->decompress_threads = params->decompress_threads; +- } +- +- if (params->has_throttle_trigger_threshold) { +- dest->throttle_trigger_threshold = params->throttle_trigger_threshold; +- } +- +- if (params->has_cpu_throttle_initial) { +- dest->cpu_throttle_initial = params->cpu_throttle_initial; +- } +- +- if (params->has_cpu_throttle_increment) { +- dest->cpu_throttle_increment = params->cpu_throttle_increment; +- } +- +- if (params->has_cpu_throttle_tailslow) { +- dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; +- } +- +- if (params->tls_creds) { +- assert(params->tls_creds->type == QTYPE_QSTRING); +- dest->tls_creds = params->tls_creds->u.s; +- } +- +- if (params->tls_hostname) { +- assert(params->tls_hostname->type == QTYPE_QSTRING); +- dest->tls_hostname = params->tls_hostname->u.s; +- } +- +- if (params->has_max_bandwidth) { +- dest->max_bandwidth = params->max_bandwidth; +- } +- +- if (params->has_downtime_limit) { +- dest->downtime_limit = params->downtime_limit; +- } +- +- if (params->has_x_checkpoint_delay) { +- dest->x_checkpoint_delay = params->x_checkpoint_delay; +- } +- +- if (params->has_block_incremental) { +- dest->block_incremental = params->block_incremental; +- } +- if (params->has_multifd_channels) { +- dest->multifd_channels = params->multifd_channels; +- } +- if (params->has_multifd_compression) { +- dest->multifd_compression = params->multifd_compression; +- } +- if (params->has_xbzrle_cache_size) { +- dest->xbzrle_cache_size = params->xbzrle_cache_size; +- } +- if (params->has_max_postcopy_bandwidth) { +- dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; +- } +- if (params->has_max_cpu_throttle) { +- dest->max_cpu_throttle = params->max_cpu_throttle; +- } +- if (params->has_announce_initial) { +- dest->announce_initial = params->announce_initial; +- } +- if (params->has_announce_max) { +- dest->announce_max = params->announce_max; +- } +- if (params->has_announce_rounds) { +- dest->announce_rounds = params->announce_rounds; +- } +- if (params->has_announce_step) { +- dest->announce_step = params->announce_step; +- } +- +- if (params->has_block_bitmap_mapping) { +- dest->has_block_bitmap_mapping = true; +- dest->block_bitmap_mapping = params->block_bitmap_mapping; +- } +-} +- +-static void migrate_params_apply(MigrateSetParameters *params, Error **errp) +-{ +- MigrationState *s = migrate_get_current(); +- +- /* TODO use QAPI_CLONE() instead of duplicating it inline */ +- +- if (params->has_compress_level) { +- s->parameters.compress_level = params->compress_level; +- } +- +- if (params->has_compress_threads) { +- s->parameters.compress_threads = params->compress_threads; +- } +- +- if (params->has_compress_wait_thread) { +- s->parameters.compress_wait_thread = params->compress_wait_thread; +- } +- +- if (params->has_decompress_threads) { +- s->parameters.decompress_threads = params->decompress_threads; +- } +- +- if (params->has_throttle_trigger_threshold) { +- s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; +- } +- +- if (params->has_cpu_throttle_initial) { +- s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; +- } +- +- if (params->has_cpu_throttle_increment) { +- s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; +- } +- +- if (params->has_cpu_throttle_tailslow) { +- s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; +- } +- +- if (params->tls_creds) { +- g_free(s->parameters.tls_creds); +- assert(params->tls_creds->type == QTYPE_QSTRING); +- s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); +- } +- +- if (params->tls_hostname) { +- g_free(s->parameters.tls_hostname); +- assert(params->tls_hostname->type == QTYPE_QSTRING); +- s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); +- } +- +- if (params->tls_authz) { +- g_free(s->parameters.tls_authz); +- assert(params->tls_authz->type == QTYPE_QSTRING); +- s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); +- } +- +- if (params->has_max_bandwidth) { +- s->parameters.max_bandwidth = params->max_bandwidth; +- if (s->to_dst_file && !migration_in_postcopy()) { +- qemu_file_set_rate_limit(s->to_dst_file, +- s->parameters.max_bandwidth / XFER_LIMIT_RATIO); +- } +- } +- +- if (params->has_downtime_limit) { +- s->parameters.downtime_limit = params->downtime_limit; +- } +- +- if (params->has_x_checkpoint_delay) { +- s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; +- if (migration_in_colo_state()) { +- colo_checkpoint_notify(s); +- } +- } +- +- if (params->has_block_incremental) { +- s->parameters.block_incremental = params->block_incremental; +- } +- if (params->has_multifd_channels) { +- s->parameters.multifd_channels = params->multifd_channels; +- } +- if (params->has_multifd_compression) { +- s->parameters.multifd_compression = params->multifd_compression; +- } +- if (params->has_xbzrle_cache_size) { +- s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; +- xbzrle_cache_resize(params->xbzrle_cache_size, errp); +- } +- if (params->has_max_postcopy_bandwidth) { +- s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; +- if (s->to_dst_file && migration_in_postcopy()) { +- qemu_file_set_rate_limit(s->to_dst_file, +- s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO); +- } +- } +- if (params->has_max_cpu_throttle) { +- s->parameters.max_cpu_throttle = params->max_cpu_throttle; +- } +- if (params->has_announce_initial) { +- s->parameters.announce_initial = params->announce_initial; +- } +- if (params->has_announce_max) { +- s->parameters.announce_max = params->announce_max; +- } +- if (params->has_announce_rounds) { +- s->parameters.announce_rounds = params->announce_rounds; +- } +- if (params->has_announce_step) { +- s->parameters.announce_step = params->announce_step; +- } +- +- if (params->has_block_bitmap_mapping) { +- qapi_free_BitmapMigrationNodeAliasList( +- s->parameters.block_bitmap_mapping); +- +- s->parameters.has_block_bitmap_mapping = true; +- s->parameters.block_bitmap_mapping = +- QAPI_CLONE(BitmapMigrationNodeAliasList, +- params->block_bitmap_mapping); +- } +-} +- +-void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) +-{ +- MigrationParameters tmp; +- +- /* TODO Rewrite "" to null instead */ +- if (params->tls_creds +- && params->tls_creds->type == QTYPE_QNULL) { +- qobject_unref(params->tls_creds->u.n); +- params->tls_creds->type = QTYPE_QSTRING; +- params->tls_creds->u.s = strdup(""); +- } +- /* TODO Rewrite "" to null instead */ +- if (params->tls_hostname +- && params->tls_hostname->type == QTYPE_QNULL) { +- qobject_unref(params->tls_hostname->u.n); +- params->tls_hostname->type = QTYPE_QSTRING; +- params->tls_hostname->u.s = strdup(""); +- } +- +- migrate_params_test_apply(params, &tmp); +- +- if (!migrate_params_check(&tmp, errp)) { +- /* Invalid parameter */ +- return; +- } +- +- migrate_params_apply(params, errp); +-} +- +- + void qmp_migrate_start_postcopy(Error **errp) + { + MigrationState *s = migrate_get_current(); +diff --git a/migration/options.c b/migration/options.c +index d4c0714683..4701c75a4d 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -12,17 +12,25 @@ + */ + + #include "qemu/osdep.h" ++#include "exec/target_page.h" + #include "qapi/clone-visitor.h" + #include "qapi/error.h" + #include "qapi/qapi-commands-migration.h" + #include "qapi/qapi-visit-migration.h" + #include "qapi/qmp/qerror.h" ++#include "qapi/qmp/qnull.h" + #include "sysemu/runstate.h" ++#include "migration/colo.h" + #include "migration/misc.h" + #include "migration.h" ++#include "qemu-file.h" + #include "ram.h" + #include "options.h" + ++/* Maximum migrate downtime set to 2000 seconds */ ++#define MAX_MIGRATE_DOWNTIME_SECONDS 2000 ++#define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000) ++ + bool migrate_auto_converge(void) + { + MigrationState *s; +@@ -729,3 +737,413 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) + + return params; + } ++ ++/* ++ * Check whether the parameters are valid. Error will be put into errp ++ * (if provided). Return true if valid, otherwise false. ++ */ ++bool migrate_params_check(MigrationParameters *params, Error **errp) ++{ ++ if (params->has_compress_level && ++ (params->compress_level > 9)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", ++ "a value between 0 and 9"); ++ return false; ++ } ++ ++ if (params->has_compress_threads && (params->compress_threads < 1)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "compress_threads", ++ "a value between 1 and 255"); ++ return false; ++ } ++ ++ if (params->has_decompress_threads && (params->decompress_threads < 1)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "decompress_threads", ++ "a value between 1 and 255"); ++ return false; ++ } ++ ++ if (params->has_throttle_trigger_threshold && ++ (params->throttle_trigger_threshold < 1 || ++ params->throttle_trigger_threshold > 100)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "throttle_trigger_threshold", ++ "an integer in the range of 1 to 100"); ++ return false; ++ } ++ ++ if (params->has_cpu_throttle_initial && ++ (params->cpu_throttle_initial < 1 || ++ params->cpu_throttle_initial > 99)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "cpu_throttle_initial", ++ "an integer in the range of 1 to 99"); ++ return false; ++ } ++ ++ if (params->has_cpu_throttle_increment && ++ (params->cpu_throttle_increment < 1 || ++ params->cpu_throttle_increment > 99)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "cpu_throttle_increment", ++ "an integer in the range of 1 to 99"); ++ return false; ++ } ++ ++ if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "max_bandwidth", ++ "an integer in the range of 0 to "stringify(SIZE_MAX) ++ " bytes/second"); ++ return false; ++ } ++ ++ if (params->has_downtime_limit && ++ (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "downtime_limit", ++ "an integer in the range of 0 to " ++ stringify(MAX_MIGRATE_DOWNTIME)" ms"); ++ return false; ++ } ++ ++ /* x_checkpoint_delay is now always positive */ ++ ++ if (params->has_multifd_channels && (params->multifd_channels < 1)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "multifd_channels", ++ "a value between 1 and 255"); ++ return false; ++ } ++ ++ if (params->has_multifd_zlib_level && ++ (params->multifd_zlib_level > 9)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level", ++ "a value between 0 and 9"); ++ return false; ++ } ++ ++ if (params->has_multifd_zstd_level && ++ (params->multifd_zstd_level > 20)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level", ++ "a value between 0 and 20"); ++ return false; ++ } ++ ++ if (params->has_xbzrle_cache_size && ++ (params->xbzrle_cache_size < qemu_target_page_size() || ++ !is_power_of_2(params->xbzrle_cache_size))) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "xbzrle_cache_size", ++ "a power of two no less than the target page size"); ++ return false; ++ } ++ ++ if (params->has_max_cpu_throttle && ++ (params->max_cpu_throttle < params->cpu_throttle_initial || ++ params->max_cpu_throttle > 99)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "max_cpu_throttle", ++ "an integer in the range of cpu_throttle_initial to 99"); ++ return false; ++ } ++ ++ if (params->has_announce_initial && ++ params->announce_initial > 100000) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "announce_initial", ++ "a value between 0 and 100000"); ++ return false; ++ } ++ if (params->has_announce_max && ++ params->announce_max > 100000) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "announce_max", ++ "a value between 0 and 100000"); ++ return false; ++ } ++ if (params->has_announce_rounds && ++ params->announce_rounds > 1000) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "announce_rounds", ++ "a value between 0 and 1000"); ++ return false; ++ } ++ if (params->has_announce_step && ++ (params->announce_step < 1 || ++ params->announce_step > 10000)) { ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, ++ "announce_step", ++ "a value between 0 and 10000"); ++ return false; ++ } ++ ++ if (params->has_block_bitmap_mapping && ++ !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) { ++ error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: "); ++ return false; ++ } ++ ++#ifdef CONFIG_LINUX ++ if (migrate_zero_copy_send() && ++ ((params->has_multifd_compression && params->multifd_compression) || ++ (params->tls_creds && *params->tls_creds))) { ++ error_setg(errp, ++ "Zero copy only available for non-compressed non-TLS multifd migration"); ++ return false; ++ } ++#endif ++ ++ return true; ++} ++ ++static void migrate_params_test_apply(MigrateSetParameters *params, ++ MigrationParameters *dest) ++{ ++ *dest = migrate_get_current()->parameters; ++ ++ /* TODO use QAPI_CLONE() instead of duplicating it inline */ ++ ++ if (params->has_compress_level) { ++ dest->compress_level = params->compress_level; ++ } ++ ++ if (params->has_compress_threads) { ++ dest->compress_threads = params->compress_threads; ++ } ++ ++ if (params->has_compress_wait_thread) { ++ dest->compress_wait_thread = params->compress_wait_thread; ++ } ++ ++ if (params->has_decompress_threads) { ++ dest->decompress_threads = params->decompress_threads; ++ } ++ ++ if (params->has_throttle_trigger_threshold) { ++ dest->throttle_trigger_threshold = params->throttle_trigger_threshold; ++ } ++ ++ if (params->has_cpu_throttle_initial) { ++ dest->cpu_throttle_initial = params->cpu_throttle_initial; ++ } ++ ++ if (params->has_cpu_throttle_increment) { ++ dest->cpu_throttle_increment = params->cpu_throttle_increment; ++ } ++ ++ if (params->has_cpu_throttle_tailslow) { ++ dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow; ++ } ++ ++ if (params->tls_creds) { ++ assert(params->tls_creds->type == QTYPE_QSTRING); ++ dest->tls_creds = params->tls_creds->u.s; ++ } ++ ++ if (params->tls_hostname) { ++ assert(params->tls_hostname->type == QTYPE_QSTRING); ++ dest->tls_hostname = params->tls_hostname->u.s; ++ } ++ ++ if (params->has_max_bandwidth) { ++ dest->max_bandwidth = params->max_bandwidth; ++ } ++ ++ if (params->has_downtime_limit) { ++ dest->downtime_limit = params->downtime_limit; ++ } ++ ++ if (params->has_x_checkpoint_delay) { ++ dest->x_checkpoint_delay = params->x_checkpoint_delay; ++ } ++ ++ if (params->has_block_incremental) { ++ dest->block_incremental = params->block_incremental; ++ } ++ if (params->has_multifd_channels) { ++ dest->multifd_channels = params->multifd_channels; ++ } ++ if (params->has_multifd_compression) { ++ dest->multifd_compression = params->multifd_compression; ++ } ++ if (params->has_xbzrle_cache_size) { ++ dest->xbzrle_cache_size = params->xbzrle_cache_size; ++ } ++ if (params->has_max_postcopy_bandwidth) { ++ dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth; ++ } ++ if (params->has_max_cpu_throttle) { ++ dest->max_cpu_throttle = params->max_cpu_throttle; ++ } ++ if (params->has_announce_initial) { ++ dest->announce_initial = params->announce_initial; ++ } ++ if (params->has_announce_max) { ++ dest->announce_max = params->announce_max; ++ } ++ if (params->has_announce_rounds) { ++ dest->announce_rounds = params->announce_rounds; ++ } ++ if (params->has_announce_step) { ++ dest->announce_step = params->announce_step; ++ } ++ ++ if (params->has_block_bitmap_mapping) { ++ dest->has_block_bitmap_mapping = true; ++ dest->block_bitmap_mapping = params->block_bitmap_mapping; ++ } ++} ++ ++static void migrate_params_apply(MigrateSetParameters *params, Error **errp) ++{ ++ MigrationState *s = migrate_get_current(); ++ ++ /* TODO use QAPI_CLONE() instead of duplicating it inline */ ++ ++ if (params->has_compress_level) { ++ s->parameters.compress_level = params->compress_level; ++ } ++ ++ if (params->has_compress_threads) { ++ s->parameters.compress_threads = params->compress_threads; ++ } ++ ++ if (params->has_compress_wait_thread) { ++ s->parameters.compress_wait_thread = params->compress_wait_thread; ++ } ++ ++ if (params->has_decompress_threads) { ++ s->parameters.decompress_threads = params->decompress_threads; ++ } ++ ++ if (params->has_throttle_trigger_threshold) { ++ s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; ++ } ++ ++ if (params->has_cpu_throttle_initial) { ++ s->parameters.cpu_throttle_initial = params->cpu_throttle_initial; ++ } ++ ++ if (params->has_cpu_throttle_increment) { ++ s->parameters.cpu_throttle_increment = params->cpu_throttle_increment; ++ } ++ ++ if (params->has_cpu_throttle_tailslow) { ++ s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow; ++ } ++ ++ if (params->tls_creds) { ++ g_free(s->parameters.tls_creds); ++ assert(params->tls_creds->type == QTYPE_QSTRING); ++ s->parameters.tls_creds = g_strdup(params->tls_creds->u.s); ++ } ++ ++ if (params->tls_hostname) { ++ g_free(s->parameters.tls_hostname); ++ assert(params->tls_hostname->type == QTYPE_QSTRING); ++ s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s); ++ } ++ ++ if (params->tls_authz) { ++ g_free(s->parameters.tls_authz); ++ assert(params->tls_authz->type == QTYPE_QSTRING); ++ s->parameters.tls_authz = g_strdup(params->tls_authz->u.s); ++ } ++ ++ if (params->has_max_bandwidth) { ++ s->parameters.max_bandwidth = params->max_bandwidth; ++ if (s->to_dst_file && !migration_in_postcopy()) { ++ qemu_file_set_rate_limit(s->to_dst_file, ++ s->parameters.max_bandwidth / XFER_LIMIT_RATIO); ++ } ++ } ++ ++ if (params->has_downtime_limit) { ++ s->parameters.downtime_limit = params->downtime_limit; ++ } ++ ++ if (params->has_x_checkpoint_delay) { ++ s->parameters.x_checkpoint_delay = params->x_checkpoint_delay; ++ if (migration_in_colo_state()) { ++ colo_checkpoint_notify(s); ++ } ++ } ++ ++ if (params->has_block_incremental) { ++ s->parameters.block_incremental = params->block_incremental; ++ } ++ if (params->has_multifd_channels) { ++ s->parameters.multifd_channels = params->multifd_channels; ++ } ++ if (params->has_multifd_compression) { ++ s->parameters.multifd_compression = params->multifd_compression; ++ } ++ if (params->has_xbzrle_cache_size) { ++ s->parameters.xbzrle_cache_size = params->xbzrle_cache_size; ++ xbzrle_cache_resize(params->xbzrle_cache_size, errp); ++ } ++ if (params->has_max_postcopy_bandwidth) { ++ s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth; ++ if (s->to_dst_file && migration_in_postcopy()) { ++ qemu_file_set_rate_limit(s->to_dst_file, ++ s->parameters.max_postcopy_bandwidth / XFER_LIMIT_RATIO); ++ } ++ } ++ if (params->has_max_cpu_throttle) { ++ s->parameters.max_cpu_throttle = params->max_cpu_throttle; ++ } ++ if (params->has_announce_initial) { ++ s->parameters.announce_initial = params->announce_initial; ++ } ++ if (params->has_announce_max) { ++ s->parameters.announce_max = params->announce_max; ++ } ++ if (params->has_announce_rounds) { ++ s->parameters.announce_rounds = params->announce_rounds; ++ } ++ if (params->has_announce_step) { ++ s->parameters.announce_step = params->announce_step; ++ } ++ ++ if (params->has_block_bitmap_mapping) { ++ qapi_free_BitmapMigrationNodeAliasList( ++ s->parameters.block_bitmap_mapping); ++ ++ s->parameters.has_block_bitmap_mapping = true; ++ s->parameters.block_bitmap_mapping = ++ QAPI_CLONE(BitmapMigrationNodeAliasList, ++ params->block_bitmap_mapping); ++ } ++} ++ ++void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) ++{ ++ MigrationParameters tmp; ++ ++ /* TODO Rewrite "" to null instead */ ++ if (params->tls_creds ++ && params->tls_creds->type == QTYPE_QNULL) { ++ qobject_unref(params->tls_creds->u.n); ++ params->tls_creds->type = QTYPE_QSTRING; ++ params->tls_creds->u.s = strdup(""); ++ } ++ /* TODO Rewrite "" to null instead */ ++ if (params->tls_hostname ++ && params->tls_hostname->type == QTYPE_QNULL) { ++ qobject_unref(params->tls_hostname->u.n); ++ params->tls_hostname->type = QTYPE_QSTRING; ++ params->tls_hostname->u.s = strdup(""); ++ } ++ ++ migrate_params_test_apply(params, &tmp); ++ ++ if (!migrate_params_check(&tmp, errp)) { ++ /* Invalid parameter */ ++ return; ++ } ++ ++ migrate_params_apply(params, errp); ++} +diff --git a/migration/options.h b/migration/options.h +index 13318a16c7..89067e59a0 100644 +--- a/migration/options.h ++++ b/migration/options.h +@@ -14,6 +14,13 @@ + #ifndef QEMU_MIGRATION_OPTIONS_H + #define QEMU_MIGRATION_OPTIONS_H + ++/* constants */ ++ ++/* Amount of time to allocate to each "chunk" of bandwidth-throttled ++ * data. */ ++#define BUFFER_DELAY 100 ++#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY) ++ + /* capabilities */ + + bool migrate_auto_converge(void); +@@ -74,4 +81,8 @@ int migrate_multifd_zstd_level(void); + uint8_t migrate_throttle_trigger_threshold(void); + uint64_t migrate_xbzrle_cache_size(void); + ++/* parameters helpers */ ++ ++bool migrate_params_check(MigrationParameters *params, Error **errp); ++ + #endif +-- +2.39.1 + diff --git a/kvm-migration-Move-qmp_query_migrate_capabilities-to-opt.patch b/kvm-migration-Move-qmp_query_migrate_capabilities-to-opt.patch new file mode 100644 index 0000000..d2564de --- /dev/null +++ b/kvm-migration-Move-qmp_query_migrate_capabilities-to-opt.patch @@ -0,0 +1,100 @@ +From 00cc3c3598828588619a7b3696819060bddaddb8 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 23:15:59 +0100 +Subject: [PATCH 34/56] migration: Move qmp_query_migrate_capabilities() to + options.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [33/50] dbfa8f1e7aa7e000b4622ce2da12d7d418710f19 (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 4d0c6b695bf5252402ebf967f83baebfd2f4b91e) +Signed-off-by: Peter Xu +--- + migration/migration.c | 22 ---------------------- + migration/options.c | 23 +++++++++++++++++++++++ + 2 files changed, 23 insertions(+), 22 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index d9e30ca918..3dc8ee4875 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -886,28 +886,6 @@ void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value) + migrate_send_rp_message(mis, MIG_RP_MSG_RESUME_ACK, sizeof(buf), &buf); + } + +-MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) +-{ +- MigrationCapabilityStatusList *head = NULL, **tail = &head; +- MigrationCapabilityStatus *caps; +- MigrationState *s = migrate_get_current(); +- int i; +- +- for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { +-#ifndef CONFIG_LIVE_BLOCK_MIGRATION +- if (i == MIGRATION_CAPABILITY_BLOCK) { +- continue; +- } +-#endif +- caps = g_malloc0(sizeof(*caps)); +- caps->capability = i; +- caps->state = s->capabilities[i]; +- QAPI_LIST_APPEND(tail, caps); +- } +- +- return head; +-} +- + MigrationParameters *qmp_query_migrate_parameters(Error **errp) + { + MigrationParameters *params; +diff --git a/migration/options.c b/migration/options.c +index 367c930f46..ff621bdeb3 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -13,6 +13,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" ++#include "qapi/qapi-commands-migration.h" + #include "sysemu/runstate.h" + #include "migration.h" + #include "ram.h" +@@ -390,3 +391,25 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) + + return true; + } ++ ++MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) ++{ ++ MigrationCapabilityStatusList *head = NULL, **tail = &head; ++ MigrationCapabilityStatus *caps; ++ MigrationState *s = migrate_get_current(); ++ int i; ++ ++ for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { ++#ifndef CONFIG_LIVE_BLOCK_MIGRATION ++ if (i == MIGRATION_CAPABILITY_BLOCK) { ++ continue; ++ } ++#endif ++ caps = g_malloc0(sizeof(*caps)); ++ caps->capability = i; ++ caps->state = s->capabilities[i]; ++ QAPI_LIST_APPEND(tail, caps); ++ } ++ ++ return head; ++} +-- +2.39.1 + diff --git a/kvm-migration-Pass-migrate_caps_check-the-old-and-new-ca.patch b/kvm-migration-Pass-migrate_caps_check-the-old-and-new-ca.patch new file mode 100644 index 0000000..7339ce0 --- /dev/null +++ b/kvm-migration-Pass-migrate_caps_check-the-old-and-new-ca.patch @@ -0,0 +1,226 @@ +From 4782b59a8b0b5762f87505ac7a83b37ddd2e0b3f Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 20:28:56 +0100 +Subject: [PATCH 19/56] migration: Pass migrate_caps_check() the old and new + caps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [18/50] df78d680d03f15d7cb7401ad89e68a4fc93fa835 (peterx/qemu-kvm) + +We used to pass the old capabilities array and the new +capabilities as a list. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit b02c7fc9ef447787414e6fa67eff75e7b7b30180) +Signed-off-by: Peter Xu +--- + migration/migration.c | 80 +++++++++++++++++-------------------------- + 1 file changed, 31 insertions(+), 49 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index d8e5fb6226..e8f596bcfa 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1299,30 +1299,20 @@ WriteTrackingSupport migrate_query_write_tracking(void) + } + + /** +- * @migration_caps_check - check capability validity ++ * @migration_caps_check - check capability compatibility + * +- * @cap_list: old capability list, array of bool +- * @params: new capabilities to be applied soon ++ * @old_caps: old capability list ++ * @new_caps: new capability list + * @errp: set *errp if the check failed, with reason + * + * Returns true if check passed, otherwise false. + */ +-static bool migrate_caps_check(bool *cap_list, +- MigrationCapabilityStatusList *params, +- Error **errp) ++static bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) + { +- MigrationCapabilityStatusList *cap; +- bool old_postcopy_cap; + MigrationIncomingState *mis = migration_incoming_get_current(); + +- old_postcopy_cap = cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]; +- +- for (cap = params; cap; cap = cap->next) { +- cap_list[cap->value->capability] = cap->value->state; +- } +- + #ifndef CONFIG_LIVE_BLOCK_MIGRATION +- if (cap_list[MIGRATION_CAPABILITY_BLOCK]) { ++ if (new_caps[MIGRATION_CAPABILITY_BLOCK]) { + error_setg(errp, "QEMU compiled without old-style (blk/-b, inc/-i) " + "block migration"); + error_append_hint(errp, "Use drive_mirror+NBD instead.\n"); +@@ -1331,7 +1321,7 @@ static bool migrate_caps_check(bool *cap_list, + #endif + + #ifndef CONFIG_REPLICATION +- if (cap_list[MIGRATION_CAPABILITY_X_COLO]) { ++ if (new_caps[MIGRATION_CAPABILITY_X_COLO]) { + error_setg(errp, "QEMU compiled without replication module" + " can't enable COLO"); + error_append_hint(errp, "Please enable replication before COLO.\n"); +@@ -1339,12 +1329,13 @@ static bool migrate_caps_check(bool *cap_list, + } + #endif + +- if (cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { ++ if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { + /* This check is reasonably expensive, so only when it's being + * set the first time, also it's only the destination that needs + * special support. + */ +- if (!old_postcopy_cap && runstate_check(RUN_STATE_INMIGRATE) && ++ if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] && ++ runstate_check(RUN_STATE_INMIGRATE) && + !postcopy_ram_supported_by_host(mis)) { + /* postcopy_ram_supported_by_host will have emitted a more + * detailed message +@@ -1353,13 +1344,13 @@ static bool migrate_caps_check(bool *cap_list, + return false; + } + +- if (cap_list[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) { ++ if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) { + error_setg(errp, "Postcopy is not compatible with ignore-shared"); + return false; + } + } + +- if (cap_list[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { ++ if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { + WriteTrackingSupport wt_support; + int idx; + /* +@@ -1383,7 +1374,7 @@ static bool migrate_caps_check(bool *cap_list, + */ + for (idx = 0; idx < check_caps_background_snapshot.size; idx++) { + int incomp_cap = check_caps_background_snapshot.caps[idx]; +- if (cap_list[incomp_cap]) { ++ if (new_caps[incomp_cap]) { + error_setg(errp, + "Background-snapshot is not compatible with %s", + MigrationCapability_str(incomp_cap)); +@@ -1393,10 +1384,10 @@ static bool migrate_caps_check(bool *cap_list, + } + + #ifdef CONFIG_LINUX +- if (cap_list[MIGRATION_CAPABILITY_ZERO_COPY_SEND] && +- (!cap_list[MIGRATION_CAPABILITY_MULTIFD] || +- cap_list[MIGRATION_CAPABILITY_COMPRESS] || +- cap_list[MIGRATION_CAPABILITY_XBZRLE] || ++ if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] && ++ (!new_caps[MIGRATION_CAPABILITY_MULTIFD] || ++ new_caps[MIGRATION_CAPABILITY_COMPRESS] || ++ new_caps[MIGRATION_CAPABILITY_XBZRLE] || + migrate_multifd_compression() || + migrate_use_tls())) { + error_setg(errp, +@@ -1404,15 +1395,15 @@ static bool migrate_caps_check(bool *cap_list, + return false; + } + #else +- if (cap_list[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) { ++ if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) { + error_setg(errp, + "Zero copy currently only available on Linux"); + return false; + } + #endif + +- if (cap_list[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) { +- if (!cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { ++ if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) { ++ if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) { + error_setg(errp, "Postcopy preempt requires postcopy-ram"); + return false; + } +@@ -1423,14 +1414,14 @@ static bool migrate_caps_check(bool *cap_list, + * different compression channels, which is not compatible with the + * preempt assumptions on channel assignments. + */ +- if (cap_list[MIGRATION_CAPABILITY_COMPRESS]) { ++ if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { + error_setg(errp, "Postcopy preempt not compatible with compress"); + return false; + } + } + +- if (cap_list[MIGRATION_CAPABILITY_MULTIFD]) { +- if (cap_list[MIGRATION_CAPABILITY_COMPRESS]) { ++ if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { ++ if (new_caps[MIGRATION_CAPABILITY_COMPRESS]) { + error_setg(errp, "Multifd is not compatible with compress"); + return false; + } +@@ -1486,15 +1477,19 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, + { + MigrationState *s = migrate_get_current(); + MigrationCapabilityStatusList *cap; +- bool cap_list[MIGRATION_CAPABILITY__MAX]; ++ bool new_caps[MIGRATION_CAPABILITY__MAX]; + + if (migration_is_running(s->state)) { + error_setg(errp, QERR_MIGRATION_ACTIVE); + return; + } + +- memcpy(cap_list, s->capabilities, sizeof(cap_list)); +- if (!migrate_caps_check(cap_list, params, errp)) { ++ memcpy(new_caps, s->capabilities, sizeof(new_caps)); ++ for (cap = params; cap; cap = cap->next) { ++ new_caps[cap->value->capability] = cap->value->state; ++ } ++ ++ if (!migrate_caps_check(s->capabilities, new_caps, errp)) { + return; + } + +@@ -4634,27 +4629,14 @@ static void migration_instance_init(Object *obj) + */ + static bool migration_object_check(MigrationState *ms, Error **errp) + { +- MigrationCapabilityStatusList *head = NULL; + /* Assuming all off */ +- bool cap_list[MIGRATION_CAPABILITY__MAX] = { 0 }, ret; +- int i; ++ bool old_caps[MIGRATION_CAPABILITY__MAX] = { 0 }; + + if (!migrate_params_check(&ms->parameters, errp)) { + return false; + } + +- for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { +- if (ms->capabilities[i]) { +- QAPI_LIST_PREPEND(head, migrate_cap_add(i, true)); +- } +- } +- +- ret = migrate_caps_check(cap_list, head, errp); +- +- /* It works with head == NULL */ +- qapi_free_MigrationCapabilityStatusList(head); +- +- return ret; ++ return migrate_caps_check(old_caps, ms->capabilities, errp); + } + + static const TypeInfo migration_type = { +-- +2.39.1 + diff --git a/kvm-migration-Rename-duplicate-to-zero_pages.patch b/kvm-migration-Rename-duplicate-to-zero_pages.patch new file mode 100644 index 0000000..22acab5 --- /dev/null +++ b/kvm-migration-Rename-duplicate-to-zero_pages.patch @@ -0,0 +1,109 @@ +From 3cecf66655a0dd599666bcac8add2dee85d5651f Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 19 Apr 2023 18:16:05 +0200 +Subject: [PATCH 16/56] migration: Rename duplicate to zero_pages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [15/50] 89db3c8b167c0f411ba95ce2730540c0e8f1206b (peterx/qemu-kvm) + +Rest of counters that refer to pages has a _pages suffix. +And historically, this showed the number of pages composed of the same +character, here comes the name "duplicated". But since years ago, it +refers to the number of zero_pages. + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +(cherry picked from commit 1a386e8de5995fb5478ea99baa6d3e71abcf4b80) +Signed-off-by: Peter Xu +--- + migration/migration.c | 2 +- + migration/ram.c | 10 +++++----- + migration/ram.h | 2 +- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 39501a0ed8..c15e2a61ca 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1142,7 +1142,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram = g_malloc0(sizeof(*info->ram)); + info->ram->transferred = stat64_get(&ram_counters.transferred); + info->ram->total = ram_bytes_total(); +- info->ram->duplicate = stat64_get(&ram_counters.duplicate); ++ info->ram->duplicate = stat64_get(&ram_counters.zero_pages); + /* legacy value. It is not used anymore */ + info->ram->skipped = 0; + info->ram->normal = stat64_get(&ram_counters.normal); +diff --git a/migration/ram.c b/migration/ram.c +index fe69ecaef4..19d345a030 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1119,7 +1119,7 @@ uint64_t ram_pagesize_summary(void) + uint64_t ram_get_total_transferred_pages(void) + { + return stat64_get(&ram_counters.normal) + +- stat64_get(&ram_counters.duplicate) + ++ stat64_get(&ram_counters.zero_pages) + + compression_counters.pages + xbzrle_counters.pages; + } + +@@ -1320,7 +1320,7 @@ static int save_zero_page(PageSearchStatus *pss, QEMUFile *f, RAMBlock *block, + int len = save_zero_page_to_file(pss, f, block, offset); + + if (len) { +- stat64_add(&ram_counters.duplicate, 1); ++ stat64_add(&ram_counters.zero_pages, 1); + ram_transferred_add(len); + return 1; + } +@@ -1359,7 +1359,7 @@ static bool control_save_page(PageSearchStatus *pss, RAMBlock *block, + if (bytes_xmit > 0) { + stat64_add(&ram_counters.normal, 1); + } else if (bytes_xmit == 0) { +- stat64_add(&ram_counters.duplicate, 1); ++ stat64_add(&ram_counters.zero_pages, 1); + } + + return true; +@@ -1486,7 +1486,7 @@ update_compress_thread_counts(const CompressParam *param, int bytes_xmit) + ram_transferred_add(bytes_xmit); + + if (param->zero_page) { +- stat64_add(&ram_counters.duplicate, 1); ++ stat64_add(&ram_counters.zero_pages, 1); + return; + } + +@@ -2621,7 +2621,7 @@ void acct_update_position(QEMUFile *f, size_t size, bool zero) + uint64_t pages = size / TARGET_PAGE_SIZE; + + if (zero) { +- stat64_add(&ram_counters.duplicate, pages); ++ stat64_add(&ram_counters.zero_pages, pages); + } else { + stat64_add(&ram_counters.normal, pages); + ram_transferred_add(size); +diff --git a/migration/ram.h b/migration/ram.h +index afa68521d7..55258334fe 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -45,7 +45,7 @@ typedef struct { + Stat64 dirty_sync_count; + Stat64 dirty_sync_missed_zero_copy; + Stat64 downtime_bytes; +- Stat64 duplicate; ++ Stat64 zero_pages; + Stat64 multifd_bytes; + Stat64 normal; + Stat64 postcopy_bytes; +-- +2.39.1 + diff --git a/kvm-migration-Rename-normal-to-normal_pages.patch b/kvm-migration-Rename-normal-to-normal_pages.patch new file mode 100644 index 0000000..8ad6447 --- /dev/null +++ b/kvm-migration-Rename-normal-to-normal_pages.patch @@ -0,0 +1,109 @@ +From 7e27e7ea83856e1a7222ff46d91495f48fb6be4d Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 19 Apr 2023 18:19:45 +0200 +Subject: [PATCH 17/56] migration: Rename normal to normal_pages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [16/50] 7df8b946918def9657bbe357861a6d72b5399ac6 (peterx/qemu-kvm) + +Rest of counters that refer to pages has a _pages suffix. +And historically, this showed the number of full pages transferred. +The name "normal" refered to the fact that they were sent without any +optimization (compression, xbzrle, zero_page, ...). + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +(cherry picked from commit 8c0cda8fa0de0a50148e2c60552afca9cffca643) +Signed-off-by: Peter Xu +--- + migration/migration.c | 2 +- + migration/ram.c | 10 +++++----- + migration/ram.h | 2 +- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index c15e2a61ca..f1b3439e5f 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1145,7 +1145,7 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s) + info->ram->duplicate = stat64_get(&ram_counters.zero_pages); + /* legacy value. It is not used anymore */ + info->ram->skipped = 0; +- info->ram->normal = stat64_get(&ram_counters.normal); ++ info->ram->normal = stat64_get(&ram_counters.normal_pages); + info->ram->normal_bytes = info->ram->normal * page_size; + info->ram->mbps = s->mbps; + info->ram->dirty_sync_count = +diff --git a/migration/ram.c b/migration/ram.c +index 19d345a030..229714045a 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1118,7 +1118,7 @@ uint64_t ram_pagesize_summary(void) + + uint64_t ram_get_total_transferred_pages(void) + { +- return stat64_get(&ram_counters.normal) + ++ return stat64_get(&ram_counters.normal_pages) + + stat64_get(&ram_counters.zero_pages) + + compression_counters.pages + xbzrle_counters.pages; + } +@@ -1357,7 +1357,7 @@ static bool control_save_page(PageSearchStatus *pss, RAMBlock *block, + } + + if (bytes_xmit > 0) { +- stat64_add(&ram_counters.normal, 1); ++ stat64_add(&ram_counters.normal_pages, 1); + } else if (bytes_xmit == 0) { + stat64_add(&ram_counters.zero_pages, 1); + } +@@ -1391,7 +1391,7 @@ static int save_normal_page(PageSearchStatus *pss, RAMBlock *block, + qemu_put_buffer(file, buf, TARGET_PAGE_SIZE); + } + ram_transferred_add(TARGET_PAGE_SIZE); +- stat64_add(&ram_counters.normal, 1); ++ stat64_add(&ram_counters.normal_pages, 1); + return 1; + } + +@@ -1447,7 +1447,7 @@ static int ram_save_multifd_page(QEMUFile *file, RAMBlock *block, + if (multifd_queue_page(file, block, offset) < 0) { + return -1; + } +- stat64_add(&ram_counters.normal, 1); ++ stat64_add(&ram_counters.normal_pages, 1); + + return 1; + } +@@ -2623,7 +2623,7 @@ void acct_update_position(QEMUFile *f, size_t size, bool zero) + if (zero) { + stat64_add(&ram_counters.zero_pages, pages); + } else { +- stat64_add(&ram_counters.normal, pages); ++ stat64_add(&ram_counters.normal_pages, pages); + ram_transferred_add(size); + qemu_file_credit_transfer(f, size); + } +diff --git a/migration/ram.h b/migration/ram.h +index 55258334fe..a6e0d70226 100644 +--- a/migration/ram.h ++++ b/migration/ram.h +@@ -47,7 +47,7 @@ typedef struct { + Stat64 downtime_bytes; + Stat64 zero_pages; + Stat64 multifd_bytes; +- Stat64 normal; ++ Stat64 normal_pages; + Stat64 postcopy_bytes; + Stat64 postcopy_requests; + Stat64 precopy_bytes; +-- +2.39.1 + diff --git a/kvm-migration-Update-atomic-stats-out-of-the-mutex.patch b/kvm-migration-Update-atomic-stats-out-of-the-mutex.patch new file mode 100644 index 0000000..7e78d82 --- /dev/null +++ b/kvm-migration-Update-atomic-stats-out-of-the-mutex.patch @@ -0,0 +1,52 @@ +From c0d377e1bf442a09b82fddbb8588fcddf6439854 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 24 Nov 2022 17:26:19 +0100 +Subject: [PATCH 09/56] migration: Update atomic stats out of the mutex +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [8/50] 88e9dbc9a3e5aef60a7c98c871144904c7062b1f (peterx/qemu-kvm) + +Reviewed-by: David Edmondson +Reviewed-by: Peter Xu +Signed-off-by: Juan Quintela +(cherry picked from commit 30fb22cda45bea43a3c0e26049ebdd71a9503ffd) +Signed-off-by: Peter Xu +--- + migration/multifd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/migration/multifd.c b/migration/multifd.c +index 01fab01a92..6ef3a27938 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -433,8 +433,8 @@ static int multifd_send_pages(QEMUFile *f) + transferred = ((uint64_t) pages->num) * p->page_size + p->packet_len; + qemu_file_acct_rate_limit(f, transferred); + ram_counters.multifd_bytes += transferred; +- stat64_add(&ram_counters.transferred, transferred); + qemu_mutex_unlock(&p->mutex); ++ stat64_add(&ram_counters.transferred, transferred); + qemu_sem_post(&p->sem); + + return 1; +@@ -628,8 +628,8 @@ int multifd_send_sync_main(QEMUFile *f) + p->pending_job++; + qemu_file_acct_rate_limit(f, p->packet_len); + ram_counters.multifd_bytes += p->packet_len; +- stat64_add(&ram_counters.transferred, p->packet_len); + qemu_mutex_unlock(&p->mutex); ++ stat64_add(&ram_counters.transferred, p->packet_len); + qemu_sem_post(&p->sem); + } + for (i = 0; i < migrate_multifd_channels(); i++) { +-- +2.39.1 + diff --git a/kvm-migration-Use-migrate_max_postcopy_bandwidth.patch b/kvm-migration-Use-migrate_max_postcopy_bandwidth.patch new file mode 100644 index 0000000..f179761 --- /dev/null +++ b/kvm-migration-Use-migrate_max_postcopy_bandwidth.patch @@ -0,0 +1,40 @@ +From 8d203baa6cbd1f371e308c2c9d59a5ca7d29dca8 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Thu, 2 Mar 2023 10:55:30 +0100 +Subject: [PATCH 38/56] migration: Use migrate_max_postcopy_bandwidth() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [37/50] d62948e9ee40a85ed9b460a583c3b0e43cd5d47f (peterx/qemu-kvm) + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 5390adec03a7d8bc6bcf5887f726b0ddaeb90681) +Signed-off-by: Peter Xu +--- + migration/migration.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 7f2e770deb..78bca9a93f 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -3799,7 +3799,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) + + if (resume) { + /* This is a resumed migration */ +- rate_limit = s->parameters.max_postcopy_bandwidth / ++ rate_limit = migrate_max_postcopy_bandwidth() / + XFER_LIMIT_RATIO; + } else { + /* This is a fresh new migration */ +-- +2.39.1 + diff --git a/kvm-migration-mark-mixed-functions-that-can-suspend.patch b/kvm-migration-mark-mixed-functions-that-can-suspend.patch new file mode 100644 index 0000000..9451696 --- /dev/null +++ b/kvm-migration-mark-mixed-functions-that-can-suspend.patch @@ -0,0 +1,153 @@ +From cfdf5715a2334ad06b5966ec986d134bbd5ba08b Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 16 Dec 2022 12:48:16 +0100 +Subject: [PATCH 05/56] migration: mark mixed functions that can suspend +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [4/50] 9f055b526edd06a3440999d5de91e5d624678c7d (peterx/qemu-kvm) + +There should be no paths from a coroutine_fn to aio_poll, however in +practice coroutine_mixed_fn will call aio_poll in the !qemu_in_coroutine() +path. By marking mixed functions, we can track accurately the call paths +that execute entirely in coroutine context, and find more missing +coroutine_fn markers. This results in more accurate checks that +coroutine code does not end up blocking. + +If the marking were extended transitively to all functions that call +these ones, static analysis could be done much more efficiently. +However, this is a start and makes it possible to use vrc's path-based +searches to find potential bugs where coroutine_fns call blocking functions. + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 394b9407e4c515f96df6647d629ee28cbb86f07c) +Signed-off-by: Peter Xu +--- + include/migration/qemu-file-types.h | 4 ++-- + migration/qemu-file.c | 14 +++++++------- + migration/qemu-file.h | 6 +++--- + 3 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/include/migration/qemu-file-types.h b/include/migration/qemu-file-types.h +index 2867e3da84..1436f9ce92 100644 +--- a/include/migration/qemu-file-types.h ++++ b/include/migration/qemu-file-types.h +@@ -35,7 +35,7 @@ void qemu_put_byte(QEMUFile *f, int v); + void qemu_put_be16(QEMUFile *f, unsigned int v); + void qemu_put_be32(QEMUFile *f, unsigned int v); + void qemu_put_be64(QEMUFile *f, uint64_t v); +-size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size); ++size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size); + + int qemu_get_byte(QEMUFile *f); + +@@ -161,7 +161,7 @@ static inline void qemu_get_sbe64s(QEMUFile *f, int64_t *pv) + qemu_get_be64s(f, (uint64_t *)pv); + } + +-size_t qemu_get_counted_string(QEMUFile *f, char buf[256]); ++size_t coroutine_mixed_fn qemu_get_counted_string(QEMUFile *f, char buf[256]); + + void qemu_put_counted_string(QEMUFile *f, const char *name); + +diff --git a/migration/qemu-file.c b/migration/qemu-file.c +index 102ab3b439..ee04240a21 100644 +--- a/migration/qemu-file.c ++++ b/migration/qemu-file.c +@@ -392,7 +392,7 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset, + * case if the underlying file descriptor gives a short read, and that can + * happen even on a blocking fd. + */ +-static ssize_t qemu_fill_buffer(QEMUFile *f) ++static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) + { + int len; + int pending; +@@ -585,7 +585,7 @@ void qemu_file_skip(QEMUFile *f, int size) + * return as many as it managed to read (assuming blocking fd's which + * all current QEMUFile are) + */ +-size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset) ++size_t coroutine_mixed_fn qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset) + { + ssize_t pending; + size_t index; +@@ -633,7 +633,7 @@ size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset) + * return as many as it managed to read (assuming blocking fd's which + * all current QEMUFile are) + */ +-size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size) ++size_t coroutine_mixed_fn qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size) + { + size_t pending = size; + size_t done = 0; +@@ -674,7 +674,7 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size) + * Note: Since **buf may get changed, the caller should take care to + * keep a pointer to the original buffer if it needs to deallocate it. + */ +-size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size) ++size_t coroutine_mixed_fn qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size) + { + if (size < IO_BUF_SIZE) { + size_t res; +@@ -696,7 +696,7 @@ size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size) + * Peeks a single byte from the buffer; this isn't guaranteed to work if + * offset leaves a gap after the previous read/peeked data. + */ +-int qemu_peek_byte(QEMUFile *f, int offset) ++int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int offset) + { + int index = f->buf_index + offset; + +@@ -713,7 +713,7 @@ int qemu_peek_byte(QEMUFile *f, int offset) + return f->buf[index]; + } + +-int qemu_get_byte(QEMUFile *f) ++int coroutine_mixed_fn qemu_get_byte(QEMUFile *f) + { + int result; + +@@ -894,7 +894,7 @@ int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src) + * else 0 + * (Note a 0 length string will return 0 either way) + */ +-size_t qemu_get_counted_string(QEMUFile *f, char buf[256]) ++size_t coroutine_fn qemu_get_counted_string(QEMUFile *f, char buf[256]) + { + size_t len = qemu_get_byte(f); + size_t res = qemu_get_buffer(f, (uint8_t *)buf, len); +diff --git a/migration/qemu-file.h b/migration/qemu-file.h +index 9d0155a2a1..d16cd50448 100644 +--- a/migration/qemu-file.h ++++ b/migration/qemu-file.h +@@ -108,8 +108,8 @@ bool qemu_file_is_writable(QEMUFile *f); + + #include "migration/qemu-file-types.h" + +-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); ++size_t coroutine_mixed_fn qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset); ++size_t coroutine_mixed_fn 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); +@@ -119,7 +119,7 @@ int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src); + * is; you aren't guaranteed to be able to peak to +n bytes unless you've + * previously peeked +n-1. + */ +-int qemu_peek_byte(QEMUFile *f, int offset); ++int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int offset); + void qemu_file_skip(QEMUFile *f, int size); + /* + * qemu_file_credit_transfer: +-- +2.39.1 + diff --git a/kvm-migration-move-migration_global_dump-to-migration-hm.patch b/kvm-migration-move-migration_global_dump-to-migration-hm.patch new file mode 100644 index 0000000..4e73c80 --- /dev/null +++ b/kvm-migration-move-migration_global_dump-to-migration-hm.patch @@ -0,0 +1,121 @@ +From 96e6914cbfb18bb8287c57b9ac9a6b364d3e7a22 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 22 Feb 2023 17:18:05 +0100 +Subject: [PATCH 20/56] migration: move migration_global_dump() to + migration-hmp-cmds.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [19/50] c8d330a2833c706b9bd78f7154be882e3977ad06 (peterx/qemu-kvm) + +It is only used there, so we can make it static. +Once there, remove spice.h that it is not used. + +Signed-off-by: Juan Quintela +Reviewed-by: Peter Xu +Reviewed-by: Philippe Mathieu-Daudé + +--- + +fix David Edmonson ui/qemu-spice.h unintended removal + +(cherry picked from commit c938157713e723165a42cb6e8364adb6fcbd0e22) +Signed-off-by: Peter Xu +--- + include/migration/misc.h | 1 - + migration/migration-hmp-cmds.c | 22 +++++++++++++++++++++- + migration/migration.c | 19 ------------------- + 3 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/include/migration/misc.h b/include/migration/misc.h +index 8b49841016..5ebe13b4b9 100644 +--- a/include/migration/misc.h ++++ b/include/migration/misc.h +@@ -66,7 +66,6 @@ bool migration_has_finished(MigrationState *); + bool migration_has_failed(MigrationState *); + /* ...and after the device transmission */ + bool migration_in_postcopy_after_devices(MigrationState *); +-void migration_global_dump(Monitor *mon); + /* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */ + bool migration_in_incoming_postcopy(void); + /* True if incoming migration entered POSTCOPY_INCOMING_ADVISE */ +diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c +index 72519ea99f..71da91967a 100644 +--- a/migration/migration-hmp-cmds.c ++++ b/migration/migration-hmp-cmds.c +@@ -15,7 +15,6 @@ + + #include "qemu/osdep.h" + #include "block/qapi.h" +-#include "migration/misc.h" + #include "migration/snapshot.h" + #include "monitor/hmp.h" + #include "monitor/monitor.h" +@@ -30,6 +29,27 @@ + #include "qemu/sockets.h" + #include "sysemu/runstate.h" + #include "ui/qemu-spice.h" ++#include "sysemu/sysemu.h" ++#include "migration.h" ++ ++static void migration_global_dump(Monitor *mon) ++{ ++ MigrationState *ms = migrate_get_current(); ++ ++ monitor_printf(mon, "globals:\n"); ++ monitor_printf(mon, "store-global-state: %s\n", ++ ms->store_global_state ? "on" : "off"); ++ monitor_printf(mon, "only-migratable: %s\n", ++ only_migratable ? "on" : "off"); ++ monitor_printf(mon, "send-configuration: %s\n", ++ ms->send_configuration ? "on" : "off"); ++ monitor_printf(mon, "send-section-footer: %s\n", ++ ms->send_section_footer ? "on" : "off"); ++ monitor_printf(mon, "decompress-error-check: %s\n", ++ ms->decompress_error_check ? "on" : "off"); ++ monitor_printf(mon, "clear-bitmap-shift: %u\n", ++ ms->clear_bitmap_shift); ++} + + void hmp_info_migrate(Monitor *mon, const QDict *qdict) + { +diff --git a/migration/migration.c b/migration/migration.c +index e8f596bcfa..aa96ffdc5b 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -4420,25 +4420,6 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) + s->migration_thread_running = true; + } + +-void migration_global_dump(Monitor *mon) +-{ +- MigrationState *ms = migrate_get_current(); +- +- monitor_printf(mon, "globals:\n"); +- monitor_printf(mon, "store-global-state: %s\n", +- ms->store_global_state ? "on" : "off"); +- monitor_printf(mon, "only-migratable: %s\n", +- only_migratable ? "on" : "off"); +- monitor_printf(mon, "send-configuration: %s\n", +- ms->send_configuration ? "on" : "off"); +- monitor_printf(mon, "send-section-footer: %s\n", +- ms->send_section_footer ? "on" : "off"); +- monitor_printf(mon, "decompress-error-check: %s\n", +- ms->decompress_error_check ? "on" : "off"); +- monitor_printf(mon, "clear-bitmap-shift: %u\n", +- ms->clear_bitmap_shift); +-} +- + #define DEFINE_PROP_MIG_CAP(name, x) \ + DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false) + +-- +2.39.1 + diff --git a/kvm-migration-postcopy-Detect-file-system-on-dest-host.patch b/kvm-migration-postcopy-Detect-file-system-on-dest-host.patch new file mode 100644 index 0000000..7700466 --- /dev/null +++ b/kvm-migration-postcopy-Detect-file-system-on-dest-host.patch @@ -0,0 +1,117 @@ +From 4827d5be5357ab89e0c46f606ad828bf97d36471 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 19 Apr 2023 12:17:38 -0400 +Subject: [PATCH 04/56] migration/postcopy: Detect file system on dest host +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [3/50] 121aeeda8a019f79dba6c077c7018bd1c86f3d71 (peterx/qemu-kvm) + +Postcopy requires the memory support userfaultfd to work. Right now we +check it but it's a bit too late (when switching to postcopy migration). + +Do that early right at enabling of postcopy. + +Note that this is still only a best effort because ramblocks can be +dynamically created. We can add check in hostmem creations and fail if +postcopy enabled, but maybe that's too aggressive. + +Still, we have chance to fail the most obvious where we know there's an +existing unsupported ramblock. + +Signed-off-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit ae30b9b2892b85e6c3d5c0b8d1949c4d77a2954a) +Signed-off-by: Peter Xu +--- + migration/postcopy-ram.c | 34 ++++++++++++++++++++++++++++++---- + 1 file changed, 30 insertions(+), 4 deletions(-) + +diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c +index 93f39f8e06..bbb8af61ae 100644 +--- a/migration/postcopy-ram.c ++++ b/migration/postcopy-ram.c +@@ -36,6 +36,7 @@ + #include "yank_functions.h" + #include "tls.h" + #include "qemu/userfaultfd.h" ++#include "qemu/mmap-alloc.h" + + /* Arbitrary limit on size of each discard command, + * keeps them around ~200 bytes +@@ -336,11 +337,12 @@ static bool ufd_check_and_apply(int ufd, MigrationIncomingState *mis) + + /* Callback from postcopy_ram_supported_by_host block iterator. + */ +-static int test_ramblock_postcopiable(RAMBlock *rb, void *opaque) ++static int test_ramblock_postcopiable(RAMBlock *rb) + { + const char *block_name = qemu_ram_get_idstr(rb); + ram_addr_t length = qemu_ram_get_used_length(rb); + size_t pagesize = qemu_ram_pagesize(rb); ++ QemuFsType fs; + + if (length % pagesize) { + error_report("Postcopy requires RAM blocks to be a page size multiple," +@@ -348,6 +350,15 @@ static int test_ramblock_postcopiable(RAMBlock *rb, void *opaque) + "page size of 0x%zx", block_name, length, pagesize); + return 1; + } ++ ++ if (rb->fd >= 0) { ++ fs = qemu_fd_getfs(rb->fd); ++ if (fs != QEMU_FS_TYPE_TMPFS && fs != QEMU_FS_TYPE_HUGETLBFS) { ++ error_report("Host backend files need to be TMPFS or HUGETLBFS only"); ++ return 1; ++ } ++ } ++ + return 0; + } + +@@ -366,6 +377,7 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + struct uffdio_range range_struct; + uint64_t feature_mask; + Error *local_err = NULL; ++ RAMBlock *block; + + if (qemu_target_page_size() > pagesize) { + error_report("Target page size bigger than host page size"); +@@ -390,9 +402,23 @@ bool postcopy_ram_supported_by_host(MigrationIncomingState *mis) + goto out; + } + +- /* We don't support postcopy with shared RAM yet */ +- if (foreach_not_ignored_block(test_ramblock_postcopiable, NULL)) { +- goto out; ++ /* ++ * We don't support postcopy with some type of ramblocks. ++ * ++ * NOTE: we explicitly ignored ramblock_is_ignored() instead we checked ++ * all possible ramblocks. This is because this function can be called ++ * when creating the migration object, during the phase RAM_MIGRATABLE ++ * is not even properly set for all the ramblocks. ++ * ++ * A side effect of this is we'll also check against RAM_SHARED ++ * ramblocks even if migrate_ignore_shared() is set (in which case ++ * we'll never migrate RAM_SHARED at all), but normally this shouldn't ++ * affect in reality, or we can revisit. ++ */ ++ RAMBLOCK_FOREACH(block) { ++ if (test_ramblock_postcopiable(block)) { ++ goto out; ++ } + } + + /* +-- +2.39.1 + diff --git a/kvm-migration-remove-extra-whitespace-character-for-code.patch b/kvm-migration-remove-extra-whitespace-character-for-code.patch new file mode 100644 index 0000000..88eb791 --- /dev/null +++ b/kvm-migration-remove-extra-whitespace-character-for-code.patch @@ -0,0 +1,44 @@ +From 93c9a1ae812720d3a29980a3c5fcfc1e916993de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=9D=8E=E7=9A=86=E4=BF=8A?= +Date: Fri, 17 Mar 2023 09:57:13 +0000 +Subject: [PATCH 07/56] migration: remove extra whitespace character for code + style +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [6/50] bc1cd812f8dfc18e47e1644b5333c703eae23d2d (peterx/qemu-kvm) + +Fix code style. + +Signed-off-by: 李皆俊 +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit 8ebb6ecc3798e66a9ba98355983762bedfa1b72d) +Signed-off-by: Peter Xu +--- + migration/ram.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/migration/ram.c b/migration/ram.c +index 79d881f735..0e68099bf9 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -3293,7 +3293,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque) + + migration_ops = g_malloc0(sizeof(MigrationOps)); + migration_ops->ram_save_target_page = ram_save_target_page_legacy; +- ret = multifd_send_sync_main(f); ++ ret = multifd_send_sync_main(f); + if (ret < 0) { + return ret; + } +-- +2.39.1 + diff --git a/kvm-migration-rename-enabled_capabilities-to-capabilitie.patch b/kvm-migration-rename-enabled_capabilities-to-capabilitie.patch new file mode 100644 index 0000000..52b19b3 --- /dev/null +++ b/kvm-migration-rename-enabled_capabilities-to-capabilitie.patch @@ -0,0 +1,329 @@ +From ee566ec12099992f9134bda1db92dd568427245a Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 18:26:59 +0100 +Subject: [PATCH 18/56] migration: rename enabled_capabilities to capabilities +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [17/50] 841a27addf273d8f559bc8ebd2c854200e8ca673 (peterx/qemu-kvm) + +It is clear from the context what that means, and such a long name +with the extra long names of the capabilities make very difficilut to +stay inside the 80 columns limit. + +Signed-off-by: Juan Quintela +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 0cec2056ff67557c18d7b8ab1b70ab47c9e31f2f) +Signed-off-by: Peter Xu +--- + migration/migration.c | 52 +++++++++++++++++++++---------------------- + migration/migration.h | 2 +- + migration/rdma.c | 4 ++-- + migration/savevm.c | 6 ++--- + 4 files changed, 31 insertions(+), 33 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index f1b3439e5f..d8e5fb6226 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -364,8 +364,7 @@ static bool migrate_late_block_activate(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[ +- MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; ++ return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE]; + } + + /* +@@ -944,7 +943,7 @@ MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) + #endif + caps = g_malloc0(sizeof(*caps)); + caps->capability = i; +- caps->state = s->enabled_capabilities[i]; ++ caps->state = s->capabilities[i]; + QAPI_LIST_APPEND(tail, caps); + } + +@@ -1494,13 +1493,13 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, + return; + } + +- memcpy(cap_list, s->enabled_capabilities, sizeof(cap_list)); ++ memcpy(cap_list, s->capabilities, sizeof(cap_list)); + if (!migrate_caps_check(cap_list, params, errp)) { + return; + } + + for (cap = params; cap; cap = cap->next) { +- s->enabled_capabilities[cap->value->capability] = cap->value->state; ++ s->capabilities[cap->value->capability] = cap->value->state; + } + } + +@@ -2569,7 +2568,7 @@ bool migrate_release_ram(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; ++ return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM]; + } + + bool migrate_postcopy_ram(void) +@@ -2578,7 +2577,7 @@ bool migrate_postcopy_ram(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; ++ return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM]; + } + + bool migrate_postcopy(void) +@@ -2592,7 +2591,7 @@ bool migrate_auto_converge(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; ++ return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE]; + } + + bool migrate_zero_blocks(void) +@@ -2601,7 +2600,7 @@ bool migrate_zero_blocks(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; ++ return s->capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS]; + } + + bool migrate_postcopy_blocktime(void) +@@ -2610,7 +2609,7 @@ bool migrate_postcopy_blocktime(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; ++ return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME]; + } + + bool migrate_use_compression(void) +@@ -2619,7 +2618,7 @@ bool migrate_use_compression(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_COMPRESS]; ++ return s->capabilities[MIGRATION_CAPABILITY_COMPRESS]; + } + + int migrate_compress_level(void) +@@ -2664,7 +2663,7 @@ bool migrate_dirty_bitmaps(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; ++ return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS]; + } + + bool migrate_ignore_shared(void) +@@ -2673,7 +2672,7 @@ bool migrate_ignore_shared(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; ++ return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED]; + } + + bool migrate_validate_uuid(void) +@@ -2682,7 +2681,7 @@ bool migrate_validate_uuid(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; ++ return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID]; + } + + bool migrate_use_events(void) +@@ -2691,7 +2690,7 @@ bool migrate_use_events(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_EVENTS]; ++ return s->capabilities[MIGRATION_CAPABILITY_EVENTS]; + } + + bool migrate_use_multifd(void) +@@ -2700,7 +2699,7 @@ bool migrate_use_multifd(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_MULTIFD]; ++ return s->capabilities[MIGRATION_CAPABILITY_MULTIFD]; + } + + bool migrate_pause_before_switchover(void) +@@ -2709,8 +2708,7 @@ bool migrate_pause_before_switchover(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[ +- MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; ++ return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER]; + } + + int migrate_multifd_channels(void) +@@ -2757,7 +2755,7 @@ bool migrate_use_zero_copy_send(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; ++ return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND]; + } + #endif + +@@ -2776,7 +2774,7 @@ int migrate_use_xbzrle(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE]; ++ return s->capabilities[MIGRATION_CAPABILITY_XBZRLE]; + } + + uint64_t migrate_xbzrle_cache_size(void) +@@ -2803,7 +2801,7 @@ bool migrate_use_block(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_BLOCK]; ++ return s->capabilities[MIGRATION_CAPABILITY_BLOCK]; + } + + bool migrate_use_return_path(void) +@@ -2812,7 +2810,7 @@ bool migrate_use_return_path(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; ++ return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH]; + } + + bool migrate_use_block_incremental(void) +@@ -2830,7 +2828,7 @@ bool migrate_background_snapshot(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; ++ return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]; + } + + bool migrate_postcopy_preempt(void) +@@ -2839,7 +2837,7 @@ bool migrate_postcopy_preempt(void) + + s = migrate_get_current(); + +- return s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; ++ return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]; + } + + /* migration thread support */ +@@ -3584,7 +3582,7 @@ fail: + bool migrate_colo_enabled(void) + { + MigrationState *s = migrate_get_current(); +- return s->enabled_capabilities[MIGRATION_CAPABILITY_X_COLO]; ++ return s->capabilities[MIGRATION_CAPABILITY_X_COLO]; + } + + typedef enum MigThrError { +@@ -4447,7 +4445,7 @@ void migration_global_dump(Monitor *mon) + } + + #define DEFINE_PROP_MIG_CAP(name, x) \ +- DEFINE_PROP_BOOL(name, MigrationState, enabled_capabilities[x], false) ++ DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false) + + static Property migration_properties[] = { + DEFINE_PROP_BOOL("store-global-state", MigrationState, +@@ -4646,7 +4644,7 @@ static bool migration_object_check(MigrationState *ms, Error **errp) + } + + for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { +- if (ms->enabled_capabilities[i]) { ++ if (ms->capabilities[i]) { + QAPI_LIST_PREPEND(head, migrate_cap_add(i, true)); + } + } +diff --git a/migration/migration.h b/migration/migration.h +index 310ae8901b..04e0860b4e 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -310,7 +310,7 @@ struct MigrationState { + int64_t downtime_start; + int64_t downtime; + int64_t expected_downtime; +- bool enabled_capabilities[MIGRATION_CAPABILITY__MAX]; ++ bool capabilities[MIGRATION_CAPABILITY__MAX]; + int64_t setup_time; + /* + * Whether guest was running when we enter the completion stage. +diff --git a/migration/rdma.c b/migration/rdma.c +index df646be35e..f35f021963 100644 +--- a/migration/rdma.c ++++ b/migration/rdma.c +@@ -4179,7 +4179,7 @@ void rdma_start_outgoing_migration(void *opaque, + } + + ret = qemu_rdma_source_init(rdma, +- s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); ++ s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); + + if (ret) { + goto err; +@@ -4201,7 +4201,7 @@ void rdma_start_outgoing_migration(void *opaque, + } + + ret = qemu_rdma_source_init(rdma_return_path, +- s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); ++ s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); + + if (ret) { + goto return_path_err; +diff --git a/migration/savevm.c b/migration/savevm.c +index aa54a67fda..589ef926ab 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -253,7 +253,7 @@ static uint32_t get_validatable_capabilities_count(void) + uint32_t result = 0; + int i; + for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { +- if (should_validate_capability(i) && s->enabled_capabilities[i]) { ++ if (should_validate_capability(i) && s->capabilities[i]) { + result++; + } + } +@@ -275,7 +275,7 @@ static int configuration_pre_save(void *opaque) + state->capabilities = g_renew(MigrationCapability, state->capabilities, + state->caps_count); + for (i = j = 0; i < MIGRATION_CAPABILITY__MAX; i++) { +- if (should_validate_capability(i) && s->enabled_capabilities[i]) { ++ if (should_validate_capability(i) && s->capabilities[i]) { + state->capabilities[j++] = i; + } + } +@@ -325,7 +325,7 @@ static bool configuration_validate_capabilities(SaveState *state) + continue; + } + source_state = test_bit(i, source_caps_bm); +- target_state = s->enabled_capabilities[i]; ++ target_state = s->capabilities[i]; + if (source_state != target_state) { + error_report("Capability %s is %s, but received capability is %s", + MigrationCapability_str(i), +-- +2.39.1 + diff --git a/kvm-postcopy-ram-do-not-use-qatomic_mb_read.patch b/kvm-postcopy-ram-do-not-use-qatomic_mb_read.patch new file mode 100644 index 0000000..0421e33 --- /dev/null +++ b/kvm-postcopy-ram-do-not-use-qatomic_mb_read.patch @@ -0,0 +1,42 @@ +From ab9b8620c62540f3267d005c198920671ef9abc3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 3 Mar 2023 11:15:28 +0100 +Subject: [PATCH 06/56] postcopy-ram: do not use qatomic_mb_read +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [5/50] 534c0e13362dfc994fa90c79bfb5ed6ee8c27dfc (peterx/qemu-kvm) + +It does not even pair with a qatomic_mb_set(), so it is clearer to use +load-acquire in this case; they are synonyms. + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 4592eaf38755a28300d113cd128f65b5b38495f2) +Signed-off-by: Peter Xu +--- + migration/postcopy-ram.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c +index bbb8af61ae..d7b48dd920 100644 +--- a/migration/postcopy-ram.c ++++ b/migration/postcopy-ram.c +@@ -1526,7 +1526,7 @@ static PostcopyState incoming_postcopy_state; + + PostcopyState postcopy_state_get(void) + { +- return qatomic_mb_read(&incoming_postcopy_state); ++ return qatomic_load_acquire(&incoming_postcopy_state); + } + + /* Set the state and return the old state */ +-- +2.39.1 + diff --git a/kvm-spice-move-client_migrate_info-command-to-ui.patch b/kvm-spice-move-client_migrate_info-command-to-ui.patch new file mode 100644 index 0000000..f1de158 --- /dev/null +++ b/kvm-spice-move-client_migrate_info-command-to-ui.patch @@ -0,0 +1,248 @@ +From 00f6e941e75f378c84c773a15efde7dd085d9ce3 Mon Sep 17 00:00:00 2001 +From: Juan Quintela +Date: Wed, 1 Mar 2023 19:40:14 +0100 +Subject: [PATCH 21/56] spice: move client_migrate_info command to ui/ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [20/50] a587bb001b51a1f9fdf2fcfb0978bb931ae443b6 (peterx/qemu-kvm) + +It has nothing to do with migration, except for the "migrate" in the +name of the command. Move it with the rest of the ui commands. + +Signed-off-by: Juan Quintela +Reviewed-by: Philippe Mathieu-Daudé +(cherry picked from commit f9e1ef7482f1ee289b04f4b45702a1701bc8929d) +Signed-off-by: Peter Xu +--- + migration/migration-hmp-cmds.c | 17 ----------------- + migration/migration.c | 30 ------------------------------ + qapi/migration.json | 28 ---------------------------- + qapi/ui.json | 28 ++++++++++++++++++++++++++++ + ui/ui-hmp-cmds.c | 17 +++++++++++++++++ + ui/ui-qmp-cmds.c | 29 +++++++++++++++++++++++++++++ + 6 files changed, 74 insertions(+), 75 deletions(-) + +diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c +index 71da91967a..4e9f00e7dc 100644 +--- a/migration/migration-hmp-cmds.c ++++ b/migration/migration-hmp-cmds.c +@@ -636,23 +636,6 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) + hmp_handle_error(mon, err); + } + +-void hmp_client_migrate_info(Monitor *mon, const QDict *qdict) +-{ +- Error *err = NULL; +- const char *protocol = qdict_get_str(qdict, "protocol"); +- const char *hostname = qdict_get_str(qdict, "hostname"); +- bool has_port = qdict_haskey(qdict, "port"); +- int port = qdict_get_try_int(qdict, "port", -1); +- bool has_tls_port = qdict_haskey(qdict, "tls-port"); +- int tls_port = qdict_get_try_int(qdict, "tls-port", -1); +- const char *cert_subject = qdict_get_try_str(qdict, "cert-subject"); +- +- qmp_client_migrate_info(protocol, hostname, +- has_port, port, has_tls_port, tls_port, +- cert_subject, &err); +- hmp_handle_error(mon, err); +-} +- + void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict) + { + Error *err = NULL; +diff --git a/migration/migration.c b/migration/migration.c +index aa96ffdc5b..b745d829a4 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -63,7 +63,6 @@ + #include "sysemu/cpus.h" + #include "yank_functions.h" + #include "sysemu/qtest.h" +-#include "ui/qemu-spice.h" + + #define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */ + +@@ -1018,35 +1017,6 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) + return params; + } + +-void qmp_client_migrate_info(const char *protocol, const char *hostname, +- bool has_port, int64_t port, +- bool has_tls_port, int64_t tls_port, +- const char *cert_subject, +- Error **errp) +-{ +- if (strcmp(protocol, "spice") == 0) { +- if (!qemu_using_spice(errp)) { +- return; +- } +- +- if (!has_port && !has_tls_port) { +- error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port"); +- return; +- } +- +- if (qemu_spice.migrate_info(hostname, +- has_port ? port : -1, +- has_tls_port ? tls_port : -1, +- cert_subject)) { +- error_setg(errp, "Could not set up display for migration"); +- return; +- } +- return; +- } +- +- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "'spice'"); +-} +- + AnnounceParameters *migrate_announce_params(void) + { + static AnnounceParameters ap; +diff --git a/qapi/migration.json b/qapi/migration.json +index c84fa10e86..2c35b7b9cf 100644 +--- a/qapi/migration.json ++++ b/qapi/migration.json +@@ -1203,34 +1203,6 @@ + { 'command': 'query-migrate-parameters', + 'returns': 'MigrationParameters' } + +-## +-# @client_migrate_info: +-# +-# Set migration information for remote display. This makes the server +-# ask the client to automatically reconnect using the new parameters +-# once migration finished successfully. Only implemented for SPICE. +-# +-# @protocol: must be "spice" +-# @hostname: migration target hostname +-# @port: spice tcp port for plaintext channels +-# @tls-port: spice tcp port for tls-secured channels +-# @cert-subject: server certificate subject +-# +-# Since: 0.14 +-# +-# Example: +-# +-# -> { "execute": "client_migrate_info", +-# "arguments": { "protocol": "spice", +-# "hostname": "virt42.lab.kraxel.org", +-# "port": 1234 } } +-# <- { "return": {} } +-# +-## +-{ 'command': 'client_migrate_info', +- 'data': { 'protocol': 'str', 'hostname': 'str', '*port': 'int', +- '*tls-port': 'int', '*cert-subject': 'str' } } +- + ## + # @migrate-start-postcopy: + # +diff --git a/qapi/ui.json b/qapi/ui.json +index 98322342f7..7ddd27a932 100644 +--- a/qapi/ui.json ++++ b/qapi/ui.json +@@ -1554,3 +1554,31 @@ + { 'command': 'display-update', + 'data': 'DisplayUpdateOptions', + 'boxed' : true } ++ ++## ++# @client_migrate_info: ++# ++# Set migration information for remote display. This makes the server ++# ask the client to automatically reconnect using the new parameters ++# once migration finished successfully. Only implemented for SPICE. ++# ++# @protocol: must be "spice" ++# @hostname: migration target hostname ++# @port: spice tcp port for plaintext channels ++# @tls-port: spice tcp port for tls-secured channels ++# @cert-subject: server certificate subject ++# ++# Since: 0.14 ++# ++# Example: ++# ++# -> { "execute": "client_migrate_info", ++# "arguments": { "protocol": "spice", ++# "hostname": "virt42.lab.kraxel.org", ++# "port": 1234 } } ++# <- { "return": {} } ++# ++## ++{ 'command': 'client_migrate_info', ++ 'data': { 'protocol': 'str', 'hostname': 'str', '*port': 'int', ++ '*tls-port': 'int', '*cert-subject': 'str' } } +diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c +index 5c456ecc02..c671389473 100644 +--- a/ui/ui-hmp-cmds.c ++++ b/ui/ui-hmp-cmds.c +@@ -458,3 +458,20 @@ hmp_screendump(Monitor *mon, const QDict *qdict) + end: + hmp_handle_error(mon, err); + } ++ ++void hmp_client_migrate_info(Monitor *mon, const QDict *qdict) ++{ ++ Error *err = NULL; ++ const char *protocol = qdict_get_str(qdict, "protocol"); ++ const char *hostname = qdict_get_str(qdict, "hostname"); ++ bool has_port = qdict_haskey(qdict, "port"); ++ int port = qdict_get_try_int(qdict, "port", -1); ++ bool has_tls_port = qdict_haskey(qdict, "tls-port"); ++ int tls_port = qdict_get_try_int(qdict, "tls-port", -1); ++ const char *cert_subject = qdict_get_try_str(qdict, "cert-subject"); ++ ++ qmp_client_migrate_info(protocol, hostname, ++ has_port, port, has_tls_port, tls_port, ++ cert_subject, &err); ++ hmp_handle_error(mon, err); ++} +diff --git a/ui/ui-qmp-cmds.c b/ui/ui-qmp-cmds.c +index dbc4afcd73..a37a7024f3 100644 +--- a/ui/ui-qmp-cmds.c ++++ b/ui/ui-qmp-cmds.c +@@ -175,3 +175,32 @@ void qmp_display_update(DisplayUpdateOptions *arg, Error **errp) + abort(); + } + } ++ ++void qmp_client_migrate_info(const char *protocol, const char *hostname, ++ bool has_port, int64_t port, ++ bool has_tls_port, int64_t tls_port, ++ const char *cert_subject, ++ Error **errp) ++{ ++ if (strcmp(protocol, "spice") == 0) { ++ if (!qemu_using_spice(errp)) { ++ return; ++ } ++ ++ if (!has_port && !has_tls_port) { ++ error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port"); ++ return; ++ } ++ ++ if (qemu_spice.migrate_info(hostname, ++ has_port ? port : -1, ++ has_tls_port ? tls_port : -1, ++ cert_subject)) { ++ error_setg(errp, "Could not set up display for migration"); ++ return; ++ } ++ return; ++ } ++ ++ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "'spice'"); ++} +-- +2.39.1 + diff --git a/kvm-util-mmap-alloc-qemu_fd_getfs.patch b/kvm-util-mmap-alloc-qemu_fd_getfs.patch new file mode 100644 index 0000000..b0e66f6 --- /dev/null +++ b/kvm-util-mmap-alloc-qemu_fd_getfs.patch @@ -0,0 +1,95 @@ +From 439a8cdd010dfd253fc2277ae4ec605b5ba621d9 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 19 Apr 2023 12:17:36 -0400 +Subject: [PATCH 02/56] util/mmap-alloc: qemu_fd_getfs() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [1/50] 8970b5ae611a933d693e0c90cbf4eda073635494 (peterx/qemu-kvm) + +This new helper fetches file system type for a fd. Only Linux is +implemented so far. Currently only tmpfs and hugetlbfs are defined, +but it can grow as needed. + +Signed-off-by: Peter Xu +Reviewed-by: David Hildenbrand +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit fa45f8dab9613993c042176ea2d25552bfebc955) +Signed-off-by: Peter Xu +--- + include/qemu/mmap-alloc.h | 7 +++++++ + util/mmap-alloc.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h +index 2825e231a7..8344daaa03 100644 +--- a/include/qemu/mmap-alloc.h ++++ b/include/qemu/mmap-alloc.h +@@ -1,8 +1,15 @@ + #ifndef QEMU_MMAP_ALLOC_H + #define QEMU_MMAP_ALLOC_H + ++typedef enum { ++ QEMU_FS_TYPE_UNKNOWN = 0, ++ QEMU_FS_TYPE_TMPFS, ++ QEMU_FS_TYPE_HUGETLBFS, ++ QEMU_FS_TYPE_NUM, ++} QemuFsType; + + size_t qemu_fd_getpagesize(int fd); ++QemuFsType qemu_fd_getfs(int fd); + + /** + * qemu_ram_mmap: mmap anonymous memory, the specified file or device. +diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c +index 5ed7d29183..ed14f9c64d 100644 +--- a/util/mmap-alloc.c ++++ b/util/mmap-alloc.c +@@ -27,8 +27,36 @@ + + #ifdef CONFIG_LINUX + #include ++#include + #endif + ++QemuFsType qemu_fd_getfs(int fd) ++{ ++#ifdef CONFIG_LINUX ++ struct statfs fs; ++ int ret; ++ ++ if (fd < 0) { ++ return QEMU_FS_TYPE_UNKNOWN; ++ } ++ ++ do { ++ ret = fstatfs(fd, &fs); ++ } while (ret != 0 && errno == EINTR); ++ ++ switch (fs.f_type) { ++ case TMPFS_MAGIC: ++ return QEMU_FS_TYPE_TMPFS; ++ case HUGETLBFS_MAGIC: ++ return QEMU_FS_TYPE_HUGETLBFS; ++ default: ++ return QEMU_FS_TYPE_UNKNOWN; ++ } ++#else ++ return QEMU_FS_TYPE_UNKNOWN; ++#endif ++} ++ + size_t qemu_fd_getpagesize(int fd) + { + #ifdef CONFIG_LINUX +-- +2.39.1 + diff --git a/kvm-vl.c-Create-late-backends-before-migration-object.patch b/kvm-vl.c-Create-late-backends-before-migration-object.patch new file mode 100644 index 0000000..e1eef6d --- /dev/null +++ b/kvm-vl.c-Create-late-backends-before-migration-object.patch @@ -0,0 +1,58 @@ +From 63e2339a6f38706c6fc5eb251426812520db6a6d Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 19 Apr 2023 12:17:37 -0400 +Subject: [PATCH 03/56] vl.c: Create late backends before migration object +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 162: migration: Pretty failures for postcopy on unsupported memory types +RH-Bugzilla: 2057267 +RH-Acked-by: Leonardo Brás +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Commit: [2/50] 7209bb94faa48650388be8fef08c77afd26517d8 (peterx/qemu-kvm) + +The migration object may want to check against different types of memory +when initialized. Delay the creation to be after late backends. + +Signed-off-by: Peter Xu +Reviewed-by: Juan Quintela +Reviewed-by: David Hildenbrand +Signed-off-by: Juan Quintela +(cherry picked from commit cb9d8b8ce1aaf38f53295fc59ec1b8b7eb4338d2) +Signed-off-by: Peter Xu +--- + softmmu/vl.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/softmmu/vl.c b/softmmu/vl.c +index ad4173138d..a44b49430b 100644 +--- a/softmmu/vl.c ++++ b/softmmu/vl.c +@@ -3592,14 +3592,19 @@ void qemu_init(int argc, char **argv) + machine_class->name, machine_class->deprecation_reason); + } + ++ /* ++ * Create backends before creating migration objects, so that it can ++ * check against compatibilities on the backend memories (e.g. postcopy ++ * over memory-backend-file objects). ++ */ ++ qemu_create_late_backends(); ++ + /* + * Note: creates a QOM object, must run only after global and + * compat properties have been set up. + */ + migration_object_init(); + +- qemu_create_late_backends(); +- + /* parse features once if machine provides default cpu_type */ + current_machine->cpu_type = machine_class->default_cpu_type; + if (cpu_option) { +-- +2.39.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 4cb63d3..e7c5444 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -148,7 +148,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 8.0.0 -Release: 3%{?rcrel}%{?dist}%{?cc_suffix} +Release: 4%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -199,6 +199,116 @@ Patch22: kvm-hw-acpi-Mark-acpi-blobs-as-resizable-on-RHEL-pc-mach.patch Patch23: kvm-migration-Handle-block-device-inactivation-failures-.patch # For bz#2058982 - Qemu core dump if cut off nfs storage during migration Patch24: kvm-migration-Minor-control-flow-simplification.patch +# For bz#2058982 - Qemu core dump if cut off nfs storage during migration +Patch25: kvm-migration-Attempt-disk-reactivation-in-more-failure-.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch26: kvm-util-mmap-alloc-qemu_fd_getfs.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch27: kvm-vl.c-Create-late-backends-before-migration-object.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch28: kvm-migration-postcopy-Detect-file-system-on-dest-host.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch29: kvm-migration-mark-mixed-functions-that-can-suspend.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch30: kvm-postcopy-ram-do-not-use-qatomic_mb_read.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch31: kvm-migration-remove-extra-whitespace-character-for-code.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch32: kvm-migration-Merge-ram_counters-and-ram_atomic_counters.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch33: kvm-migration-Update-atomic-stats-out-of-the-mutex.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch34: kvm-migration-Make-multifd_bytes-atomic.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch35: kvm-migration-Make-dirty_sync_missed_zero_copy-atomic.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch36: kvm-migration-Make-precopy_bytes-atomic.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch37: kvm-migration-Make-downtime_bytes-atomic.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch38: kvm-migration-Make-dirty_sync_count-atomic.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch39: kvm-migration-Make-postcopy_requests-atomic.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch40: kvm-migration-Rename-duplicate-to-zero_pages.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch41: kvm-migration-Rename-normal-to-normal_pages.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch42: kvm-migration-rename-enabled_capabilities-to-capabilitie.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch43: kvm-migration-Pass-migrate_caps_check-the-old-and-new-ca.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch44: kvm-migration-move-migration_global_dump-to-migration-hm.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch45: kvm-spice-move-client_migrate_info-command-to-ui.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch46: kvm-migration-Create-migrate_cap_set.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch47: kvm-migration-Create-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch48: kvm-migration-Move-migrate_colo_enabled-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch49: kvm-migration-Move-migrate_use_compression-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch50: kvm-migration-Move-migrate_use_events-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch51: kvm-migration-Move-migrate_use_multifd-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch52: kvm-migration-Move-migrate_use_zero_copy_send-to-options.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch53: kvm-migration-Move-migrate_use_xbzrle-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch54: kvm-migration-Move-migrate_use_block-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch55: kvm-migration-Move-migrate_use_return-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch56: kvm-migration-Create-migrate_rdma_pin_all-function.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch57: kvm-migration-Move-migrate_caps_check-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch58: kvm-migration-Move-qmp_query_migrate_capabilities-to-opt.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch59: kvm-migration-Move-qmp_migrate_set_capabilities-to-optio.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch60: kvm-migration-Move-migrate_cap_set-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch61: kvm-migration-Move-parameters-functions-to-option.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch62: kvm-migration-Use-migrate_max_postcopy_bandwidth.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch63: kvm-migration-Move-migrate_use_block_incremental-to-opti.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch64: kvm-migration-Create-migrate_throttle_trigger_threshold.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch65: kvm-migration-Create-migrate_checkpoint_delay.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch66: kvm-migration-Create-migrate_max_cpu_throttle.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch67: kvm-migration-Move-migrate_announce_params-to-option.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch68: kvm-migration-Create-migrate_cpu_throttle_initial-to-opt.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch69: kvm-migration-Create-migrate_cpu_throttle_increment-func.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch70: kvm-migration-Create-migrate_cpu_throttle_tailslow-funct.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch71: kvm-migration-Move-migrate_postcopy-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch72: kvm-migration-Create-migrate_max_bandwidth-function.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch73: kvm-migration-Move-migrate_use_tls-to-options.c.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch74: kvm-migration-Move-qmp_migrate_set_parameters-to-options.patch +# For bz#2057267 - Migration with postcopy fail when vm set with shared memory +Patch75: kvm-migration-Allow-postcopy_ram_supported_by_host-to-re.patch +# For bz#2185688 - [qemu-kvm] no response with QMP command block_resize +Patch76: kvm-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch +# For bz#2185688 - [qemu-kvm] no response with QMP command block_resize +Patch77: kvm-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch +# For bz#2185688 - [qemu-kvm] no response with QMP command block_resize +Patch78: kvm-iotests-Use-alternative-CPU-type-that-is-not-depreca.patch +# For bz#2185688 - [qemu-kvm] no response with QMP command block_resize +Patch79: kvm-iotests-Test-resizing-image-attached-to-an-iothread.patch %if %{have_clang} BuildRequires: clang @@ -215,6 +325,7 @@ BuildRequires: glib2-devel BuildRequires: gnutls-devel BuildRequires: cyrus-sasl-devel BuildRequires: libaio-devel +BuildRequires: liburing-devel BuildRequires: python3-devel BuildRequires: libattr-devel BuildRequires: libusbx-devel >= %{libusbx_version} @@ -713,6 +824,7 @@ run_configure \ --enable-libusb \ --enable-libudev \ --enable-linux-aio \ + --enable-linux-io-uring \ --enable-lzo \ --enable-malloc-trim \ --enable-modules \ @@ -1221,6 +1333,72 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Mon May 22 2023 Miroslav Rezanina - 8.0.0-4 +- kvm-migration-Attempt-disk-reactivation-in-more-failure-.patch [bz#2058982] +- kvm-util-mmap-alloc-qemu_fd_getfs.patch [bz#2057267] +- kvm-vl.c-Create-late-backends-before-migration-object.patch [bz#2057267] +- kvm-migration-postcopy-Detect-file-system-on-dest-host.patch [bz#2057267] +- kvm-migration-mark-mixed-functions-that-can-suspend.patch [bz#2057267] +- kvm-postcopy-ram-do-not-use-qatomic_mb_read.patch [bz#2057267] +- kvm-migration-remove-extra-whitespace-character-for-code.patch [bz#2057267] +- kvm-migration-Merge-ram_counters-and-ram_atomic_counters.patch [bz#2057267] +- kvm-migration-Update-atomic-stats-out-of-the-mutex.patch [bz#2057267] +- kvm-migration-Make-multifd_bytes-atomic.patch [bz#2057267] +- kvm-migration-Make-dirty_sync_missed_zero_copy-atomic.patch [bz#2057267] +- kvm-migration-Make-precopy_bytes-atomic.patch [bz#2057267] +- kvm-migration-Make-downtime_bytes-atomic.patch [bz#2057267] +- kvm-migration-Make-dirty_sync_count-atomic.patch [bz#2057267] +- kvm-migration-Make-postcopy_requests-atomic.patch [bz#2057267] +- kvm-migration-Rename-duplicate-to-zero_pages.patch [bz#2057267] +- kvm-migration-Rename-normal-to-normal_pages.patch [bz#2057267] +- kvm-migration-rename-enabled_capabilities-to-capabilitie.patch [bz#2057267] +- kvm-migration-Pass-migrate_caps_check-the-old-and-new-ca.patch [bz#2057267] +- kvm-migration-move-migration_global_dump-to-migration-hm.patch [bz#2057267] +- kvm-spice-move-client_migrate_info-command-to-ui.patch [bz#2057267] +- kvm-migration-Create-migrate_cap_set.patch [bz#2057267] +- kvm-migration-Create-options.c.patch [bz#2057267] +- kvm-migration-Move-migrate_colo_enabled-to-options.c.patch [bz#2057267] +- kvm-migration-Move-migrate_use_compression-to-options.c.patch [bz#2057267] +- kvm-migration-Move-migrate_use_events-to-options.c.patch [bz#2057267] +- kvm-migration-Move-migrate_use_multifd-to-options.c.patch [bz#2057267] +- kvm-migration-Move-migrate_use_zero_copy_send-to-options.patch [bz#2057267] +- kvm-migration-Move-migrate_use_xbzrle-to-options.c.patch [bz#2057267] +- kvm-migration-Move-migrate_use_block-to-options.c.patch [bz#2057267] +- kvm-migration-Move-migrate_use_return-to-options.c.patch [bz#2057267] +- kvm-migration-Create-migrate_rdma_pin_all-function.patch [bz#2057267] +- kvm-migration-Move-migrate_caps_check-to-options.c.patch [bz#2057267] +- kvm-migration-Move-qmp_query_migrate_capabilities-to-opt.patch [bz#2057267] +- kvm-migration-Move-qmp_migrate_set_capabilities-to-optio.patch [bz#2057267] +- kvm-migration-Move-migrate_cap_set-to-options.c.patch [bz#2057267] +- kvm-migration-Move-parameters-functions-to-option.c.patch [bz#2057267] +- kvm-migration-Use-migrate_max_postcopy_bandwidth.patch [bz#2057267] +- kvm-migration-Move-migrate_use_block_incremental-to-opti.patch [bz#2057267] +- kvm-migration-Create-migrate_throttle_trigger_threshold.patch [bz#2057267] +- kvm-migration-Create-migrate_checkpoint_delay.patch [bz#2057267] +- kvm-migration-Create-migrate_max_cpu_throttle.patch [bz#2057267] +- kvm-migration-Move-migrate_announce_params-to-option.c.patch [bz#2057267] +- kvm-migration-Create-migrate_cpu_throttle_initial-to-opt.patch [bz#2057267] +- kvm-migration-Create-migrate_cpu_throttle_increment-func.patch [bz#2057267] +- kvm-migration-Create-migrate_cpu_throttle_tailslow-funct.patch [bz#2057267] +- kvm-migration-Move-migrate_postcopy-to-options.c.patch [bz#2057267] +- kvm-migration-Create-migrate_max_bandwidth-function.patch [bz#2057267] +- kvm-migration-Move-migrate_use_tls-to-options.c.patch [bz#2057267] +- kvm-migration-Move-qmp_migrate_set_parameters-to-options.patch [bz#2057267] +- kvm-migration-Allow-postcopy_ram_supported_by_host-to-re.patch [bz#2057267] +- kvm-block-bdrv-blk_co_unref-for-calls-in-coroutine-conte.patch [bz#2185688] +- kvm-block-Don-t-call-no_coroutine_fns-in-qmp_block_resiz.patch [bz#2185688] +- kvm-iotests-Use-alternative-CPU-type-that-is-not-depreca.patch [bz#2185688] +- kvm-iotests-Test-resizing-image-attached-to-an-iothread.patch [bz#2185688] +- kvm-Enable-Linux-io_uring.patch [bz#1947230] +- Resolves: bz#2058982 + (Qemu core dump if cut off nfs storage during migration) +- Resolves: bz#2057267 + (Migration with postcopy fail when vm set with shared memory) +- Resolves: bz#2185688 + ([qemu-kvm] no response with QMP command block_resize) +- Resolves: bz#1947230 + (Enable QEMU support for io_uring in RHEL9) + * Mon May 15 2023 Miroslav Rezanina - 8.0.0-3 - kvm-migration-Handle-block-device-inactivation-failures-.patch [bz#2058982] - kvm-migration-Minor-control-flow-simplification.patch [bz#2058982]