* [PATCH v4 RESEND 1/4] guestperf: Support deferred migration for multifd
2025-02-14 10:55 [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment yong.huang
@ 2025-02-14 10:55 ` yong.huang
2025-02-14 10:55 ` [PATCH v4 RESEND 2/4] guestperf: Nitpick the inconsistent parameters yong.huang
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: yong.huang @ 2025-02-14 10:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Fabiano Rosas, Peter Xu, Daniel P . Berrangé, Hyman Huang
From: Hyman Huang <yong.huang@smartx.com>
The way to enable multifd migration has been changed by commit,
82137e6c8c (migration: enforce multifd and postcopy preempt to
be set before incoming), and guestperf has not made the
necessary changes. If multifd migration had been enabled in the
previous manner, the following error would have occurred:
Multifd must be set before incoming starts
Supporting deferred migration will fix it.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
---
tests/migration-stress/guestperf/engine.py | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/tests/migration-stress/guestperf/engine.py b/tests/migration-stress/guestperf/engine.py
index 608d7270f6..4b15322e8d 100644
--- a/tests/migration-stress/guestperf/engine.py
+++ b/tests/migration-stress/guestperf/engine.py
@@ -106,7 +106,8 @@ def _migrate_progress(self, vm):
info.get("dirty-limit-ring-full-time", 0),
)
- def _migrate(self, hardware, scenario, src, dst, connect_uri):
+ def _migrate(self, hardware, scenario, src,
+ dst, connect_uri, defer_migrate):
src_qemu_time = []
src_vcpu_time = []
src_pid = src.get_pid()
@@ -220,6 +221,8 @@ def _migrate(self, hardware, scenario, src, dst, connect_uri):
resp = src.cmd("migrate-set-parameters",
vcpu_dirty_limit=scenario._vcpu_dirty_limit)
+ if defer_migrate:
+ resp = dst.cmd("migrate-incoming", uri=connect_uri)
resp = src.cmd("migrate", uri=connect_uri)
post_copy = False
@@ -373,11 +376,14 @@ def _get_common_args(self, hardware, tunnelled=False):
def _get_src_args(self, hardware):
return self._get_common_args(hardware)
- def _get_dst_args(self, hardware, uri):
+ def _get_dst_args(self, hardware, uri, defer_migrate):
tunnelled = False
if self._dst_host != "localhost":
tunnelled = True
argv = self._get_common_args(hardware, tunnelled)
+
+ if defer_migrate:
+ return argv + ["-incoming", "defer"]
return argv + ["-incoming", uri]
@staticmethod
@@ -424,6 +430,7 @@ def _get_timings(self, vm):
def run(self, hardware, scenario, result_dir=os.getcwd()):
abs_result_dir = os.path.join(result_dir, scenario._name)
+ defer_migrate = False
if self._transport == "tcp":
uri = "tcp:%s:9000" % self._dst_host
@@ -439,6 +446,9 @@ def run(self, hardware, scenario, result_dir=os.getcwd()):
except:
pass
+ if scenario._multifd:
+ defer_migrate = True
+
if self._dst_host != "localhost":
dstmonaddr = ("localhost", 9001)
else:
@@ -452,7 +462,7 @@ def run(self, hardware, scenario, result_dir=os.getcwd()):
monitor_address=srcmonaddr)
dst = QEMUMachine(self._binary,
- args=self._get_dst_args(hardware, uri),
+ args=self._get_dst_args(hardware, uri, defer_migrate),
wrapper=self._get_dst_wrapper(hardware),
name="qemu-dst-%d" % os.getpid(),
monitor_address=dstmonaddr)
@@ -461,7 +471,8 @@ def run(self, hardware, scenario, result_dir=os.getcwd()):
src.launch()
dst.launch()
- ret = self._migrate(hardware, scenario, src, dst, uri)
+ ret = self._migrate(hardware, scenario, src,
+ dst, uri, defer_migrate)
progress_history = ret[0]
qemu_timings = ret[1]
vcpu_timings = ret[2]
--
2.27.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v4 RESEND 2/4] guestperf: Nitpick the inconsistent parameters
2025-02-14 10:55 [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment yong.huang
2025-02-14 10:55 ` [PATCH v4 RESEND 1/4] guestperf: Support deferred migration for multifd yong.huang
@ 2025-02-14 10:55 ` yong.huang
2025-02-14 10:55 ` [PATCH v4 RESEND 3/4] guestperf: Introduce multifd compression option yong.huang
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: yong.huang @ 2025-02-14 10:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Fabiano Rosas, Peter Xu, Daniel P . Berrangé, Hyman Huang
From: Hyman Huang <yong.huang@smartx.com>
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
---
tests/migration-stress/guestperf/comparison.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/migration-stress/guestperf/comparison.py b/tests/migration-stress/guestperf/comparison.py
index 42cc0372d1..40e9d2eb1d 100644
--- a/tests/migration-stress/guestperf/comparison.py
+++ b/tests/migration-stress/guestperf/comparison.py
@@ -127,7 +127,7 @@ def __init__(self, name, scenarios):
# varying numbers of channels
Comparison("compr-multifd", scenarios = [
Scenario("compr-multifd-channels-4",
- multifd=True, multifd_channels=2),
+ multifd=True, multifd_channels=4),
Scenario("compr-multifd-channels-8",
multifd=True, multifd_channels=8),
Scenario("compr-multifd-channels-32",
--
2.27.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v4 RESEND 3/4] guestperf: Introduce multifd compression option
2025-02-14 10:55 [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment yong.huang
2025-02-14 10:55 ` [PATCH v4 RESEND 1/4] guestperf: Support deferred migration for multifd yong.huang
2025-02-14 10:55 ` [PATCH v4 RESEND 2/4] guestperf: Nitpick the inconsistent parameters yong.huang
@ 2025-02-14 10:55 ` yong.huang
2025-02-14 10:55 ` [PATCH v4 RESEND 4/4] guestperf: Add test result data into report yong.huang
2025-02-14 18:13 ` [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment Fabiano Rosas
4 siblings, 0 replies; 7+ messages in thread
From: yong.huang @ 2025-02-14 10:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Fabiano Rosas, Peter Xu, Daniel P . Berrangé, Hyman Huang
From: Hyman Huang <yong.huang@smartx.com>
Guestperf tool does not cover the multifd compression option
currently, it is worth supporting so that developers can
analysis the migration performance with different
compression algorithms.
Multifd support 4 compression algorithms currently:
zlib, zstd, qpl, uadk
To request that multifd with the specified compression
algorithm such as zlib:
$ ./tests/migration-stress/guestperf.py \
--multifd --multifd-channels 4 --multifd-compression zlib \
--output output.json
To run the entire standardized set of multifd compression
comparisons, with unix migration:
$ ./tests/migration-stress/guestperf-batch.py \
--dst-host localhost --transport unix \
--filter compr-multifd-compression* --output outputdir
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
---
tests/migration-stress/guestperf/comparison.py | 13 +++++++++++++
tests/migration-stress/guestperf/engine.py | 14 ++++++++++++++
tests/migration-stress/guestperf/scenario.py | 7 +++++--
tests/migration-stress/guestperf/shell.py | 3 +++
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/tests/migration-stress/guestperf/comparison.py b/tests/migration-stress/guestperf/comparison.py
index 40e9d2eb1d..dee3ac25e4 100644
--- a/tests/migration-stress/guestperf/comparison.py
+++ b/tests/migration-stress/guestperf/comparison.py
@@ -158,4 +158,17 @@ def __init__(self, name, scenarios):
Scenario("compr-dirty-limit-50MB",
dirty_limit=True, vcpu_dirty_limit=50),
]),
+
+ # Looking at effect of multifd with
+ # different compression algorithms
+ Comparison("compr-multifd-compression", scenarios = [
+ Scenario("compr-multifd-compression-zlib",
+ multifd=True, multifd_channels=2, multifd_compression="zlib"),
+ Scenario("compr-multifd-compression-zstd",
+ multifd=True, multifd_channels=2, multifd_compression="zstd"),
+ Scenario("compr-multifd-compression-qpl",
+ multifd=True, multifd_channels=2, multifd_compression="qpl"),
+ Scenario("compr-multifd-compression-uadk",
+ multifd=True, multifd_channels=2, multifd_compression="uadk"),
+ ]),
]
diff --git a/tests/migration-stress/guestperf/engine.py b/tests/migration-stress/guestperf/engine.py
index 4b15322e8d..e11f6a8496 100644
--- a/tests/migration-stress/guestperf/engine.py
+++ b/tests/migration-stress/guestperf/engine.py
@@ -31,6 +31,8 @@
'..', '..', '..', 'python'))
from qemu.machine import QEMUMachine
+# multifd supported compression algorithms
+MULTIFD_CMP_ALGS = ("zlib", "zstd", "qpl", "uadk")
class Engine(object):
@@ -191,6 +193,12 @@ def _migrate(self, hardware, scenario, src,
scenario._compression_xbzrle_cache))
if scenario._multifd:
+ if (scenario._multifd_compression and
+ (scenario._multifd_compression not in MULTIFD_CMP_ALGS)):
+ raise Exception("unsupported multifd compression "
+ "algorithm: %s" %
+ scenario._multifd_compression)
+
resp = src.cmd("migrate-set-capabilities",
capabilities = [
{ "capability": "multifd",
@@ -206,6 +214,12 @@ def _migrate(self, hardware, scenario, src,
resp = dst.cmd("migrate-set-parameters",
multifd_channels=scenario._multifd_channels)
+ if scenario._multifd_compression:
+ resp = src.cmd("migrate-set-parameters",
+ multifd_compression=scenario._multifd_compression)
+ resp = dst.cmd("migrate-set-parameters",
+ multifd_compression=scenario._multifd_compression)
+
if scenario._dirty_limit:
if not hardware._dirty_ring_size:
raise Exception("dirty ring size must be configured when "
diff --git a/tests/migration-stress/guestperf/scenario.py b/tests/migration-stress/guestperf/scenario.py
index 154c4f5d5f..4be7fafebf 100644
--- a/tests/migration-stress/guestperf/scenario.py
+++ b/tests/migration-stress/guestperf/scenario.py
@@ -30,7 +30,7 @@ def __init__(self, name,
auto_converge=False, auto_converge_step=10,
compression_mt=False, compression_mt_threads=1,
compression_xbzrle=False, compression_xbzrle_cache=10,
- multifd=False, multifd_channels=2,
+ multifd=False, multifd_channels=2, multifd_compression="",
dirty_limit=False, x_vcpu_dirty_limit_period=500,
vcpu_dirty_limit=1):
@@ -61,6 +61,7 @@ def __init__(self, name,
self._multifd = multifd
self._multifd_channels = multifd_channels
+ self._multifd_compression = multifd_compression
self._dirty_limit = dirty_limit
self._x_vcpu_dirty_limit_period = x_vcpu_dirty_limit_period
@@ -85,6 +86,7 @@ def serialize(self):
"compression_xbzrle_cache": self._compression_xbzrle_cache,
"multifd": self._multifd,
"multifd_channels": self._multifd_channels,
+ "multifd_compression": self._multifd_compression,
"dirty_limit": self._dirty_limit,
"x_vcpu_dirty_limit_period": self._x_vcpu_dirty_limit_period,
"vcpu_dirty_limit": self._vcpu_dirty_limit,
@@ -109,4 +111,5 @@ def deserialize(cls, data):
data["compression_xbzrle"],
data["compression_xbzrle_cache"],
data["multifd"],
- data["multifd_channels"])
+ data["multifd_channels"],
+ data["multifd_compression"])
diff --git a/tests/migration-stress/guestperf/shell.py b/tests/migration-stress/guestperf/shell.py
index 046afeb84e..63bbe3226c 100644
--- a/tests/migration-stress/guestperf/shell.py
+++ b/tests/migration-stress/guestperf/shell.py
@@ -131,6 +131,8 @@ def __init__(self):
action="store_true")
parser.add_argument("--multifd-channels", dest="multifd_channels",
default=2, type=int)
+ parser.add_argument("--multifd-compression", dest="multifd_compression",
+ default="")
parser.add_argument("--dirty-limit", dest="dirty_limit", default=False,
action="store_true")
@@ -167,6 +169,7 @@ def get_scenario(self, args):
multifd=args.multifd,
multifd_channels=args.multifd_channels,
+ multifd_compression=args.multifd_compression,
dirty_limit=args.dirty_limit,
x_vcpu_dirty_limit_period=\
--
2.27.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v4 RESEND 4/4] guestperf: Add test result data into report
2025-02-14 10:55 [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment yong.huang
` (2 preceding siblings ...)
2025-02-14 10:55 ` [PATCH v4 RESEND 3/4] guestperf: Introduce multifd compression option yong.huang
@ 2025-02-14 10:55 ` yong.huang
2025-02-14 14:26 ` Fabiano Rosas
2025-02-14 18:13 ` [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment Fabiano Rosas
4 siblings, 1 reply; 7+ messages in thread
From: yong.huang @ 2025-02-14 10:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Fabiano Rosas, Peter Xu, Daniel P . Berrangé, Hyman Huang
From: Hyman Huang <yong.huang@smartx.com>
The migration result data is not included in the guestperf
report information; include the result as a report entry
so the developer can check whether the migration was successful
after running guestperf.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
tests/migration-stress/guestperf/engine.py | 10 ++++++++--
tests/migration-stress/guestperf/report.py | 20 ++++++++++++++++++++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/tests/migration-stress/guestperf/engine.py b/tests/migration-stress/guestperf/engine.py
index e11f6a8496..d8462db765 100644
--- a/tests/migration-stress/guestperf/engine.py
+++ b/tests/migration-stress/guestperf/engine.py
@@ -24,7 +24,7 @@
import time
from guestperf.progress import Progress, ProgressStats
-from guestperf.report import Report
+from guestperf.report import Report, ReportResult
from guestperf.timings import TimingRecord, Timings
sys.path.append(os.path.join(os.path.dirname(__file__),
@@ -276,7 +276,11 @@ def _migrate(self, hardware, scenario, src,
src_vcpu_time.extend(self._vcpu_timing(src_pid, src_threads))
sleep_secs -= 1
- return [progress_history, src_qemu_time, src_vcpu_time]
+ result = ReportResult()
+ if progress._status == "completed" and not paused:
+ result = ReportResult(True)
+
+ return [progress_history, src_qemu_time, src_vcpu_time, result]
if self._verbose and (loop % 20) == 0:
print("Iter %d: remain %5dMB of %5dMB (total %5dMB @ %5dMb/sec)" % (
@@ -490,6 +494,7 @@ def run(self, hardware, scenario, result_dir=os.getcwd()):
progress_history = ret[0]
qemu_timings = ret[1]
vcpu_timings = ret[2]
+ result = ret[3]
if uri[0:5] == "unix:" and os.path.exists(uri[5:]):
os.remove(uri[5:])
@@ -509,6 +514,7 @@ def run(self, hardware, scenario, result_dir=os.getcwd()):
Timings(self._get_timings(src) + self._get_timings(dst)),
Timings(qemu_timings),
Timings(vcpu_timings),
+ result,
self._binary, self._dst_host, self._kernel,
self._initrd, self._transport, self._sleep)
except Exception as e:
diff --git a/tests/migration-stress/guestperf/report.py b/tests/migration-stress/guestperf/report.py
index 1efd40c868..e135e01be6 100644
--- a/tests/migration-stress/guestperf/report.py
+++ b/tests/migration-stress/guestperf/report.py
@@ -24,6 +24,22 @@
from guestperf.progress import Progress
from guestperf.timings import Timings
+class ReportResult(object):
+
+ def __init__(self, success=False):
+ self._success = success
+
+ def serialize(self):
+ return {
+ "success": self._success,
+ }
+
+ @classmethod
+ def deserialize(cls, data):
+ return cls(
+ data["success"])
+
+
class Report(object):
def __init__(self,
@@ -33,6 +49,7 @@ def __init__(self,
guest_timings,
qemu_timings,
vcpu_timings,
+ result,
binary,
dst_host,
kernel,
@@ -46,6 +63,7 @@ def __init__(self,
self._guest_timings = guest_timings
self._qemu_timings = qemu_timings
self._vcpu_timings = vcpu_timings
+ self._result = result
self._binary = binary
self._dst_host = dst_host
self._kernel = kernel
@@ -61,6 +79,7 @@ def serialize(self):
"guest_timings": self._guest_timings.serialize(),
"qemu_timings": self._qemu_timings.serialize(),
"vcpu_timings": self._vcpu_timings.serialize(),
+ "result": self._result.serialize(),
"binary": self._binary,
"dst_host": self._dst_host,
"kernel": self._kernel,
@@ -78,6 +97,7 @@ def deserialize(cls, data):
Timings.deserialize(data["guest_timings"]),
Timings.deserialize(data["qemu_timings"]),
Timings.deserialize(data["vcpu_timings"]),
+ ReportResult.deserialize(data["result"]),
data["binary"],
data["dst_host"],
data["kernel"],
--
2.27.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment
2025-02-14 10:55 [PATCH v4 RESEND 0/4] Guestperf: miscellaneous refinement and enrichment yong.huang
` (3 preceding siblings ...)
2025-02-14 10:55 ` [PATCH v4 RESEND 4/4] guestperf: Add test result data into report yong.huang
@ 2025-02-14 18:13 ` Fabiano Rosas
4 siblings, 0 replies; 7+ messages in thread
From: Fabiano Rosas @ 2025-02-14 18:13 UTC (permalink / raw)
To: yong.huang, qemu-devel; +Cc: Peter Xu, Daniel P . Berrangé, Hyman Huang
yong.huang@smartx.com writes:
> From: Hyman Huang <yong.huang@smartx.com>
>
> v4:
> 1. rebase v3 patchset on master
> 2. build initrd-stress.img manually like before as suggested by Peter and Fabiano
> 3. drop the [PATCH v3 1/5], [PATCH v3 2/5] patches
> 4. add an extra patch: [PATCH v4 4/4] guestperf: Add test result data into report
>
> Please review, thanks
> Yong
>
> v3:
> 1. Remove the two redundant assignments in [PATCH v2 2/5] suggested by Daniel
>
> v2:
> 1. Update the MAINTAINERS section suggested by Fabiano Rosas
> 2. Ensure the dependencies when build the initrd-stress.img suggested by Daniel
> 3. Fix some bugs
>
> v1:
> The previous patchset:
> https://lore.kernel.org/qemu-devel/cover.1722957352.git.yong.huang@smartx.com/
> does not made the necessary changes and tests for the upstream version.
>
> This patchset works for that:
> 1. Move the guestperf to scripts directory suggested by Fabiano Rosas
> 2. Make initrd-stress.img built by default suggested by Fabiano Rosas
> 3. Make the necessary changes to adapt the latest multifd behavior
> 4. A nitpick for multifd migration
> 5. Support multifd compression option
>
> Hyman Huang (4):
> guestperf: Support deferred migration for multifd
> guestperf: Nitpick the inconsistent parameters
> guestperf: Introduce multifd compression option
> guestperf: Add test result data into report
>
> .../migration-stress/guestperf/comparison.py | 15 ++++++-
> tests/migration-stress/guestperf/engine.py | 43 ++++++++++++++++---
> tests/migration-stress/guestperf/report.py | 20 +++++++++
> tests/migration-stress/guestperf/scenario.py | 7 ++-
> tests/migration-stress/guestperf/shell.py | 3 ++
> 5 files changed, 79 insertions(+), 9 deletions(-)
Queued, thanks!
^ permalink raw reply [flat|nested] 7+ messages in thread