migration/rdma: Remove unregister code
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 Reviewed-by: Jinpu Wang <jinpu.wang@cloud.ionos.com> Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Fabiano Rosas <farosas@suse.de>
Peter Xu committed
Aug 20, 2026 at 16:03 UTC
16f72079b57bd9e250df3604fa134211a205679c
2 files changed
-142
migration/rdma.c
-133
@@ -142,8 +142,6 @@ enum {
142
RDMA_CONTROL_REGISTER_REQUEST, /* dynamic page registration */
143
RDMA_CONTROL_REGISTER_RESULT, /* key to use after registration */
144
RDMA_CONTROL_REGISTER_FINISHED, /* current iteration finished */
145
- RDMA_CONTROL_UNREGISTER_REQUEST, /* dynamic UN-registration */
146
- RDMA_CONTROL_UNREGISTER_FINISHED, /* unpinning finished */
145
RDMA_CONTROL_NUM,
146
};
147
@@ -232,8 +230,6 @@ static const char *control_desc(unsigned int rdma_control)
230
[RDMA_CONTROL_REGISTER_REQUEST] = "REGISTER REQUEST",
231
[RDMA_CONTROL_REGISTER_RESULT] = "REGISTER RESULT",
232
[RDMA_CONTROL_REGISTER_FINISHED] = "REGISTER FINISHED",
235
- [RDMA_CONTROL_UNREGISTER_REQUEST] = "UNREGISTER REQUEST",
236
- [RDMA_CONTROL_UNREGISTER_FINISHED] = "UNREGISTER FINISHED",
233
};
234
235
if (rdma_control >= RDMA_CONTROL_NUM) {
@@ -370,9 +366,6 @@ typedef struct RDMAContext {
366
int total_registrations;
367
int total_writes;
368
373
- int unregister_current, unregister_next;
374
- uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX];
375
-
369
GHashTable *blockmap;
370
371
/* the RDMAContext for return path */
@@ -1186,91 +1179,6 @@ static int qemu_rdma_reg_control(RDMAContext *rdma, int idx)
1179
return -1;
1180
}
1181
1189
-/*
1190
- * Perform a non-optimized memory unregistration after every transfer
1191
- * for demonstration purposes, only if pin-all is not requested.
1192
- *
1193
- * Potential optimizations:
1194
- * 1. Start a new thread to run this function continuously
1195
- - for bit clearing
1196
- - and for receipt of unregister messages
1197
- * 2. Use an LRU.
1198
- * 3. Use workload hints.
1199
- */
1200
-static int qemu_rdma_unregister_waiting(RDMAContext *rdma)
1201
-{
1202
- Error *err = NULL;
1203
-
1204
- while (rdma->unregistrations[rdma->unregister_current]) {
1205
- int ret;
1206
- uint64_t wr_id = rdma->unregistrations[rdma->unregister_current];
1207
- uint64_t chunk =
1208
- (wr_id & RDMA_WRID_CHUNK_MASK) >> RDMA_WRID_CHUNK_SHIFT;
1209
- uint64_t index =
1210
- (wr_id & RDMA_WRID_BLOCK_MASK) >> RDMA_WRID_BLOCK_SHIFT;
1211
- RDMALocalBlock *block =
1212
- &(rdma->local_ram_blocks.block[index]);
1213
- RDMARegister reg = { .current_index = index };
1214
- RDMAControlHeader resp = { .type = RDMA_CONTROL_UNREGISTER_FINISHED,
1215
- };
1216
- RDMAControlHeader head = { .len = sizeof(RDMARegister),
1217
- .type = RDMA_CONTROL_UNREGISTER_REQUEST,
1218
- .repeat = 1,
1219
- };
1220
-
1221
- trace_qemu_rdma_unregister_waiting_proc(chunk,
1222
- rdma->unregister_current);
1223
-
1224
- rdma->unregistrations[rdma->unregister_current] = 0;
1225
- rdma->unregister_current++;
1226
-
1227
- if (rdma->unregister_current == RDMA_SIGNALED_SEND_MAX) {
1228
- rdma->unregister_current = 0;
1229
- }
1230
-
1231
-
1232
- /*
1233
- * Unregistration is speculative (because migration is single-threaded
1234
- * and we cannot break the protocol's inifinband message ordering).
1235
- * Thus, if the memory is currently being used for transmission,
1236
- * then abort the attempt to unregister and try again
1237
- * later the next time a completion is received for this memory.
1238
- */
1239
- clear_bit(chunk, block->unregister_bitmap);
1240
-
1241
- if (test_bit(chunk, block->transit_bitmap)) {
1242
- trace_qemu_rdma_unregister_waiting_inflight(chunk);
1243
- continue;
1244
- }
1245
-
1246
- trace_qemu_rdma_unregister_waiting_send(chunk);
1247
-
1248
- ret = ibv_dereg_mr(block->pmr[chunk]);
1249
- block->pmr[chunk] = NULL;
1250
- block->remote_keys[chunk] = 0;
1251
-
1252
- if (ret != 0) {
1253
- error_report("unregistration chunk failed: %s",
1254
- strerror(ret));
1255
- return -1;
1256
- }
1257
- rdma->total_registrations--;
1258
-
1259
- reg.key.chunk = chunk;
1260
- register_to_network(rdma, ®);
1261
- ret = qemu_rdma_exchange_send(rdma, &head, (uint8_t *) ®,
1262
- &resp, NULL, NULL, &err);
1263
- if (ret < 0) {
1264
- error_report_err(err);
1265
- return -1;
1266
- }
1267
-
1268
- trace_qemu_rdma_unregister_waiting_complete(chunk);
1269
- }
1270
-
1271
- return 0;
1272
-}
1273
-
1182
static uint64_t qemu_rdma_make_wrid(uint64_t wr_id, uint64_t index,
1183
uint64_t chunk)
1184
{
@@ -2757,8 +2665,6 @@ static int qemu_rdma_drain_cq(RDMAContext *rdma)
2665
}
2666
}
2667
2760
- qemu_rdma_unregister_waiting(rdma);
2761
-
2668
return 0;
2669
}
2670
@@ -3336,10 +3242,6 @@ int rdma_registration_handle(QEMUFile *f)
3242
.type = RDMA_CONTROL_REGISTER_RESULT,
3243
.repeat = 0,
3244
};
3339
- RDMAControlHeader unreg_resp = { .len = 0,
3340
- .type = RDMA_CONTROL_UNREGISTER_FINISHED,
3341
- .repeat = 0,
3342
- };
3245
RDMAControlHeader blocks = { .type = RDMA_CONTROL_RAM_BLOCKS_RESULT,
3246
.repeat = 1 };
3247
QIOChannelRDMA *rioc;
@@ -3552,41 +3454,6 @@ int rdma_registration_handle(QEMUFile *f)
3454
ret = qemu_rdma_post_send_control(rdma,
3455
(uint8_t *) results, ®_resp, &err);
3456
3555
- if (ret < 0) {
3556
- error_report_err(err);
3557
- goto err;
3558
- }
3559
- break;
3560
- case RDMA_CONTROL_UNREGISTER_REQUEST:
3561
- trace_rdma_registration_handle_unregister(head.repeat);
3562
- unreg_resp.repeat = head.repeat;
3563
- registers = (RDMARegister *) rdma->wr_data[idx].control_curr;
3564
-
3565
- for (int count = 0; count < head.repeat; count++) {
3566
- reg = ®isters[count];
3567
- network_to_register(reg);
3568
-
3569
- trace_rdma_registration_handle_unregister_loop(count,
3570
- reg->current_index, reg->key.chunk);
3571
-
3572
- block = &(rdma->local_ram_blocks.block[reg->current_index]);
3573
-
3574
- ret = ibv_dereg_mr(block->pmr[reg->key.chunk]);
3575
- block->pmr[reg->key.chunk] = NULL;
3576
-
3577
- if (ret != 0) {
3578
- error_report("rdma unregistration chunk failed: %s",
3579
- strerror(errno));
3580
- goto err;
3581
- }
3582
-
3583
- rdma->total_registrations--;
3584
-
3585
- trace_rdma_registration_handle_unregister_success(reg->key.chunk);
3586
- }
3587
-
3588
- ret = qemu_rdma_post_send_control(rdma, NULL, &unreg_resp, &err);
3589
-
3457
if (ret < 0) {
3458
error_report_err(err);
3459
goto err;
migration/trace-events
-9
@@ -242,12 +242,6 @@ qemu_rdma_register_and_get_keys(uint64_t len, void *start) "Registering %" PRIu6
242
qemu_rdma_register_odp_mr(const char *name) "Try to register On-Demand Paging memory region: %s"
243
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"
244
qemu_rdma_resolve_host_trying(const char *host, const char *ip) "Trying %s => %s"
245
-qemu_rdma_signal_unregister_append(uint64_t chunk, int pos) "Appending unregister chunk %" PRIu64 " at position %d"
246
-qemu_rdma_signal_unregister_already(uint64_t chunk) "Unregister chunk %" PRIu64 " already in queue"
247
-qemu_rdma_unregister_waiting_inflight(uint64_t chunk) "Cannot unregister inflight chunk: %" PRIu64
248
-qemu_rdma_unregister_waiting_proc(uint64_t chunk, int pos) "Processing unregister for chunk: %" PRIu64 " at position %d"
249
-qemu_rdma_unregister_waiting_send(uint64_t chunk) "Sending unregister for chunk: %" PRIu64
250
-qemu_rdma_unregister_waiting_complete(uint64_t chunk) "Unregister for chunk: %" PRIu64 " complete."
245
qemu_rdma_write_flush(int sent) "sent total: %d"
246
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"
247
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 +260,6 @@ rdma_registration_handle_ram_blocks_loop(const char *name, uint64_t offset, uint
260
rdma_registration_handle_register(int requests) "%d requests"
261
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
262
rdma_registration_handle_register_rkey(int rkey) "0x%x"
269
-rdma_registration_handle_unregister(int requests) "%d requests"
270
-rdma_registration_handle_unregister_loop(int count, int index, uint64_t chunk) "Unregistration request (%d): index %d, chunk %" PRIu64
271
-rdma_registration_handle_unregister_success(uint64_t chunk) "%" PRIu64
263
rdma_registration_handle_wait(void) ""
264
rdma_registration_start(uint64_t flags) "%" PRIu64
265
rdma_registration_stop(uint64_t flags) "%" PRIu64