From: Peter Xu <peterx@redhat.com>
To: Yanfei Xu <yanfei.xu@bytedance.com>
Cc: qemu-devel@nongnu.org, farosas@suse.de, lizhijian@fujitsu.com,
isyanfei.xu@gmail.com, jinpu.wang@cloud.ionos.com
Subject: Re: [RFC PATCH v1 2/2] migration/rdma: Allow multiple in-flight writes per chunk
Date: Thu, 20 Aug 2026 15:39:39 -0400 [thread overview]
Message-ID: <aodX-7MIcGXmHEpP@x1.local> (raw)
In-Reply-To: <20260820125833.1541756-3-yanfei.xu@bytedance.com>
On Thu, Aug 20, 2026 at 08:58:33PM +0800, Yanfei Xu wrote:
> qemu_rdma_write_one() waits for an earlier write to the same
> registration chunk to complete. This serializes disjoint dirty ranges
> in a chunk and leaves send queue capacity unused.
>
> Remove the per-chunk wait and use the reference counts to track all
> outstanding writes. The existing per-iteration drain remains the
> completion barrier.
I think this should work (by accident; will explain below), but I want to
raise the definition of iteration here, and it may or may not be what was
expected.
Migration core has this problem likely since 10+ years ago when it start to
have two definitions..
- Each time ram_save_iterate() is invoked: this is the "iteration" that
RDMA is tracking, it does qemu_rdma_drain_cq() when finishing for each
call (applies to complete() too)
- Each time migration RAM core syncs dirty info and re-scans the whole
guest memories (all ramblocks)
For RDMA (and non-RDMA too), what matters is for each same page its new
version always lands *after* its old version. IIUC, what it really needs
is defintion 2), not 1).. See the call of multifd_ram_sync_per_round() of
find_dirty_block(), so it was called "a round" there, but I believe we
report such iteration count (in reality, "dirty-sync-count") in QMP
query-migrate with this concept.
I still think relying on the qemu_rdma_drain_cq() should be fine for now,
it's because currently we hold bitmap_mutex across the whole
ram_save_iterate() (NOTE: postcopy preempt may release it.. another thing
to discuss..), so bmap at least for precopy shouldn't be able to change, it
also means for each ram_save_iterate() we shouldn't be sending the same
page twice. But I think it's risky relying on that fact, e.g. we already
have concurrent sync dirty bitmap, like cpu_throttle_dirty_sync_timer_tick,
so maybe it's better RDMA also flush its pages at definition 2) not 1).
IIUC, it'll also improve on performance because RDMA needs to flush less.
Maybe we should make it a generic API in find_dirty_block(), like
notifiers, so that multifd (and maybe RDMA too?) doesn't need to hard code
things like multifd_ram_flush_and_sync().
Thanks,
>
> Signed-off-by: Yanfei Xu <yanfei.xu@bytedance.com>
> ---
> migration/rdma.c | 19 +------------------
> migration/trace-events | 1 -
> 2 files changed, 1 insertion(+), 19 deletions(-)
>
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 973a7a745a..63bc357657 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -1869,7 +1869,7 @@ static int qemu_rdma_write_one(RDMAContext *rdma,
> struct ibv_sge sge;
> struct ibv_send_wr send_wr = { 0 };
> struct ibv_send_wr *bad_wr;
> - int reg_result_idx, ret, count = 0;
> + int reg_result_idx, ret;
> uint64_t chunk, chunks;
> uint64_t chunk_size = migrate_rdma_chunk_size();
> uint8_t *chunk_start, *chunk_end;
> @@ -1910,23 +1910,6 @@ retry:
>
> chunk_end = ram_chunk_end(block, chunk + chunks);
>
> -
> - while (qemu_rdma_chunk_in_transit(block, chunk)) {
> - (void)count;
> - trace_qemu_rdma_write_one_block(count++, current_index, chunk,
> - sge.addr, length, rdma->nb_sent, block->nb_chunks);
> -
> - ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
> -
> - if (ret < 0) {
> - error_setg(errp, "Failed to Wait for previous write to complete "
> - "block %d chunk %" PRIu64
> - " current %" PRIu64 " len %" PRIu64 " %d",
> - current_index, chunk, sge.addr, length, rdma->nb_sent);
> - return -1;
> - }
> - }
> -
> if (!rdma->pin_all || !block->is_ram_block) {
> if (!block->remote_keys[chunk]) {
> /*
> diff --git a/migration/trace-events b/migration/trace-events
> index 172761be78..253ff71891 100644
> --- a/migration/trace-events
> +++ b/migration/trace-events
> @@ -249,7 +249,6 @@ qemu_rdma_unregister_waiting_proc(uint64_t chunk, int pos) "Processing unregiste
> qemu_rdma_unregister_waiting_send(uint64_t chunk) "Sending unregister for chunk: %" PRIu64
> qemu_rdma_unregister_waiting_complete(uint64_t chunk) "Unregister for chunk: %" PRIu64 " complete."
> qemu_rdma_write_flush(int sent) "sent total: %d"
> -qemu_rdma_write_one_block(int count, int block, uint64_t chunk, uint64_t current, uint64_t len, int nb_sent, int nb_chunks) "(%d) Not clobbering: block: %d chunk %" PRIu64 " current %" PRIu64 " len %" PRIu64 " %d %d"
> qemu_rdma_write_one_post(uint64_t chunk, long addr, long remote, uint32_t len) "Posting chunk: %" PRIu64 ", addr: 0x%lx remote: 0x%lx, bytes %" PRIu32
> qemu_rdma_write_one_queue_full(void) ""
> qemu_rdma_write_one_recvregres(int mykey, int theirkey, uint64_t chunk) "Received registration result: my key: 0x%x their key 0x%x, chunk %" PRIu64
> --
> 2.20.1
>
--
Peter Xu
next prev parent reply other threads:[~2026-08-20 19:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 12:58 [RFC PATCH v1 0/2] migration/rdma: Allow multiple writes per chunk Yanfei Xu
2026-08-20 12:58 ` [RFC PATCH v1 1/2] migration/rdma: Track in-flight writes with refcounts Yanfei Xu
2026-08-20 12:58 ` [RFC PATCH v1 2/2] migration/rdma: Allow multiple in-flight writes per chunk Yanfei Xu
2026-08-20 19:39 ` Peter Xu [this message]
2026-08-20 19:59 ` [RFC PATCH v1 0/2] migration/rdma: Allow multiple " 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=aodX-7MIcGXmHEpP@x1.local \
--to=peterx@redhat.com \
--cc=farosas@suse.de \
--cc=isyanfei.xu@gmail.com \
--cc=jinpu.wang@cloud.ionos.com \
--cc=lizhijian@fujitsu.com \
--cc=qemu-devel@nongnu.org \
--cc=yanfei.xu@bytedance.com \
/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.