* [PATCH 00/10] migration/rdma: Fixes or drops
@ 2026-08-17 20:24 Peter Xu
2026-08-17 20:24 ` [PATCH 01/10] migration/rdma: Introduce RDMA_CONTROL_NUM Peter Xu
` (9 more replies)
0 siblings, 10 replies; 16+ messages in thread
From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw)
To: qemu-devel
Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang,
Juraj Marcin, Yanfei Xu
This series includes some RDMA changes, either to drop some dead code, or
to harden some checks for the incoming data stream, or both.
Please have a look, this should close all RDMA recent AI reports (none of
them are real security issues), thanks.
Peter Xu (10):
migration/rdma: Introduce RDMA_CONTROL_NUM
migration/rdma: Remove unregister code
migration/rdma: Stick with rdma_ prefix for all tracepoints
migration/rdma: Drop RDMALocalBlock.is_ram_block
migration/rdma: Drop RDMALocalBlock.unregister_bitmap
migration/rdma: Drop RDMARegister.key.chunk
migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST on buflen
migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST chunks
migration/rdma: Sanity check upper bound of register MR address
migration/rdma: Sanity check compress request ranges
migration/rdma.c | 344 +++++++++++++----------------------------
migration/trace-events | 83 +++++-----
2 files changed, 144 insertions(+), 283 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 01/10] migration/rdma: Introduce RDMA_CONTROL_NUM 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 02/10] migration/rdma: Remove unregister code Peter Xu ` (8 subsequent siblings) 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu Introduce this to say how many control messages we have. We did it because we're going to remove the last one (RDMA_CONTROL_UNREGISTER_FINISHED) soon. Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/migration/rdma.c b/migration/rdma.c index 438419d189..62a509b236 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -144,6 +144,7 @@ enum { RDMA_CONTROL_REGISTER_FINISHED, /* current iteration finished */ RDMA_CONTROL_UNREGISTER_REQUEST, /* dynamic UN-registration */ RDMA_CONTROL_UNREGISTER_FINISHED, /* unpinning finished */ + RDMA_CONTROL_NUM, }; @@ -235,7 +236,7 @@ static const char *control_desc(unsigned int rdma_control) [RDMA_CONTROL_UNREGISTER_FINISHED] = "UNREGISTER FINISHED", }; - if (rdma_control > RDMA_CONTROL_UNREGISTER_FINISHED) { + if (rdma_control >= RDMA_CONTROL_NUM) { return "??BAD CONTROL VALUE??"; } -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/10] migration/rdma: Remove unregister code 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu 2026-08-17 20:24 ` [PATCH 01/10] migration/rdma: Introduce RDMA_CONTROL_NUM Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-18 11:57 ` Yanfei Xu 2026-08-17 20:24 ` [PATCH 03/10] migration/rdma: Stick with rdma_ prefix for all tracepoints Peter Xu ` (7 subsequent siblings) 9 siblings, 1 reply; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu The unregister code was there since the first commit RDMA migration was merged, but it was never functioning. Remove the dead code. Since the two control messages are the last ones, we don't even need to worry about compatibility of legacy RDMA control commands, we can directly remove the messages too. As a side effect, this patch closes a report by removing the code completely. Reported-by: Tristan (@TristanInSec) Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4003 Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 133 ----------------------------------------- migration/trace-events | 7 --- 2 files changed, 140 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index 62a509b236..eae4afd6df 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -142,8 +142,6 @@ enum { RDMA_CONTROL_REGISTER_REQUEST, /* dynamic page registration */ RDMA_CONTROL_REGISTER_RESULT, /* key to use after registration */ RDMA_CONTROL_REGISTER_FINISHED, /* current iteration finished */ - RDMA_CONTROL_UNREGISTER_REQUEST, /* dynamic UN-registration */ - RDMA_CONTROL_UNREGISTER_FINISHED, /* unpinning finished */ RDMA_CONTROL_NUM, }; @@ -232,8 +230,6 @@ static const char *control_desc(unsigned int rdma_control) [RDMA_CONTROL_REGISTER_REQUEST] = "REGISTER REQUEST", [RDMA_CONTROL_REGISTER_RESULT] = "REGISTER RESULT", [RDMA_CONTROL_REGISTER_FINISHED] = "REGISTER FINISHED", - [RDMA_CONTROL_UNREGISTER_REQUEST] = "UNREGISTER REQUEST", - [RDMA_CONTROL_UNREGISTER_FINISHED] = "UNREGISTER FINISHED", }; if (rdma_control >= RDMA_CONTROL_NUM) { @@ -370,9 +366,6 @@ typedef struct RDMAContext { int total_registrations; int total_writes; - int unregister_current, unregister_next; - uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; - GHashTable *blockmap; /* the RDMAContext for return path */ @@ -1186,91 +1179,6 @@ static int qemu_rdma_reg_control(RDMAContext *rdma, int idx) return -1; } -/* - * Perform a non-optimized memory unregistration after every transfer - * for demonstration purposes, only if pin-all is not requested. - * - * Potential optimizations: - * 1. Start a new thread to run this function continuously - - for bit clearing - - and for receipt of unregister messages - * 2. Use an LRU. - * 3. Use workload hints. - */ -static int qemu_rdma_unregister_waiting(RDMAContext *rdma) -{ - Error *err = NULL; - - while (rdma->unregistrations[rdma->unregister_current]) { - int ret; - uint64_t wr_id = rdma->unregistrations[rdma->unregister_current]; - uint64_t chunk = - (wr_id & RDMA_WRID_CHUNK_MASK) >> RDMA_WRID_CHUNK_SHIFT; - uint64_t index = - (wr_id & RDMA_WRID_BLOCK_MASK) >> RDMA_WRID_BLOCK_SHIFT; - RDMALocalBlock *block = - &(rdma->local_ram_blocks.block[index]); - RDMARegister reg = { .current_index = index }; - RDMAControlHeader resp = { .type = RDMA_CONTROL_UNREGISTER_FINISHED, - }; - RDMAControlHeader head = { .len = sizeof(RDMARegister), - .type = RDMA_CONTROL_UNREGISTER_REQUEST, - .repeat = 1, - }; - - trace_qemu_rdma_unregister_waiting_proc(chunk, - rdma->unregister_current); - - rdma->unregistrations[rdma->unregister_current] = 0; - rdma->unregister_current++; - - if (rdma->unregister_current == RDMA_SIGNALED_SEND_MAX) { - rdma->unregister_current = 0; - } - - - /* - * Unregistration is speculative (because migration is single-threaded - * and we cannot break the protocol's inifinband message ordering). - * Thus, if the memory is currently being used for transmission, - * then abort the attempt to unregister and try again - * later the next time a completion is received for this memory. - */ - clear_bit(chunk, block->unregister_bitmap); - - if (test_bit(chunk, block->transit_bitmap)) { - trace_qemu_rdma_unregister_waiting_inflight(chunk); - continue; - } - - trace_qemu_rdma_unregister_waiting_send(chunk); - - ret = ibv_dereg_mr(block->pmr[chunk]); - block->pmr[chunk] = NULL; - block->remote_keys[chunk] = 0; - - if (ret != 0) { - error_report("unregistration chunk failed: %s", - strerror(ret)); - return -1; - } - rdma->total_registrations--; - - reg.key.chunk = chunk; - register_to_network(rdma, ®); - ret = qemu_rdma_exchange_send(rdma, &head, (uint8_t *) ®, - &resp, NULL, NULL, &err); - if (ret < 0) { - error_report_err(err); - return -1; - } - - trace_qemu_rdma_unregister_waiting_complete(chunk); - } - - return 0; -} - static uint64_t qemu_rdma_make_wrid(uint64_t wr_id, uint64_t index, uint64_t chunk) { @@ -2757,8 +2665,6 @@ static int qemu_rdma_drain_cq(RDMAContext *rdma) } } - qemu_rdma_unregister_waiting(rdma); - return 0; } @@ -3336,10 +3242,6 @@ int rdma_registration_handle(QEMUFile *f) .type = RDMA_CONTROL_REGISTER_RESULT, .repeat = 0, }; - RDMAControlHeader unreg_resp = { .len = 0, - .type = RDMA_CONTROL_UNREGISTER_FINISHED, - .repeat = 0, - }; RDMAControlHeader blocks = { .type = RDMA_CONTROL_RAM_BLOCKS_RESULT, .repeat = 1 }; QIOChannelRDMA *rioc; @@ -3552,41 +3454,6 @@ int rdma_registration_handle(QEMUFile *f) ret = qemu_rdma_post_send_control(rdma, (uint8_t *) results, ®_resp, &err); - if (ret < 0) { - error_report_err(err); - goto err; - } - break; - case RDMA_CONTROL_UNREGISTER_REQUEST: - trace_rdma_registration_handle_unregister(head.repeat); - unreg_resp.repeat = head.repeat; - registers = (RDMARegister *) rdma->wr_data[idx].control_curr; - - for (int count = 0; count < head.repeat; count++) { - reg = ®isters[count]; - network_to_register(reg); - - trace_rdma_registration_handle_unregister_loop(count, - reg->current_index, reg->key.chunk); - - block = &(rdma->local_ram_blocks.block[reg->current_index]); - - ret = ibv_dereg_mr(block->pmr[reg->key.chunk]); - block->pmr[reg->key.chunk] = NULL; - - if (ret != 0) { - error_report("rdma unregistration chunk failed: %s", - strerror(errno)); - goto err; - } - - rdma->total_registrations--; - - trace_rdma_registration_handle_unregister_success(reg->key.chunk); - } - - ret = qemu_rdma_post_send_control(rdma, NULL, &unreg_resp, &err); - if (ret < 0) { error_report_err(err); goto err; diff --git a/migration/trace-events b/migration/trace-events index af0e784535..d1fe8f1382 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -244,10 +244,6 @@ qemu_rdma_advise_mr(const char *name, uint32_t len, uint64_t addr, const char *r qemu_rdma_resolve_host_trying(const char *host, const char *ip) "Trying %s => %s" qemu_rdma_signal_unregister_append(uint64_t chunk, int pos) "Appending unregister chunk %" PRIu64 " at position %d" qemu_rdma_signal_unregister_already(uint64_t chunk) "Unregister chunk %" PRIu64 " already in queue" -qemu_rdma_unregister_waiting_inflight(uint64_t chunk) "Cannot unregister inflight chunk: %" PRIu64 -qemu_rdma_unregister_waiting_proc(uint64_t chunk, int pos) "Processing unregister for chunk: %" PRIu64 " at position %d" -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 @@ -266,9 +262,6 @@ rdma_registration_handle_ram_blocks_loop(const char *name, uint64_t offset, uint rdma_registration_handle_register(int requests) "%d requests" rdma_registration_handle_register_loop(int req, int index, uint64_t addr, uint64_t chunks) "Registration request (%d): index %d, current_addr %" PRIu64 " chunks: %" PRIu64 rdma_registration_handle_register_rkey(int rkey) "0x%x" -rdma_registration_handle_unregister(int requests) "%d requests" -rdma_registration_handle_unregister_loop(int count, int index, uint64_t chunk) "Unregistration request (%d): index %d, chunk %" PRIu64 -rdma_registration_handle_unregister_success(uint64_t chunk) "%" PRIu64 rdma_registration_handle_wait(void) "" rdma_registration_start(uint64_t flags) "%" PRIu64 rdma_registration_stop(uint64_t flags) "%" PRIu64 -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 02/10] migration/rdma: Remove unregister code 2026-08-17 20:24 ` [PATCH 02/10] migration/rdma: Remove unregister code Peter Xu @ 2026-08-18 11:57 ` Yanfei Xu 2026-08-18 13:01 ` Peter Xu 0 siblings, 1 reply; 16+ messages in thread From: Yanfei Xu @ 2026-08-18 11:57 UTC (permalink / raw) To: Peter Xu, qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, Jack Wang, Juraj Marcin, Yanfei Xu Hi Peter, No objection to removing the dead code — it clearly never worked I do have one question about the direction, though. The removed logic was the only in-tree attempt at MR unregistration for the non-pin-all path. Without it, registered MRs grow monotonically over a migration, and with large, widely-spread dirty memory over chunks the accumulated MR metadata (user + kernel) can cost more than pin-all and even perform worse — which rather defeats the purpose of not pinning everything. do we still intend to keep and improve the non-pin-all path going forward? If so, some form of dynamic MR unregistration will eventually be needed and it might be worth keeping this code,or at least leaving a TODO to mark the gap? Thanks, Yanfei On 2026/8/18 04:24, Peter Xu wrote: > The unregister code was there since the first commit RDMA migration was > merged, but it was never functioning. Remove the dead code. > > Since the two control messages are the last ones, we don't even need to > worry about compatibility of legacy RDMA control commands, we can directly > remove the messages too. > > As a side effect, this patch closes a report by removing the code > completely. > > Reported-by: Tristan (@TristanInSec) > Closes:https://gitlab.com/qemu-project/qemu/-/work_items/4003 > Signed-off-by: Peter Xu<peterx@redhat.com> ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 02/10] migration/rdma: Remove unregister code 2026-08-18 11:57 ` Yanfei Xu @ 2026-08-18 13:01 ` Peter Xu 2026-08-18 13:57 ` Yanfei Xu 0 siblings, 1 reply; 16+ messages in thread From: Peter Xu @ 2026-08-18 13:01 UTC (permalink / raw) To: Yanfei Xu Cc: qemu-devel, Li Zhijian, Samuel Zhang, Fabiano Rosas, Jack Wang, Juraj Marcin, Yanfei Xu On Tue, Aug 18, 2026 at 07:57:06PM +0800, Yanfei Xu wrote: > Hi Peter, Hi, Yanfei, > > No objection to removing the dead code — it clearly never worked > > I do have one question about the direction, though. The removed logic > was the only in-tree attempt at MR unregistration for the non-pin-all > path. Without it, registered MRs grow monotonically over a migration, > and with large, widely-spread dirty memory over chunks the accumulated > MR metadata (user + kernel) can cost more than pin-all and even perform > worse — which rather defeats the purpose of not pinning everything. > > do we still intend to keep and improve the non-pin-all path going > forward? If so, some form of dynamic MR unregistration will eventually > be needed and it might be worth keeping this code,or at least leaving > a TODO to mark the gap? Thanks for taking a look. This is a valid question to ask. Though it was there for 13 years without being "enhanced", it means the possibility we leverage it in the next couple of years is low. You also discussed the other side of things: I am not a frequent RDMA user, but my understanding is frequent MR reg operations already slow down migration quite a bit. It means dynamic management including unregisters will be even worse. AFAICT, it'll be a challenging task if we want to keep the performance in bar and add a hard throttle to pinned memory. Obviously, RDMA migration users care a bunch on performance. So I see no good reason to not drop it. Even if someone will work out that problem, it's still not much code to add, and it'll likely be easier we design it from scratch with the demand, and without worry of breaking anyone. When that happens (if it ever will..), someone should also send an update to MAINTAINER file on RDMA migration to change it out of Odd Fixes stage.. Thanks, -- Peter Xu ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 02/10] migration/rdma: Remove unregister code 2026-08-18 13:01 ` Peter Xu @ 2026-08-18 13:57 ` Yanfei Xu 2026-08-18 14:43 ` Peter Xu 0 siblings, 1 reply; 16+ messages in thread From: Yanfei Xu @ 2026-08-18 13:57 UTC (permalink / raw) To: Peter Xu Cc: qemu-devel, Li Zhijian, Samuel Zhang, Fabiano Rosas, Jack Wang, Juraj Marcin, Yanfei Xu On 2026/8/18 21:01, Peter Xu wrote: > On Tue, Aug 18, 2026 at 07:57:06PM +0800, Yanfei Xu wrote: >> Hi Peter, > Hi, Yanfei, > >> No objection to removing the dead code — it clearly never worked >> >> I do have one question about the direction, though. The removed logic >> was the only in-tree attempt at MR unregistration for the non-pin-all >> path. Without it, registered MRs grow monotonically over a migration, >> and with large, widely-spread dirty memory over chunks the accumulated >> MR metadata (user + kernel) can cost more than pin-all and even perform >> worse — which rather defeats the purpose of not pinning everything. >> >> do we still intend to keep and improve the non-pin-all path going >> forward? If so, some form of dynamic MR unregistration will eventually >> be needed and it might be worth keeping this code,or at least leaving >> a TODO to mark the gap? > Thanks for taking a look. This is a valid question to ask. > > Though it was there for 13 years without being "enhanced", it means the > possibility we leverage it in the next couple of years is low. > > You also discussed the other side of things: I am not a frequent RDMA user, > but my understanding is frequent MR reg operations already slow down > migration quite a bit. It means dynamic management including unregisters > will be even worse. AFAICT, it'll be a challenging task if we want to keep > the performance in bar and add a hard throttle to pinned memory. One advantage of non-pin-all is that it neither sends the all-zero chunk nor registers the corresponding MRs. For guests with a low dirty-page workload and a large number of zero pages, this lets it migrate faster than pin-all and pin less guest memory during the migration. > > Obviously, RDMA migration users care a bunch on performance. > > So I see no good reason to not drop it. Even if someone will work out that > problem, it's still not much code to add, and it'll likely be easier we > design it from scratch with the demand, and without worry of breaking > anyone. Got it, thanks for the explanation. Regards, Yanfei > > When that happens (if it ever will..), someone should also send an update > to MAINTAINER file on RDMA migration to change it out of Odd Fixes stage.. > > Thanks, > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 02/10] migration/rdma: Remove unregister code 2026-08-18 13:57 ` Yanfei Xu @ 2026-08-18 14:43 ` Peter Xu 2026-08-19 3:55 ` Yanfei Xu 0 siblings, 1 reply; 16+ messages in thread From: Peter Xu @ 2026-08-18 14:43 UTC (permalink / raw) To: Yanfei Xu Cc: qemu-devel, Li Zhijian, Samuel Zhang, Fabiano Rosas, Jack Wang, Juraj Marcin, Yanfei Xu On Tue, Aug 18, 2026 at 09:57:12PM +0800, Yanfei Xu wrote: > > On 2026/8/18 21:01, Peter Xu wrote: > > On Tue, Aug 18, 2026 at 07:57:06PM +0800, Yanfei Xu wrote: > > > Hi Peter, > > Hi, Yanfei, > > > > > No objection to removing the dead code — it clearly never worked > > > > > > I do have one question about the direction, though. The removed logic > > > was the only in-tree attempt at MR unregistration for the non-pin-all > > > path. Without it, registered MRs grow monotonically over a migration, > > > and with large, widely-spread dirty memory over chunks the accumulated > > > MR metadata (user + kernel) can cost more than pin-all and even perform > > > worse — which rather defeats the purpose of not pinning everything. > > > > > > do we still intend to keep and improve the non-pin-all path going > > > forward? If so, some form of dynamic MR unregistration will eventually > > > be needed and it might be worth keeping this code,or at least leaving > > > a TODO to mark the gap? > > Thanks for taking a look. This is a valid question to ask. > > > > Though it was there for 13 years without being "enhanced", it means the > > possibility we leverage it in the next couple of years is low. > > > > You also discussed the other side of things: I am not a frequent RDMA user, > > but my understanding is frequent MR reg operations already slow down > > migration quite a bit. It means dynamic management including unregisters > > will be even worse. AFAICT, it'll be a challenging task if we want to keep > > the performance in bar and add a hard throttle to pinned memory. > > One advantage of non-pin-all is that it neither sends the all-zero chunk > nor registers the corresponding MRs. For guests with a low dirty-page > workload and a large number of zero pages, this lets it migrate faster > than pin-all and pin less guest memory during the migration. I actually don't know why RDMA_CONTROL_COMPRESS is only used in !pin_all, do you know? I can only guess RDMA WRITEs were fast and need no round-robin chats, so it's faster than RDMA_CONTROL_COMPRESS, but you seem to say it's not true. Meanwhile, I would expect pin-all=off ultimately should meet the same perf over pin-all=on.. so I don't really know how needs pin-all=on... maybe it's useful when one is looking for minimum total migration time when VMs are required to be evicted from one host? Feel free to share if you have more data points; I'm almost speaking from reading the code, so it could be wrong. Thanks, -- Peter Xu ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 02/10] migration/rdma: Remove unregister code 2026-08-18 14:43 ` Peter Xu @ 2026-08-19 3:55 ` Yanfei Xu 0 siblings, 0 replies; 16+ messages in thread From: Yanfei Xu @ 2026-08-19 3:55 UTC (permalink / raw) To: Peter Xu Cc: qemu-devel, Li Zhijian, Samuel Zhang, Fabiano Rosas, Jack Wang, Juraj Marcin, Yanfei Xu On 2026/8/18 22:43, Peter Xu wrote: > I actually don't know why RDMA_CONTROL_COMPRESS is only used in !pin_all, > do you know? my understanding is that with RDMA_CONTROL_COMPRESS, the corresponding MR isn't registered, so the memset(0) in destination side can be guaranteed to complete before the next RDMA write to the same chunk. Or it needs an extra ack from destionation for the memset(0) complation. > > I can only guess RDMA WRITEs were fast and need no round-robin chats, so > it's faster than RDMA_CONTROL_COMPRESS, but you seem to say it's not true. if most of guest's pages are not being allocated yet or are zero page, RDMA_CONTROL_COMPRESS works more efficient. > > Meanwhile, I would expect pin-all=off ultimately should meet the same perf > over pin-all=on.. so I don't really know how needs pin-all=on... maybe > it's useful when one is looking for minimum total migration time when VMs > are required to be evicted from one host? > > Feel free to share if you have more data points; I'm almost speaking from > reading the code, so it could be wrong. Hah, I am new to RDMA live migration, glad to discuss ^_^ Yanfei ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 03/10] migration/rdma: Stick with rdma_ prefix for all tracepoints 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu 2026-08-17 20:24 ` [PATCH 01/10] migration/rdma: Introduce RDMA_CONTROL_NUM Peter Xu 2026-08-17 20:24 ` [PATCH 02/10] migration/rdma: Remove unregister code Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 04/10] migration/rdma: Drop RDMALocalBlock.is_ram_block Peter Xu ` (6 subsequent siblings) 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu There're a bunch of RDMA tracepoints that are prefixed with "rdma_*", most of the rest with "qemu_rdma_*". Align them up. The "qemu_" prefix isn't helping. Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 76 +++++++++++++++++++++--------------------- migration/trace-events | 76 +++++++++++++++++++++--------------------- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index eae4afd6df..ffae0a887f 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -631,7 +631,7 @@ static void qemu_rdma_init_ram_blocks(RDMAContext *rdma) memset(local, 0, sizeof *local); ret = foreach_not_ignored_block(qemu_rdma_init_one_block, rdma); assert(!ret); - trace_qemu_rdma_init_ram_blocks(local->nb_blocks); + trace_rdma_init_ram_blocks(local->nb_blocks); rdma->dest_blocks = g_new0(RDMADestBlock, rdma->local_ram_blocks.nb_blocks); local->init = true; @@ -734,11 +734,11 @@ static void qemu_rdma_dump_id(const char *who, struct ibv_context *verbs) struct ibv_port_attr port; if (ibv_query_port(verbs, 1, &port)) { - trace_qemu_rdma_dump_id_failed(who); + trace_rdma_dump_id_failed(who); return; } - trace_qemu_rdma_dump_id(who, + trace_rdma_dump_id(who, verbs->device->name, verbs->device->dev_name, verbs->device->dev_path, @@ -759,7 +759,7 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id) char dgid[33]; inet_ntop(AF_INET6, &id->route.addr.addr.ibaddr.sgid, sgid, sizeof sgid); inet_ntop(AF_INET6, &id->route.addr.addr.ibaddr.dgid, dgid, sizeof dgid); - trace_qemu_rdma_dump_gid(who, sgid, dgid); + trace_rdma_dump_gid(who, sgid, dgid); } /* @@ -809,7 +809,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) inet_ntop(e->ai_family, &((struct sockaddr_in *) e->ai_dst_addr)->sin_addr, ip, sizeof ip); - trace_qemu_rdma_resolve_host_trying(rdma->host, ip); + trace_rdma_resolve_host_trying(rdma->host, ip); ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_dst_addr, RDMA_RESOLVE_TIMEOUT_MS); @@ -998,7 +998,7 @@ static void qemu_rdma_advise_prefetch_mr(struct ibv_pd *pd, uint64_t addr, ret = ibv_advise_mr(pd, advice, IBV_ADVISE_MR_FLAG_FLUSH, &sg_list, 1); /* ignore the error */ - trace_qemu_rdma_advise_mr(name, len, addr, strerror(ret)); + trace_rdma_advise_mr(name, len, addr, strerror(ret)); #endif } @@ -1029,7 +1029,7 @@ static int qemu_rdma_reg_whole_ram_blocks(RDMAContext *rdma, Error **errp) ibv_reg_mr(rdma->pd, local->block[i].local_host_addr, local->block[i].length, access); - trace_qemu_rdma_register_odp_mr(local->block[i].block_name); + trace_rdma_register_odp_mr(local->block[i].block_name); if (local->block[i].mr) { qemu_rdma_advise_prefetch_mr(rdma->pd, @@ -1125,7 +1125,7 @@ static int qemu_rdma_register_and_get_keys(RDMAContext *rdma, int access = rkey ? IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE : 0; - trace_qemu_rdma_register_and_get_keys(len, chunk_start); + trace_rdma_register_and_get_keys(len, chunk_start); block->pmr[chunk] = ibv_reg_mr(rdma->pd, chunk_start, len, access); /* @@ -1139,7 +1139,7 @@ static int qemu_rdma_register_and_get_keys(RDMAContext *rdma, access |= IBV_ACCESS_ON_DEMAND; /* register ODP mr */ block->pmr[chunk] = ibv_reg_mr(rdma->pd, chunk_start, len, access); - trace_qemu_rdma_register_odp_mr(block->block_name); + trace_rdma_register_odp_mr(block->block_name); if (block->pmr[chunk]) { qemu_rdma_advise_prefetch_mr(rdma->pd, (uintptr_t)chunk_start, @@ -1221,7 +1221,7 @@ static int qemu_rdma_poll(RDMAContext *rdma, struct ibv_cq *cq, if (rdma->control_ready_expected && (wr_id >= RDMA_WRID_RECV_CONTROL)) { - trace_qemu_rdma_poll_recv(wr_id - RDMA_WRID_RECV_CONTROL, wr_id, + trace_rdma_poll_recv(wr_id - RDMA_WRID_RECV_CONTROL, wr_id, rdma->nb_sent); rdma->control_ready_expected = 0; } @@ -1233,7 +1233,7 @@ static int qemu_rdma_poll(RDMAContext *rdma, struct ibv_cq *cq, (wc.wr_id & RDMA_WRID_BLOCK_MASK) >> RDMA_WRID_BLOCK_SHIFT; RDMALocalBlock *block = &(rdma->local_ram_blocks.block[index]); - trace_qemu_rdma_poll_write(wr_id, rdma->nb_sent, + trace_rdma_poll_write(wr_id, rdma->nb_sent, index, chunk, block->local_host_addr, (void *)(uintptr_t)block->remote_host_addr); @@ -1243,7 +1243,7 @@ static int qemu_rdma_poll(RDMAContext *rdma, struct ibv_cq *cq, rdma->nb_sent--; } } else { - trace_qemu_rdma_poll_other(wr_id, rdma->nb_sent); + trace_rdma_poll_other(wr_id, rdma->nb_sent); } *wr_id_out = wc.wr_id; @@ -1378,7 +1378,7 @@ static int qemu_rdma_block_for_wrid(RDMAContext *rdma, break; } if (wr_id != wrid_requested) { - trace_qemu_rdma_block_for_wrid_miss(wrid_requested, wr_id); + trace_rdma_block_for_wrid_miss(wrid_requested, wr_id); } } @@ -1415,7 +1415,7 @@ static int qemu_rdma_block_for_wrid(RDMAContext *rdma, break; } if (wr_id != wrid_requested) { - trace_qemu_rdma_block_for_wrid_miss(wrid_requested, wr_id); + trace_rdma_block_for_wrid_miss(wrid_requested, wr_id); } } @@ -1463,7 +1463,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf, .num_sge = 1, }; - trace_qemu_rdma_post_send_control(control_desc(head->type)); + trace_rdma_post_send_control(control_desc(head->type)); /* * We don't actually need to do a memcpy() in here if we used @@ -1546,10 +1546,10 @@ static int qemu_rdma_exchange_get_response(RDMAContext *rdma, network_to_control((void *) rdma->wr_data[idx].control); memcpy(head, rdma->wr_data[idx].control, sizeof(RDMAControlHeader)); - trace_qemu_rdma_exchange_get_response_start(control_desc(expecting)); + trace_rdma_exchange_get_response_start(control_desc(expecting)); if (expecting == RDMA_CONTROL_NONE) { - trace_qemu_rdma_exchange_get_response_none(control_desc(head->type), + trace_rdma_exchange_get_response_none(control_desc(head->type), head->type); } else if (head->type != expecting || head->type == RDMA_CONTROL_ERROR) { error_setg(errp, "Was expecting a %s (%d) control message" @@ -1659,14 +1659,14 @@ static int qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head, */ if (resp) { if (callback) { - trace_qemu_rdma_exchange_send_issue_callback(); + trace_rdma_exchange_send_issue_callback(); ret = callback(rdma, errp); if (ret < 0) { return -1; } } - trace_qemu_rdma_exchange_send_waiting(control_desc(resp->type)); + trace_rdma_exchange_send_waiting(control_desc(resp->type)); ret = qemu_rdma_exchange_get_response(rdma, resp, resp->type, RDMA_WRID_DATA, errp); @@ -1679,7 +1679,7 @@ static int qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head, if (resp_idx) { *resp_idx = RDMA_WRID_DATA; } - trace_qemu_rdma_exchange_send_received(control_desc(resp->type)); + trace_rdma_exchange_send_received(control_desc(resp->type)); } rdma->control_ready_expected = 1; @@ -1782,7 +1782,7 @@ retry: } } - trace_qemu_rdma_write_one_top(chunks + 1, + trace_rdma_write_one_top(chunks + 1, (chunks + 1) * chunk_size / 1024 / 1024); chunk_end = ram_chunk_end(block, chunk + chunks); @@ -1790,7 +1790,7 @@ retry: while (test_bit(chunk, block->transit_bitmap)) { (void)count; - trace_qemu_rdma_write_one_block(count++, current_index, chunk, + trace_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); @@ -1823,7 +1823,7 @@ retry: head.len = sizeof(comp); head.type = RDMA_CONTROL_COMPRESS; - trace_qemu_rdma_write_one_zero(chunk, sge.length, + trace_rdma_write_one_zero(chunk, sge.length, current_index, current_addr); compress_to_network(rdma, &comp); @@ -1860,7 +1860,7 @@ retry: } reg.chunks = chunks; - trace_qemu_rdma_write_one_sendreg(chunk, sge.length, current_index, + trace_rdma_write_one_sendreg(chunk, sge.length, current_index, current_addr); register_to_network(rdma, ®); @@ -1883,7 +1883,7 @@ retry: network_to_result(reg_result); - trace_qemu_rdma_write_one_recvregres(block->remote_keys[chunk], + trace_rdma_write_one_recvregres(block->remote_keys[chunk], reg_result->rkey, chunk); block->remote_keys[chunk] = reg_result->rkey; @@ -1926,7 +1926,7 @@ retry: send_wr.wr.rdma.remote_addr = block->remote_host_addr + (current_addr - block->offset); - trace_qemu_rdma_write_one_post(chunk, sge.addr, send_wr.wr.rdma.remote_addr, + trace_rdma_write_one_post(chunk, sge.addr, send_wr.wr.rdma.remote_addr, sge.length); /* @@ -1936,7 +1936,7 @@ retry: ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr); if (ret == ENOMEM) { - trace_qemu_rdma_write_one_queue_full(); + trace_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 " @@ -1993,7 +1993,7 @@ static int qemu_rdma_write_flush(RDMAContext *rdma, Error **errp) if (ret == 0) { rdma->nb_sent++; - trace_qemu_rdma_write_flush(rdma->nb_sent); + trace_rdma_write_flush(rdma->nb_sent); } rdma->current_length = 0; @@ -2109,7 +2109,7 @@ static void qemu_rdma_cleanup(RDMAContext *rdma) } rdma_disconnect(rdma->cm_id); - trace_qemu_rdma_cleanup_disconnect(); + trace_rdma_cleanup_disconnect(); rdma->connected = false; } @@ -2292,7 +2292,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, bool return_path, * on the source first requested the capability. */ if (rdma->pin_all) { - trace_qemu_rdma_connect_pin_all_requested(); + trace_rdma_connect_pin_all_requested(); cap.flags |= RDMA_CAPABILITY_PIN_ALL; } @@ -2343,7 +2343,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, bool return_path, rdma->pin_all = false; } - trace_qemu_rdma_connect_pin_all_outcome(rdma->pin_all); + trace_rdma_connect_pin_all_outcome(rdma->pin_all); rdma_ack_cm_event(cm_event); @@ -2412,7 +2412,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) inet_ntop(e->ai_family, &((struct sockaddr_in *) e->ai_dst_addr)->sin_addr, ip, sizeof ip); - trace_qemu_rdma_dest_init_trying(rdma->host, ip); + trace_rdma_dest_init_trying(rdma->host, ip); ret = rdma_bind_addr(listen_id, e->ai_dst_addr); if (ret < 0) { continue; @@ -2547,7 +2547,7 @@ static size_t qemu_rdma_fill(RDMAContext *rdma, uint8_t *buf, size_t len = 0; if (rdma->wr_data[idx].control_len) { - trace_qemu_rdma_fill(rdma->wr_data[idx].control_len, size); + trace_rdma_fill(rdma->wr_data[idx].control_len, size); len = MIN(size, rdma->wr_data[idx].control_len); memcpy(buf, rdma->wr_data[idx].control_curr, len); @@ -2859,7 +2859,7 @@ static int qio_channel_rdma_close(QIOChannel *ioc, RDMAContext *rdmain, *rdmaout; struct rdma_close_rcu *rcu = g_new(struct rdma_close_rcu, 1); - trace_qemu_rdma_close(); + trace_rdma_close(); rdmain = rioc->rdmain; if (rdmain) { @@ -3132,11 +3132,11 @@ static int qemu_rdma_accept(RDMAContext *rdma) rdma_ack_cm_event(cm_event); - trace_qemu_rdma_accept_pin_state(rdma->pin_all); + trace_rdma_accept_pin_state(rdma->pin_all); caps_to_network(&cap); - trace_qemu_rdma_accept_pin_verbsc(verbs); + trace_rdma_accept_pin_verbsc(verbs); if (!rdma->verbs) { rdma->verbs = verbs; @@ -3727,13 +3727,13 @@ static void rdma_accept_incoming_migration(void *opaque) RDMAContext *rdma = opaque; QIOChannel *ioc; - trace_qemu_rdma_accept_incoming_migration(); + trace_rdma_accept_incoming_migration(); if (qemu_rdma_accept(rdma) < 0) { error_report("RDMA ERROR: Migration initialization failed"); return; } - trace_qemu_rdma_accept_incoming_migration_accepted(); + trace_rdma_accept_incoming_migration_accepted(); if (rdma->is_return_path) { return; diff --git a/migration/trace-events b/migration/trace-events index d1fe8f1382..d0ad736c8c 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -214,44 +214,44 @@ migrate_global_state_post_load(const char *state) "loaded state: %s" migrate_global_state_pre_save(const char *state) "saved state: %s" # rdma.c -qemu_rdma_accept_incoming_migration(void) "" -qemu_rdma_accept_incoming_migration_accepted(void) "" -qemu_rdma_accept_pin_state(bool pin) "%d" -qemu_rdma_accept_pin_verbsc(void *verbs) "Verbs context after listen: %p" -qemu_rdma_block_for_wrid_miss(uint64_t wcomp, uint64_t req) "A Wanted wrid %" PRIu64 " but got %" PRIu64 -qemu_rdma_cleanup_disconnect(void) "" -qemu_rdma_close(void) "" -qemu_rdma_connect_pin_all_requested(void) "" -qemu_rdma_connect_pin_all_outcome(bool pin) "%d" -qemu_rdma_dest_init_trying(const char *host, const char *ip) "%s => %s" -qemu_rdma_dump_id_failed(const char *who) "%s RDMA Device opened, but can't query port information" -qemu_rdma_dump_id(const char *who, const char *name, const char *dev_name, const char *dev_path, const char *ibdev_path, int transport, const char *transport_name) "%s RDMA Device opened: kernel name %s uverbs device name %s, infiniband_verbs class device path %s, infiniband class device path %s, transport: (%d) %s" -qemu_rdma_dump_gid(const char *who, const char *src, const char *dst) "%s Source GID: %s, Dest GID: %s" -qemu_rdma_exchange_get_response_start(const char *desc) "CONTROL: %s receiving..." -qemu_rdma_exchange_get_response_none(const char *desc, int type) "Surprise: got %s (%d)" -qemu_rdma_exchange_send_issue_callback(void) "" -qemu_rdma_exchange_send_waiting(const char *desc) "Waiting for response %s" -qemu_rdma_exchange_send_received(const char *desc) "Response %s received." -qemu_rdma_fill(size_t control_len, size_t size) "RDMA %zd of %zd bytes already in buffer" -qemu_rdma_init_ram_blocks(int blocks) "Allocated %d local ram block structures" -qemu_rdma_poll_recv(uint64_t comp, int64_t id, int sent) "completion %" PRIu64 " received (%" PRId64 ") left %d" -qemu_rdma_poll_write(uint64_t comp, int left, uint64_t block, uint64_t chunk, void *local, void *remote) "completions %" PRIu64 " left %d, block %" PRIu64 ", chunk: %" PRIu64 " %p %p" -qemu_rdma_poll_other(uint64_t comp, int left) "other completion %" PRIu64 " received left %d" -qemu_rdma_post_send_control(const char *desc) "CONTROL: sending %s.." -qemu_rdma_register_and_get_keys(uint64_t len, void *start) "Registering %" PRIu64 " bytes @ %p" -qemu_rdma_register_odp_mr(const char *name) "Try to register On-Demand Paging memory region: %s" -qemu_rdma_advise_mr(const char *name, uint32_t len, uint64_t addr, const char *res) "Try to advise block %s prefetch at %" PRIu32 "@0x%" PRIx64 ": %s" -qemu_rdma_resolve_host_trying(const char *host, const char *ip) "Trying %s => %s" -qemu_rdma_signal_unregister_append(uint64_t chunk, int pos) "Appending unregister chunk %" PRIu64 " at position %d" -qemu_rdma_signal_unregister_already(uint64_t chunk) "Unregister chunk %" PRIu64 " already in queue" -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 -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)" -qemu_rdma_write_one_zero(uint64_t chunk, int len, int index, int64_t offset) "Entire chunk is zero, sending compress: %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64 +rdma_accept_incoming_migration(void) "" +rdma_accept_incoming_migration_accepted(void) "" +rdma_accept_pin_state(bool pin) "%d" +rdma_accept_pin_verbsc(void *verbs) "Verbs context after listen: %p" +rdma_block_for_wrid_miss(uint64_t wcomp, uint64_t req) "A Wanted wrid %" PRIu64 " but got %" PRIu64 +rdma_cleanup_disconnect(void) "" +rdma_close(void) "" +rdma_connect_pin_all_requested(void) "" +rdma_connect_pin_all_outcome(bool pin) "%d" +rdma_dest_init_trying(const char *host, const char *ip) "%s => %s" +rdma_dump_id_failed(const char *who) "%s RDMA Device opened, but can't query port information" +rdma_dump_id(const char *who, const char *name, const char *dev_name, const char *dev_path, const char *ibdev_path, int transport, const char *transport_name) "%s RDMA Device opened: kernel name %s uverbs device name %s, infiniband_verbs class device path %s, infiniband class device path %s, transport: (%d) %s" +rdma_dump_gid(const char *who, const char *src, const char *dst) "%s Source GID: %s, Dest GID: %s" +rdma_exchange_get_response_start(const char *desc) "CONTROL: %s receiving..." +rdma_exchange_get_response_none(const char *desc, int type) "Surprise: got %s (%d)" +rdma_exchange_send_issue_callback(void) "" +rdma_exchange_send_waiting(const char *desc) "Waiting for response %s" +rdma_exchange_send_received(const char *desc) "Response %s received." +rdma_fill(size_t control_len, size_t size) "RDMA %zd of %zd bytes already in buffer" +rdma_init_ram_blocks(int blocks) "Allocated %d local ram block structures" +rdma_poll_recv(uint64_t comp, int64_t id, int sent) "completion %" PRIu64 " received (%" PRId64 ") left %d" +rdma_poll_write(uint64_t comp, int left, uint64_t block, uint64_t chunk, void *local, void *remote) "completions %" PRIu64 " left %d, block %" PRIu64 ", chunk: %" PRIu64 " %p %p" +rdma_poll_other(uint64_t comp, int left) "other completion %" PRIu64 " received left %d" +rdma_post_send_control(const char *desc) "CONTROL: sending %s.." +rdma_register_and_get_keys(uint64_t len, void *start) "Registering %" PRIu64 " bytes @ %p" +rdma_register_odp_mr(const char *name) "Try to register On-Demand Paging memory region: %s" +rdma_advise_mr(const char *name, uint32_t len, uint64_t addr, const char *res) "Try to advise block %s prefetch at %" PRIu32 "@0x%" PRIx64 ": %s" +rdma_resolve_host_trying(const char *host, const char *ip) "Trying %s => %s" +rdma_signal_unregister_append(uint64_t chunk, int pos) "Appending unregister chunk %" PRIu64 " at position %d" +rdma_signal_unregister_already(uint64_t chunk) "Unregister chunk %" PRIu64 " already in queue" +rdma_write_flush(int sent) "sent total: %d" +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" +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 +rdma_write_one_queue_full(void) "" +rdma_write_one_recvregres(int mykey, int theirkey, uint64_t chunk) "Received registration result: my key: 0x%x their key 0x%x, chunk %" PRIu64 +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 +rdma_write_one_top(uint64_t chunks, uint64_t size) "Writing %" PRIu64 " chunks, (%" PRIu64 " MB)" +rdma_write_one_zero(uint64_t chunk, int len, int index, int64_t offset) "Entire chunk is zero, sending compress: %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64 rdma_add_block(const char *block_name, int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Added Block: '%s':%d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d" rdma_block_notification_handle(const char *name, int index) "%s at %d" rdma_delete_block(void *block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Deleted Block: %p, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d" -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/10] migration/rdma: Drop RDMALocalBlock.is_ram_block 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu ` (2 preceding siblings ...) 2026-08-17 20:24 ` [PATCH 03/10] migration/rdma: Stick with rdma_ prefix for all tracepoints Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 05/10] migration/rdma: Drop RDMALocalBlock.unregister_bitmap Peter Xu ` (5 subsequent siblings) 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu This is guaranteed to be true. There seems to have support for some dynamically allocated buffers but it was never really supported. Remove dead code. As a side effect, this patch closes a report by removing the buggy code completely. Reported-by: Tristan (@TristanInSec) Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4006 Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 73 ++++++++++++++---------------------------------- 1 file changed, 21 insertions(+), 52 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index ffae0a887f..354935433c 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -196,7 +196,6 @@ typedef struct RDMALocalBlock { uint32_t remote_rkey; /* rkeys for non-chunk-level registration */ int index; /* which block are we */ unsigned int src_index; /* (Only used on dest) */ - bool is_ram_block; int nb_chunks; unsigned long *transit_bitmap; unsigned long *unregister_bitmap; @@ -441,14 +440,12 @@ static void register_to_network(RDMAContext *rdma, RDMARegister *reg) RDMALocalBlock *local_block; local_block = &rdma->local_ram_blocks.block[reg->current_index]; - if (local_block->is_ram_block) { - /* - * current_addr as passed in is an address in the local ram_addr_t - * space, we need to translate this for the destination - */ - reg->key.current_addr -= local_block->offset; - reg->key.current_addr += rdma->dest_blocks[reg->current_index].offset; - } + /* + * current_addr as passed in is an address in the local ram_addr_t + * space, we need to translate this for the destination + */ + reg->key.current_addr -= local_block->offset; + reg->key.current_addr += rdma->dest_blocks[reg->current_index].offset; reg->key.current_addr = htonll(reg->key.current_addr); reg->current_index = htonl(reg->current_index); reg->chunks = htonll(reg->chunks); @@ -585,8 +582,6 @@ static void rdma_add_block(RDMAContext *rdma, const char *block_name, bitmap_clear(block->unregister_bitmap, 0, block->nb_chunks); block->remote_keys = g_new0(uint32_t, block->nb_chunks); - block->is_ram_block = local->init ? false : true; - if (rdma->blockmap) { g_hash_table_insert(rdma->blockmap, (void *)(uintptr_t)block_offset, block); } @@ -1767,19 +1762,10 @@ retry: chunk = ram_chunk_index(block->local_host_addr, (uint8_t *)(uintptr_t)sge.addr); chunk_start = ram_chunk_start(block, chunk); + chunks = length / chunk_size; - if (block->is_ram_block) { - chunks = length / chunk_size; - - if (chunks && ((length % chunk_size) == 0)) { - chunks--; - } - } else { - chunks = block->length / chunk_size; - - if (chunks && ((block->length % chunk_size) == 0)) { - chunks--; - } + if (chunks && ((length % chunk_size) == 0)) { + chunks--; } trace_rdma_write_one_top(chunks + 1, @@ -1804,7 +1790,7 @@ retry: } } - if (!rdma->pin_all || !block->is_ram_block) { + if (!rdma->pin_all) { if (!block->remote_keys[chunk]) { /* * This chunk has not yet been registered, so first check to see @@ -1853,11 +1839,7 @@ retry: * Otherwise, tell other side to register. */ reg.current_index = current_index; - if (block->is_ram_block) { - reg.key.current_addr = current_addr; - } else { - reg.key.chunk = chunk; - } + reg.key.current_addr = current_addr; reg.chunks = chunks; trace_rdma_write_one_sendreg(chunk, sge.length, current_index, @@ -3408,30 +3390,17 @@ int rdma_registration_handle(QEMUFile *f) goto err; } block = &(rdma->local_ram_blocks.block[reg->current_index]); - if (block->is_ram_block) { - if (block->offset > reg->key.current_addr) { - error_report("rdma: bad register address for block %s" - " offset: %" PRIx64 " current_addr: %" PRIx64, - block->block_name, block->offset, - reg->key.current_addr); - goto err; - } - host_addr = (block->local_host_addr + - (reg->key.current_addr - block->offset)); - chunk = ram_chunk_index(block->local_host_addr, - (uint8_t *) host_addr); - } else { - chunk = reg->key.chunk; - host_addr = block->local_host_addr + - (reg->key.chunk * migrate_rdma_chunk_size()); - /* Check for particularly bad chunk value */ - if (host_addr < (void *)block->local_host_addr) { - error_report("rdma: bad chunk for block %s" - " chunk: %" PRIx64, - block->block_name, reg->key.chunk); - goto err; - } + if (block->offset > reg->key.current_addr) { + error_report("rdma: bad register address for block %s" + " offset: %" PRIx64 " current_addr: %" PRIx64, + block->block_name, block->offset, + reg->key.current_addr); + goto err; } + host_addr = (block->local_host_addr + + (reg->key.current_addr - block->offset)); + chunk = ram_chunk_index(block->local_host_addr, + (uint8_t *) host_addr); chunk_start = ram_chunk_start(block, chunk); chunk_end = ram_chunk_end(block, chunk + reg->chunks); /* avoid "-Waddress-of-packed-member" warning */ -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/10] migration/rdma: Drop RDMALocalBlock.unregister_bitmap 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu ` (3 preceding siblings ...) 2026-08-17 20:24 ` [PATCH 04/10] migration/rdma: Drop RDMALocalBlock.is_ram_block Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 06/10] migration/rdma: Drop RDMARegister.key.chunk Peter Xu ` (4 subsequent siblings) 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu Not used anymore. Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index 354935433c..c06395a51a 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -198,7 +198,6 @@ typedef struct RDMALocalBlock { unsigned int src_index; /* (Only used on dest) */ int nb_chunks; unsigned long *transit_bitmap; - unsigned long *unregister_bitmap; } RDMALocalBlock; /* @@ -578,8 +577,6 @@ static void rdma_add_block(RDMAContext *rdma, const char *block_name, block->nb_chunks = ram_chunk_index(host_addr, host_addr + length) + 1UL; block->transit_bitmap = bitmap_new(block->nb_chunks); bitmap_clear(block->transit_bitmap, 0, block->nb_chunks); - block->unregister_bitmap = bitmap_new(block->nb_chunks); - bitmap_clear(block->unregister_bitmap, 0, block->nb_chunks); block->remote_keys = g_new0(uint32_t, block->nb_chunks); if (rdma->blockmap) { @@ -665,9 +662,6 @@ static void rdma_delete_block(RDMAContext *rdma, RDMALocalBlock *block) g_free(block->transit_bitmap); block->transit_bitmap = NULL; - g_free(block->unregister_bitmap); - block->unregister_bitmap = NULL; - g_free(block->remote_keys); block->remote_keys = NULL; -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/10] migration/rdma: Drop RDMARegister.key.chunk 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu ` (4 preceding siblings ...) 2026-08-17 20:24 ` [PATCH 05/10] migration/rdma: Drop RDMALocalBlock.unregister_bitmap Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 07/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST on buflen Peter Xu ` (3 subsequent siblings) 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu Not used anymore. Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index c06395a51a..f64bcee418 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -415,10 +415,7 @@ static void network_to_control(RDMAControlHeader *control) * the actual RDMA operation. */ typedef struct QEMU_PACKED { - union QEMU_PACKED { - uint64_t current_addr; /* offset into the ram_addr_t space */ - uint64_t chunk; /* chunk to lookup if unregistering */ - } key; + uint64_t current_addr; /* offset into the ram_addr_t space */ uint32_t current_index; /* which ramblock the chunk belongs to */ uint32_t padding; uint64_t chunks; /* how many sequential chunks to register */ @@ -443,16 +440,16 @@ static void register_to_network(RDMAContext *rdma, RDMARegister *reg) * current_addr as passed in is an address in the local ram_addr_t * space, we need to translate this for the destination */ - reg->key.current_addr -= local_block->offset; - reg->key.current_addr += rdma->dest_blocks[reg->current_index].offset; - reg->key.current_addr = htonll(reg->key.current_addr); + reg->current_addr -= local_block->offset; + reg->current_addr += rdma->dest_blocks[reg->current_index].offset; + reg->current_addr = htonll(reg->current_addr); reg->current_index = htonl(reg->current_index); reg->chunks = htonll(reg->chunks); } static void network_to_register(RDMARegister *reg) { - reg->key.current_addr = ntohll(reg->key.current_addr); + reg->current_addr = ntohll(reg->current_addr); reg->current_index = ntohl(reg->current_index); reg->chunks = ntohll(reg->chunks); } @@ -1833,7 +1830,7 @@ retry: * Otherwise, tell other side to register. */ reg.current_index = current_index; - reg.key.current_addr = current_addr; + reg.current_addr = current_addr; reg.chunks = chunks; trace_rdma_write_one_sendreg(chunk, sge.length, current_index, @@ -3375,7 +3372,7 @@ int rdma_registration_handle(QEMUFile *f) reg_result = &results[count]; trace_rdma_registration_handle_register_loop(count, - reg->current_index, reg->key.current_addr, reg->chunks); + reg->current_index, reg->current_addr, reg->chunks); if (reg->current_index >= rdma->local_ram_blocks.nb_blocks) { error_report("rdma: 'register' bad block index %u (vs %d)", @@ -3384,15 +3381,15 @@ int rdma_registration_handle(QEMUFile *f) goto err; } block = &(rdma->local_ram_blocks.block[reg->current_index]); - if (block->offset > reg->key.current_addr) { + if (block->offset > reg->current_addr) { error_report("rdma: bad register address for block %s" " offset: %" PRIx64 " current_addr: %" PRIx64, block->block_name, block->offset, - reg->key.current_addr); + reg->current_addr); goto err; } host_addr = (block->local_host_addr + - (reg->key.current_addr - block->offset)); + (reg->current_addr - block->offset)); chunk = ram_chunk_index(block->local_host_addr, (uint8_t *) host_addr); chunk_start = ram_chunk_start(block, chunk); -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST on buflen 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu ` (5 preceding siblings ...) 2026-08-17 20:24 ` [PATCH 06/10] migration/rdma: Drop RDMARegister.key.chunk Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 08/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST chunks Peter Xu ` (2 subsequent siblings) 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu RDMA header supports head.repeat on RDMA_CONTROL_REGISTER_REQUEST, which can include >1 memory registrations. The current code did check over head.repeat to guard against RDMA_CONTROL_MAX_COMMANDS_PER_MESSAGE, however it didn't further check the buffer size (head.len) to make sure the received data is large enough to include the repeated entries. Check it. This is almost only to harden this piece of code, in reality on source side QEMU never uses repeat>1.. However since it's a protocol, still keep it. Check the buffer size instead. In case it's not obvious to new RDMA readers: head.len should be the size RDMA has last received, as qemu_rdma_exchange_get_response() checked on it against byte_len (which was further fetched from ibv_wc.byte_len in qemu_rdma_poll()). Reported-by: Tristan (@TristanInSec) Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4028 Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/migration/rdma.c b/migration/rdma.c index f64bcee418..5ce8b06818 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3362,6 +3362,14 @@ int rdma_registration_handle(QEMUFile *f) reg_resp.repeat = head.repeat; registers = (RDMARegister *) rdma->wr_data[idx].control_curr; + /* Making sure the register buffers to read are valid */ + if (head.len != head.repeat * sizeof(RDMARegister)) { + error_report("%s: Invalid RDMA_CONTROL_REGISTER_REQUEST " + "(head.repeat=%"PRIu32", head.len=%"PRIu32")", + __func__, head.repeat, head.len); + goto err; + } + for (int count = 0; count < head.repeat; count++) { uint64_t chunk; uint8_t *chunk_start, *chunk_end; -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST chunks 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu ` (6 preceding siblings ...) 2026-08-17 20:24 ` [PATCH 07/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST on buflen Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 09/10] migration/rdma: Sanity check upper bound of register MR address Peter Xu 2026-08-17 20:24 ` [PATCH 10/10] migration/rdma: Sanity check compress request ranges Peter Xu 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu The value received on wire for head.chunks when registering new RDMA regions is not correctly checked. Logically the value can still make ram_chunk_start() (of ram_chunk_end()) to overflow, having a result pointer very small, smaller than RDMALocalBlock.local_host_addr. Add the sanity check. Reported-by: Tristan (@TristanInSec) Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4011 Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/migration/rdma.c b/migration/rdma.c index 5ce8b06818..bbbc40ea3b 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3401,6 +3401,13 @@ int rdma_registration_handle(QEMUFile *f) chunk = ram_chunk_index(block->local_host_addr, (uint8_t *) host_addr); chunk_start = ram_chunk_start(block, chunk); + if (chunk + reg->chunks > block->nb_chunks) { + error_report("%s: head.chunks contains illegal value" + " (chunk=%"PRIu64", chunks=%"PRIu64", " + "nb_chunks=%d)", __func__, chunk, + reg->chunks, block->nb_chunks); + goto err; + } chunk_end = ram_chunk_end(block, chunk + reg->chunks); /* avoid "-Waddress-of-packed-member" warning */ uint32_t tmp_rkey = 0; -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/10] migration/rdma: Sanity check upper bound of register MR address 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu ` (7 preceding siblings ...) 2026-08-17 20:24 ` [PATCH 08/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST chunks Peter Xu @ 2026-08-17 20:24 ` Peter Xu 2026-08-17 20:24 ` [PATCH 10/10] migration/rdma: Sanity check compress request ranges Peter Xu 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu Before registration of RDMA ranges, QEMU destination checks for validity of current_addr no less than the target ramblock's start address. But it didn't check for the upper bound to make sure the address is within the size of the ramblock. Add it. Reported-by: Tristan (@TristanInSec) Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4007 Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/migration/rdma.c b/migration/rdma.c index bbbc40ea3b..13dd60c11b 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3389,7 +3389,8 @@ int rdma_registration_handle(QEMUFile *f) goto err; } block = &(rdma->local_ram_blocks.block[reg->current_index]); - if (block->offset > reg->current_addr) { + if (block->offset > reg->current_addr || + block->offset + block->length <= reg->current_addr) { error_report("rdma: bad register address for block %s" " offset: %" PRIx64 " current_addr: %" PRIx64, block->block_name, block->offset, -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/10] migration/rdma: Sanity check compress request ranges 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu ` (8 preceding siblings ...) 2026-08-17 20:24 ` [PATCH 09/10] migration/rdma: Sanity check upper bound of register MR address Peter Xu @ 2026-08-17 20:24 ` Peter Xu 9 siblings, 0 replies; 16+ messages in thread From: Peter Xu @ 2026-08-17 20:24 UTC (permalink / raw) To: qemu-devel Cc: Li Zhijian, Samuel Zhang, Fabiano Rosas, peterx, Jack Wang, Juraj Marcin, Yanfei Xu The offset/length ranges are not sanity checked in RDMA requests, add the checks. Reported-by: Tristan (@TristanInSec) Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4005 Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/rdma.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/migration/rdma.c b/migration/rdma.c index 13dd60c11b..699aaa9903 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3200,6 +3200,28 @@ static int dest_ram_sort_func(const void *a, const void *b) return (a_index < b_index) ? -1 : (a_index != b_index); } +static bool rdma_compress_range_check(RDMALocalBlock *block, + RDMACompress *comp) +{ + uint64_t block_end = block->offset + block->length; + uint64_t comp_end; + + if (uadd64_overflow(comp->offset, comp->length, &comp_end)) { + goto fail; + } + + if (comp->offset < block->offset || comp_end > block_end) { + goto fail; + } + + return true; +fail: + error_report("%s: compress request range outside range" + " (block=%s, offset=%"PRIu64", length=%"PRIu64")", + __func__, block->block_name, comp->offset, comp->length); + return false; +} + /* * During each iteration of the migration, we listen for instructions * by the source VM to perform dynamic page registrations before they @@ -3279,7 +3301,9 @@ int rdma_registration_handle(QEMUFile *f) goto err; } block = &(rdma->local_ram_blocks.block[comp->block_idx]); - + if (!rdma_compress_range_check(block, comp)) { + goto err; + } host_addr = block->local_host_addr + (comp->offset - block->offset); if (comp->value) { -- 2.54.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-08-19 3:56 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-17 20:24 [PATCH 00/10] migration/rdma: Fixes or drops Peter Xu 2026-08-17 20:24 ` [PATCH 01/10] migration/rdma: Introduce RDMA_CONTROL_NUM Peter Xu 2026-08-17 20:24 ` [PATCH 02/10] migration/rdma: Remove unregister code Peter Xu 2026-08-18 11:57 ` Yanfei Xu 2026-08-18 13:01 ` Peter Xu 2026-08-18 13:57 ` Yanfei Xu 2026-08-18 14:43 ` Peter Xu 2026-08-19 3:55 ` Yanfei Xu 2026-08-17 20:24 ` [PATCH 03/10] migration/rdma: Stick with rdma_ prefix for all tracepoints Peter Xu 2026-08-17 20:24 ` [PATCH 04/10] migration/rdma: Drop RDMALocalBlock.is_ram_block Peter Xu 2026-08-17 20:24 ` [PATCH 05/10] migration/rdma: Drop RDMALocalBlock.unregister_bitmap Peter Xu 2026-08-17 20:24 ` [PATCH 06/10] migration/rdma: Drop RDMARegister.key.chunk Peter Xu 2026-08-17 20:24 ` [PATCH 07/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST on buflen Peter Xu 2026-08-17 20:24 ` [PATCH 08/10] migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST chunks Peter Xu 2026-08-17 20:24 ` [PATCH 09/10] migration/rdma: Sanity check upper bound of register MR address Peter Xu 2026-08-17 20:24 ` [PATCH 10/10] migration/rdma: Sanity check compress request ranges Peter 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.