* [PATCH v2 0/3] migration/rdma: Misc RDMA migration fixes
@ 2026-08-21 13:35 Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 1/3] migration/rdma: Fix write-side shutdown Yanfei Xu
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Yanfei Xu @ 2026-08-21 13:35 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, farosas, lizhijian, jinpu.wang, isyanfei.xu, Yanfei Xu
This series fixes three RDMA migration issues.
v1->v2:
- patch1/2: Collect Reviewed-by
- patch2: Add reproducation step and error logs in commit message
- patch3: Wrap the post-send op and retry logic into a helper, and
retry only once after draining a completion when the queue
is full. (I believe ENOMEM is only recoverable in the
queue-full case, so we retry once; it should succeed after
a completion is drained. Any further ENOMEM is treated as
non-recoverable.)
Yanfei Xu (3):
migration/rdma: Fix write-side shutdown
migration/rdma: Post initial receive before accepting
migration/rdma: Retry control sends on full queue
migration/rdma.c | 92 ++++++++++++++++++++++++++----------------
migration/trace-events | 2 +-
2 files changed, 58 insertions(+), 36 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/3] migration/rdma: Fix write-side shutdown
2026-08-21 13:35 [PATCH v2 0/3] migration/rdma: Misc RDMA migration fixes Yanfei Xu
@ 2026-08-21 13:35 ` Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 2/3] migration/rdma: Post initial receive before accepting Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 3/3] migration/rdma: Retry control sends on full queue Yanfei Xu
2 siblings, 0 replies; 7+ messages in thread
From: Yanfei Xu @ 2026-08-21 13:35 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, farosas, lizhijian, jinpu.wang, isyanfei.xu, Yanfei Xu
qio_channel_rdma_shutdown() reads rdmain for both the input and
output contexts. As a result, a write-side shutdown marks the input
context as errored while leaving the output context active. A shutdown
of both directions also fails to stop the output context.
Read rdmaout from the output context so each shutdown direction marks
the corresponding RDMA context as errored.
Fixes: 54db882f073a ("migration: implement the shutdown for RDMA QIOChannel")
Signed-off-by: Yanfei Xu <yanfei.xu@bytedance.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Peter Xu <peterx@redhat.com>
---
migration/rdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/migration/rdma.c b/migration/rdma.c
index 438419d189..e17ace62b0 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -2982,7 +2982,7 @@ qio_channel_rdma_shutdown(QIOChannel *ioc,
RCU_READ_LOCK_GUARD();
rdmain = qatomic_rcu_read(&rioc->rdmain);
- rdmaout = qatomic_rcu_read(&rioc->rdmain);
+ rdmaout = qatomic_rcu_read(&rioc->rdmaout);
switch (how) {
case QIO_CHANNEL_SHUTDOWN_READ:
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/3] migration/rdma: Post initial receive before accepting
2026-08-21 13:35 [PATCH v2 0/3] migration/rdma: Misc RDMA migration fixes Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 1/3] migration/rdma: Fix write-side shutdown Yanfei Xu
@ 2026-08-21 13:35 ` Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 3/3] migration/rdma: Retry control sends on full queue Yanfei Xu
2 siblings, 0 replies; 7+ messages in thread
From: Yanfei Xu @ 2026-08-21 13:35 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, farosas, lizhijian, jinpu.wang, isyanfei.xu, Yanfei Xu
The source return-path thread can send READY before the destination has
posted its initial receive. Since RNR retries default to zero, the send
can fail and abort migration.
Post the initial receive before rdma_accept() to close this window.
Adding delays can easily reproduce it. For exmaple with sleep(1), error
could be found at the source side:
2026-08-20T05:55:11.471421Z qemu_rdma_exchange_get_response_start CONTROL: READY receiving...
2026-08-20T05:55:11.471422Z qemu_rdma_post_send_control CONTROL: sending QEMU FILE..
2026-08-20T05:55:11.471447Z qemu_rdma_poll_other other completion 2000 received left 0
2026-08-20T05:55:11.471589Z qemu_rdma_poll_recv completion 0 received (4000) left 0
2026-08-20T05:55:11.471592Z qemu_rdma_poll_other other completion 4000 received left 0
2026-08-20T05:55:11.471594Z qemu_rdma_exchange_get_response_start CONTROL: READY receiving...
2026-08-20T05:55:11.471596Z qemu_rdma_post_send_control CONTROL: sending QEMU FILE..
2026-08-20T05:55:11.471617Z qemu_rdma_poll_other other completion 2000 received left 0
2026-08-20T05:55:11.705561Z qemu_rdma_close
2026-08-20T05:55:11.705587Z qemu_rdma_close
2026-08-20T05:55:11.705626Z qemu-system-x86_64: rdma migration: send polling control error
2026-08-20T05:55:11.707001Z qemu-system-x86_64: warning: Early error. Sending error.
2026-08-20T05:55:11.707031Z qemu_rdma_post_send_control CONTROL: sending ERROR..
2026-08-20T05:55:11.707038Z qemu-system-x86_64: warning: rdma migration: send polling control error
2026-08-20T05:55:11.707301Z qemu_rdma_cleanup_disconnect
2026-08-20T05:55:11.710569Z qemu_rdma_cleanup_disconnect
Fixes: 55cc1b5937a8 ("migration: create a dedicated connection for rdma return path")
Signed-off-by: Yanfei Xu <yanfei.xu@bytedance.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Jack Wang <jinpu.wang@cloud.ionos.com>
---
migration/rdma.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/migration/rdma.c b/migration/rdma.c
index e17ace62b0..6e8436ccc1 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3263,6 +3263,12 @@ static int qemu_rdma_accept(RDMAContext *rdma)
}
}
+ ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_READY, &err);
+ if (ret < 0) {
+ error_report_err(err);
+ goto err_rdma_dest_wait;
+ }
+
/* Accept the second connection request for return path */
if ((migrate_postcopy() || migrate_return_path())
&& !rdma->is_return_path) {
@@ -3295,12 +3301,6 @@ static int qemu_rdma_accept(RDMAContext *rdma)
rdma_ack_cm_event(cm_event);
rdma->connected = true;
- ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_READY, &err);
- if (ret < 0) {
- error_report_err(err);
- goto err_rdma_dest_wait;
- }
-
qemu_rdma_dump_gid("dest_connect", rdma->cm_id);
return 0;
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] migration/rdma: Retry control sends on full queue
2026-08-21 13:35 [PATCH v2 0/3] migration/rdma: Misc RDMA migration fixes Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 1/3] migration/rdma: Fix write-side shutdown Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 2/3] migration/rdma: Post initial receive before accepting Yanfei Xu
@ 2026-08-21 13:35 ` Yanfei Xu
2026-08-21 14:10 ` Peter Xu
2 siblings, 1 reply; 7+ messages in thread
From: Yanfei Xu @ 2026-08-21 13:35 UTC (permalink / raw)
To: qemu-devel; +Cc: peterx, farosas, lizhijian, jinpu.wang, isyanfei.xu, Yanfei Xu
RAM writes and control messages share the send queue. If outstanding
writes fill it, RDMA writes drain a completion and retry, but control
sends fail the migration.
Move send posting and queue-full handling into a common helper. On
ENOMEM, drain one outstanding RDMA write and retry the failed request
once. If no write is outstanding, or the retry still fails, propagate
the error.
Signed-off-by: Yanfei Xu <yanfei.xu@bytedance.com>
---
migration/rdma.c | 78 +++++++++++++++++++++++++++---------------
migration/trace-events | 2 +-
2 files changed, 51 insertions(+), 29 deletions(-)
diff --git a/migration/rdma.c b/migration/rdma.c
index 6e8436ccc1..ee6da4f137 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -1530,6 +1530,52 @@ err_block_for_wrid:
return -1;
}
+/*
+ * Post a send work request, draining an outstanding RDMA write if the send
+ * queue is full.
+ */
+static int qemu_rdma_post_send(RDMAContext *rdma,
+ struct ibv_send_wr *send_wr,
+ Error **errp)
+{
+ struct ibv_send_wr *bad_wr;
+ uint64_t wr_id = send_wr->wr_id & RDMA_WRID_TYPE_MASK;
+ const char *wr_desc;
+ int ret;
+
+ switch (wr_id) {
+ case RDMA_WRID_RDMA_WRITE:
+ wr_desc = "RDMA write";
+ break;
+ case RDMA_WRID_SEND_CONTROL:
+ wr_desc = "control send";
+ break;
+ default:
+ wr_desc = "send work request";
+ break;
+ }
+
+ ret = ibv_post_send(rdma->qp, send_wr, &bad_wr);
+ if (ret == ENOMEM && rdma->nb_sent) {
+ trace_qemu_rdma_post_send_queue_full(send_wr->wr_id, rdma->nb_sent);
+ ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
+ if (ret < 0) {
+ error_setg(errp, "rdma migration: failed to make room for %s",
+ wr_desc);
+ return -1;
+ }
+ ret = ibv_post_send(rdma->qp, send_wr, &bad_wr);
+ }
+
+ if (ret > 0) {
+ error_setg_errno(errp, ret, "rdma migration: post %s failed",
+ wr_desc);
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* Post a SEND message work request for the control channel
* containing some data and block until the post completes.
@@ -1540,7 +1586,6 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
{
int ret;
RDMAWorkRequestData *wr = &rdma->wr_data[RDMA_WRID_CONTROL];
- struct ibv_send_wr *bad_wr;
struct ibv_sge sge = {
.addr = (uintptr_t)(wr->control),
.length = head->len + sizeof(RDMAControlHeader),
@@ -1572,11 +1617,8 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
memcpy(wr->control + sizeof(RDMAControlHeader), buf, head->len);
}
-
- ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr);
-
- if (ret > 0) {
- error_setg(errp, "Failed to use post IB SEND for control");
+ ret = qemu_rdma_post_send(rdma, &send_wr, errp);
+ if (ret < 0) {
return -1;
}
@@ -1836,7 +1878,6 @@ 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;
uint64_t chunk, chunks;
uint64_t chunk_size = migrate_rdma_chunk_size();
@@ -1850,7 +1891,6 @@ static int qemu_rdma_write_one(RDMAContext *rdma,
.repeat = 1,
};
-retry:
sge.addr = (uintptr_t)(block->local_host_addr +
(current_addr - block->offset));
sge.length = length;
@@ -2020,26 +2060,8 @@ retry:
trace_qemu_rdma_write_one_post(chunk, sge.addr, send_wr.wr.rdma.remote_addr,
sge.length);
- /*
- * ibv_post_send() does not return negative error numbers,
- * per the specification they are positive - no idea why.
- */
- ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr);
-
- if (ret == ENOMEM) {
- trace_qemu_rdma_write_one_queue_full();
- ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
- if (ret < 0) {
- error_setg(errp, "rdma migration: failed to make "
- "room in full send queue!");
- return -1;
- }
-
- goto retry;
-
- } else if (ret > 0) {
- error_setg_errno(errp, ret,
- "rdma migration: post rdma write failed");
+ ret = qemu_rdma_post_send(rdma, &send_wr, errp);
+ if (ret < 0) {
return -1;
}
diff --git a/migration/trace-events b/migration/trace-events
index af0e784535..bc0c167a1a 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -251,7 +251,7 @@ qemu_rdma_unregister_waiting_complete(uint64_t chunk) "Unregister for chunk: %"
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_post_send_queue_full(uint64_t wr_id, int sent) "send queue full, wr_id=%" PRIu64 ", outstanding writes=%d"
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
qemu_rdma_write_one_sendreg(uint64_t chunk, int len, int index, int64_t offset) "Sending registration request chunk %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
qemu_rdma_write_one_top(uint64_t chunks, uint64_t size) "Writing %" PRIu64 " chunks, (%" PRIu64 " MB)"
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 3/3] migration/rdma: Retry control sends on full queue
2026-08-21 13:35 ` [PATCH v2 3/3] migration/rdma: Retry control sends on full queue Yanfei Xu
@ 2026-08-21 14:10 ` Peter Xu
2026-08-21 14:25 ` Peter Xu
0 siblings, 1 reply; 7+ messages in thread
From: Peter Xu @ 2026-08-21 14:10 UTC (permalink / raw)
To: Yanfei Xu; +Cc: qemu-devel, farosas, lizhijian, jinpu.wang, isyanfei.xu
On Fri, Aug 21, 2026 at 09:35:59PM +0800, Yanfei Xu wrote:
> RAM writes and control messages share the send queue. If outstanding
> writes fill it, RDMA writes drain a completion and retry, but control
> sends fail the migration.
>
> Move send posting and queue-full handling into a common helper. On
> ENOMEM, drain one outstanding RDMA write and retry the failed request
> once. If no write is outstanding, or the retry still fails, propagate
> the error.
>
> Signed-off-by: Yanfei Xu <yanfei.xu@bytedance.com>
In general looks good, thanks,
Reviewed-by: Peter Xu <peterx@redhat.com>
I have nitpicks though, you can keep the R-b if you agree and would also
like to respin with that. See below.
> ---
> migration/rdma.c | 78 +++++++++++++++++++++++++++---------------
> migration/trace-events | 2 +-
> 2 files changed, 51 insertions(+), 29 deletions(-)
>
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 6e8436ccc1..ee6da4f137 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -1530,6 +1530,52 @@ err_block_for_wrid:
> return -1;
> }
>
> +/*
> + * Post a send work request, draining an outstanding RDMA write if the send
> + * queue is full.
> + */
> +static int qemu_rdma_post_send(RDMAContext *rdma,
> + struct ibv_send_wr *send_wr,
> + Error **errp)
Good to have errp and mask libibverb's weird positive returns.. but then
since we're at it anyway, better if we switch retval to bool too. It's
pretty much QEMU standard now to do this by default in new fn()s:
bool fn(..., Error **errp);
> +{
> + struct ibv_send_wr *bad_wr;
> + uint64_t wr_id = send_wr->wr_id & RDMA_WRID_TYPE_MASK;
> + const char *wr_desc;
> + int ret;
> +
> + switch (wr_id) {
> + case RDMA_WRID_RDMA_WRITE:
> + wr_desc = "RDMA write";
> + break;
> + case RDMA_WRID_SEND_CONTROL:
> + wr_desc = "control send";
> + break;
> + default:
> + wr_desc = "send work request";
> + break;
Do we have other possibility? I thought it should be either WRITE or SEND,
if so, we could g_assert_not_reached().
> + }
> +
> + ret = ibv_post_send(rdma->qp, send_wr, &bad_wr);
> + if (ret == ENOMEM && rdma->nb_sent) {
> + trace_qemu_rdma_post_send_queue_full(send_wr->wr_id, rdma->nb_sent);
> + ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
> + if (ret < 0) {
> + error_setg(errp, "rdma migration: failed to make room for %s",
> + wr_desc);
> + return -1;
> + }
> + ret = ibv_post_send(rdma->qp, send_wr, &bad_wr);
Yes, RDMA is almost single-threaded.. one retry would be enough, agreed.
Thanks,
> + }
> +
> + if (ret > 0) {
> + error_setg_errno(errp, ret, "rdma migration: post %s failed",
> + wr_desc);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> /*
> * Post a SEND message work request for the control channel
> * containing some data and block until the post completes.
> @@ -1540,7 +1586,6 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
> {
> int ret;
> RDMAWorkRequestData *wr = &rdma->wr_data[RDMA_WRID_CONTROL];
> - struct ibv_send_wr *bad_wr;
> struct ibv_sge sge = {
> .addr = (uintptr_t)(wr->control),
> .length = head->len + sizeof(RDMAControlHeader),
> @@ -1572,11 +1617,8 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
> memcpy(wr->control + sizeof(RDMAControlHeader), buf, head->len);
> }
>
> -
> - ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr);
> -
> - if (ret > 0) {
> - error_setg(errp, "Failed to use post IB SEND for control");
> + ret = qemu_rdma_post_send(rdma, &send_wr, errp);
> + if (ret < 0) {
> return -1;
> }
>
> @@ -1836,7 +1878,6 @@ 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;
> uint64_t chunk, chunks;
> uint64_t chunk_size = migrate_rdma_chunk_size();
> @@ -1850,7 +1891,6 @@ static int qemu_rdma_write_one(RDMAContext *rdma,
> .repeat = 1,
> };
>
> -retry:
> sge.addr = (uintptr_t)(block->local_host_addr +
> (current_addr - block->offset));
> sge.length = length;
> @@ -2020,26 +2060,8 @@ retry:
> trace_qemu_rdma_write_one_post(chunk, sge.addr, send_wr.wr.rdma.remote_addr,
> sge.length);
>
> - /*
> - * ibv_post_send() does not return negative error numbers,
> - * per the specification they are positive - no idea why.
> - */
> - ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr);
> -
> - if (ret == ENOMEM) {
> - trace_qemu_rdma_write_one_queue_full();
> - ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
> - if (ret < 0) {
> - error_setg(errp, "rdma migration: failed to make "
> - "room in full send queue!");
> - return -1;
> - }
> -
> - goto retry;
> -
> - } else if (ret > 0) {
> - error_setg_errno(errp, ret,
> - "rdma migration: post rdma write failed");
> + ret = qemu_rdma_post_send(rdma, &send_wr, errp);
> + if (ret < 0) {
> return -1;
> }
>
> diff --git a/migration/trace-events b/migration/trace-events
> index af0e784535..bc0c167a1a 100644
> --- a/migration/trace-events
> +++ b/migration/trace-events
> @@ -251,7 +251,7 @@ qemu_rdma_unregister_waiting_complete(uint64_t chunk) "Unregister for chunk: %"
> 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_post_send_queue_full(uint64_t wr_id, int sent) "send queue full, wr_id=%" PRIu64 ", outstanding writes=%d"
> 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
> qemu_rdma_write_one_sendreg(uint64_t chunk, int len, int index, int64_t offset) "Sending registration request chunk %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
> qemu_rdma_write_one_top(uint64_t chunks, uint64_t size) "Writing %" PRIu64 " chunks, (%" PRIu64 " MB)"
> --
> 2.20.1
>
--
Peter Xu
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 3/3] migration/rdma: Retry control sends on full queue
2026-08-21 14:10 ` Peter Xu
@ 2026-08-21 14:25 ` Peter Xu
2026-08-23 2:38 ` Yanfei Xu
0 siblings, 1 reply; 7+ messages in thread
From: Peter Xu @ 2026-08-21 14:25 UTC (permalink / raw)
To: Yanfei Xu; +Cc: qemu-devel, farosas, lizhijian, jinpu.wang, isyanfei.xu
On Fri, Aug 21, 2026 at 10:10:40AM -0400, Peter Xu wrote:
> > + switch (wr_id) {
> > + case RDMA_WRID_RDMA_WRITE:
> > + wr_desc = "RDMA write";
> > + break;
> > + case RDMA_WRID_SEND_CONTROL:
> > + wr_desc = "control send";
> > + break;
> > + default:
> > + wr_desc = "send work request";
> > + break;
>
> Do we have other possibility? I thought it should be either WRITE or SEND,
> if so, we could g_assert_not_reached().
Some side discussion..
Since we're talking about the wrids, IIUC the whole RDMA wrid space is a
bit messy. E.g. RDMA_WRID_SEND_CONTROL is used without having
RDMA_WRID_CONTROL (2000, rather than 2022) for SEND control messages.
IIUC the two-layered wrid name space is confusing, maybe we can rewrite the
wrid allocation to only use one namespace with very limited wrid
possibilities, selecting rdma->wr_data[] index based on the few
possibilities. My gut feeling is that's much easier to read.
In all cases, this will be a separate discussion, not relevant to this
series alone, but I want to see if I'm the only one got confused by these
two-layered RDMA_WRID_*.
Thanks,
--
Peter Xu
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 3/3] migration/rdma: Retry control sends on full queue
2026-08-21 14:25 ` Peter Xu
@ 2026-08-23 2:38 ` Yanfei Xu
0 siblings, 0 replies; 7+ messages in thread
From: Yanfei Xu @ 2026-08-23 2:38 UTC (permalink / raw)
To: Peter Xu, Yanfei Xu; +Cc: qemu-devel, farosas, lizhijian, jinpu.wang
On 2026/8/21 22:25, Peter Xu wrote:
> On Fri, Aug 21, 2026 at 10:10:40AM -0400, Peter Xu wrote:
>>> + switch (wr_id) {
>>> + case RDMA_WRID_RDMA_WRITE:
>>> + wr_desc = "RDMA write";
>>> + break;
>>> + case RDMA_WRID_SEND_CONTROL:
>>> + wr_desc = "control send";
>>> + break;
>>> + default:
>>> + wr_desc = "send work request";
>>> + break;
>> Do we have other possibility? I thought it should be either WRITE or SEND,
>> if so, we could g_assert_not_reached().
> Some side discussion..
>
> Since we're talking about the wrids, IIUC the whole RDMA wrid space is a
> bit messy. E.g. RDMA_WRID_SEND_CONTROL is used without having
> RDMA_WRID_CONTROL (2000, rather than 2022) for SEND control messages.
>
> IIUC the two-layered wrid name space is confusing, maybe we can rewrite the
> wrid allocation to only use one namespace with very limited wrid
> possibilities, selecting rdma->wr_data[] index based on the few
> possibilities. My gut feeling is that's much easier to read.
I agree it would be better with using one namespace.
>
> In all cases, this will be a separate discussion, not relevant to this
> series alone, but I want to see if I'm the only one got confused by these
> two-layered RDMA_WRID_*.
It's true that the two-layered RDMA_WRID_* are not that clear, and I have to
rely on their comments to understand them.
Regards,
Yanfei
>
> Thanks,
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-23 2:39 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-21 13:35 [PATCH v2 0/3] migration/rdma: Misc RDMA migration fixes Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 1/3] migration/rdma: Fix write-side shutdown Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 2/3] migration/rdma: Post initial receive before accepting Yanfei Xu
2026-08-21 13:35 ` [PATCH v2 3/3] migration/rdma: Retry control sends on full queue Yanfei Xu
2026-08-21 14:10 ` Peter Xu
2026-08-21 14:25 ` Peter Xu
2026-08-23 2:38 ` Yanfei Xu
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.