From: Bin Guo <guobin@linux.alibaba.com>
To: qemu-devel@nongnu.org
Cc: peterx@redhat.com, farosas@suse.de
Subject: [PATCH 7/8] migration/multifd: cache migrate_multifd_channels() in send/recv hot paths
Date: Mon, 18 May 2026 19:01:11 +0800 [thread overview]
Message-ID: <20260518110112.21395-8-guobin@linux.alibaba.com> (raw)
In-Reply-To: <20260518110112.21395-1-guobin@linux.alibaba.com>
multifd_send() and multifd_recv() are on the per-page-batch hot path
of live migration. Both functions call migrate_multifd_channels()
multiple times (3-4 calls each) for modulo arithmetic in the
round-robin channel selection loop.
Each call goes through migrate_get_current() -> dereference
MigrationState -> read parameters.multifd_channels. While each
individual call is cheap, these functions execute for every page
batch during the entire migration, easily millions of times.
Cache the return value in a local variable at function entry. The
channel count is fixed for the duration of a migration and cannot
change mid-flight.
For multifd_send(): 3 calls reduced to 1.
For multifd_recv(): 4 calls reduced to 1.
Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
---
migration/multifd.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/migration/multifd.c b/migration/multifd.c
index 67ee9bdf5e..cc2fa90204 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -362,13 +362,15 @@ bool multifd_send(MultiFDSendData **send_data)
/* We wait here, until at least one channel is ready */
qemu_sem_wait(&multifd_send_state->channels_ready);
+ int thread_count = migrate_multifd_channels();
+
/*
* next_channel can remain from a previous migration that was
* using more channels, so ensure it doesn't overflow if the
* limit is lower now.
*/
- next_channel %= migrate_multifd_channels();
- for (i = next_channel;; i = (i + 1) % migrate_multifd_channels()) {
+ next_channel %= thread_count;
+ for (i = next_channel;; i = (i + 1) % thread_count) {
if (multifd_send_should_exit()) {
return false;
}
@@ -378,7 +380,7 @@ bool multifd_send(MultiFDSendData **send_data)
* sender thread can clear it.
*/
if (qatomic_read(&p->pending_job) == false) {
- next_channel = (i + 1) % migrate_multifd_channels();
+ next_channel = (i + 1) % thread_count;
break;
}
}
@@ -998,6 +1000,7 @@ bool multifd_recv(void)
int i;
static int next_recv_channel;
MultiFDRecvParams *p = NULL;
+ int thread_count = migrate_multifd_channels();
MultiFDRecvData *data = multifd_recv_state->data;
/*
@@ -1005,8 +1008,8 @@ bool multifd_recv(void)
* using more channels, so ensure it doesn't overflow if the
* limit is lower now.
*/
- next_recv_channel %= migrate_multifd_channels();
- for (i = next_recv_channel;; i = (i + 1) % migrate_multifd_channels()) {
+ next_recv_channel %= thread_count;
+ for (i = next_recv_channel;; i = (i + 1) % thread_count) {
if (multifd_recv_should_exit()) {
return false;
}
@@ -1014,7 +1017,7 @@ bool multifd_recv(void)
p = &multifd_recv_state->params[i];
if (qatomic_read(&p->pending_job) == false) {
- next_recv_channel = (i + 1) % migrate_multifd_channels();
+ next_recv_channel = (i + 1) % thread_count;
break;
}
}
--
2.50.1 (Apple Git-155)
next prev parent reply other threads:[~2026-05-18 11:02 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-18 11:01 [PATCH 0/8] migration: cleanups, fixes and micro-optimizations Bin Guo
2026-05-18 11:01 ` [PATCH 1/8] migration/fd: collapse migration_fd_valid into single boolean expression Bin Guo
2026-05-18 20:22 ` Fabiano Rosas
2026-05-18 11:01 ` [PATCH 2/8] migration/global_state: replace strcpy("") with explicit NUL termination Bin Guo
2026-05-18 20:32 ` Fabiano Rosas
2026-05-18 11:01 ` [PATCH 3/8] migration/vmstate: avoid per-element heap churn in vmsd ptr marker field Bin Guo
2026-05-19 7:32 ` Fabiano Rosas
2026-05-18 11:01 ` [PATCH 4/8] migration/savevm: use stack-allocated bitmap in configuration_validate_capabilities Bin Guo
2026-05-18 20:53 ` Fabiano Rosas
2026-05-18 11:01 ` [PATCH 5/8] migration/multifd: fix off-by-one in recv channel ID validation Bin Guo
2026-05-18 19:43 ` Fabiano Rosas
2026-05-18 11:01 ` [PATCH 6/8] migration/multifd: merge thread-join and cleanup loops in multifd_recv_cleanup Bin Guo
2026-05-18 20:21 ` Fabiano Rosas
2026-05-18 11:01 ` Bin Guo [this message]
2026-05-19 7:16 ` [PATCH 7/8] migration/multifd: cache migrate_multifd_channels() in send/recv hot paths Fabiano Rosas
2026-05-18 11:01 ` [PATCH 8/8] migration/multifd: cache channel count in multifd_send_sync_main Bin Guo
2026-05-19 7:17 ` Fabiano Rosas
2026-05-20 19:33 ` [PATCH 0/8] migration: cleanups, fixes and micro-optimizations Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260518110112.21395-8-guobin@linux.alibaba.com \
--to=guobin@linux.alibaba.com \
--cc=farosas@suse.de \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.