[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH RFC 11/12] migration/rdma: use multiRDMA to send RAM block for NO
From: |
Zhimin Feng |
Subject: |
[PATCH RFC 11/12] migration/rdma: use multiRDMA to send RAM block for NOT rdma-pin-all mode |
Date: |
Thu, 9 Jan 2020 12:59:21 +0800 |
From: fengzhimin <address@hidden>
Signed-off-by: fengzhimin <address@hidden>
---
migration/rdma.c | 109 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 105 insertions(+), 4 deletions(-)
diff --git a/migration/rdma.c b/migration/rdma.c
index 36261f1fc8..0a150099e2 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -2084,8 +2084,7 @@ static int qemu_rdma_write_one(QEMUFile *f, RDMAContext
*rdma,
.repeat = 1,
};
- if (migrate_use_multiRDMA() &&
- migrate_use_rdma_pin_all()) {
+ if (migrate_use_multiRDMA()) {
/* The multiRDMA threads only send ram block */
if (strcmp(block->block_name, "mach-virt.ram") == 0) {
int channel = get_multiRDMA_channel();
@@ -2311,8 +2310,7 @@ static int qemu_rdma_write_flush(QEMUFile *f, RDMAContext
*rdma)
}
if (ret == 0) {
- if (migrate_use_multiRDMA() &&
- migrate_use_rdma_pin_all()) {
+ if (migrate_use_multiRDMA()) {
/* The multiRDMA threads only send ram block */
RDMALocalBlock *block = NULL;
block = &(rdma->local_ram_blocks.block[rdma->current_index]);
@@ -4234,12 +4232,24 @@ err:
static int qemu_multiRDMA_registration_handle(void *opaque)
{
+ RDMAControlHeader reg_resp = { .len = sizeof(RDMARegisterResult),
+ .type = RDMA_CONTROL_REGISTER_RESULT,
+ .repeat = 0,
+ };
RDMAControlHeader blocks = { .type = RDMA_CONTROL_RAM_BLOCKS_RESULT,
.repeat = 1 };
MultiRDMARecvParams *p = opaque;
RDMAContext *rdma = p->rdma;
RDMALocalBlocks *local = &rdma->local_ram_blocks;
RDMAControlHeader head;
+ RDMARegister *reg, *registers;
+ RDMACompress *comp;
+ RDMARegisterResult *reg_result;
+ static RDMARegisterResult results[RDMA_CONTROL_MAX_COMMANDS_PER_MESSAGE];
+ RDMALocalBlock *block;
+ void *host_addr;
+ int idx = 0;
+ int count = 0;
int ret = 0;
int i = 0;
@@ -4260,8 +4270,28 @@ static int qemu_multiRDMA_registration_handle(void
*opaque)
}
switch (head.type) {
+ case RDMA_CONTROL_COMPRESS:
+ comp = (RDMACompress *) rdma->wr_data[idx].control_curr;
+ network_to_compress(comp);
+
+ if (comp->block_idx >= rdma->local_ram_blocks.nb_blocks) {
+ error_report("rdma: 'compress' bad block index %u (vs %d)",
+ (unsigned int)comp->block_idx,
+ rdma->local_ram_blocks.nb_blocks);
+ ret = -EIO;
+ goto out;
+ }
+ block = &(rdma->local_ram_blocks.block[comp->block_idx]);
+
+ host_addr = block->local_host_addr +
+ (comp->offset - block->offset);
+
+ ram_handle_compressed(host_addr, comp->value, comp->length);
+ break;
+
case RDMA_CONTROL_REGISTER_FINISHED:
goto out;
+
case RDMA_CONTROL_RAM_BLOCKS_REQUEST:
qsort(rdma->local_ram_blocks.block,
rdma->local_ram_blocks.nb_blocks,
@@ -4310,8 +4340,79 @@ static int qemu_multiRDMA_registration_handle(void
*opaque)
error_report("rdma migration: error sending remote info");
goto out;
}
+ break;
+
+ case RDMA_CONTROL_REGISTER_REQUEST:
+ reg_resp.repeat = head.repeat;
+ registers = (RDMARegister *) rdma->wr_data[idx].control_curr;
+ for (count = 0; count < head.repeat; count++) {
+ uint64_t chunk;
+ uint8_t *chunk_start, *chunk_end;
+
+ reg = ®isters[count];
+ network_to_register(reg);
+
+ reg_result = &results[count];
+
+ if (reg->current_index >= rdma->local_ram_blocks.nb_blocks) {
+ error_report("rdma: 'register' bad block index %u (vs %d)",
+ (unsigned int)reg->current_index,
+ rdma->local_ram_blocks.nb_blocks);
+ ret = -ENOENT;
+ goto out;
+ }
+ 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);
+ ret = -ERANGE;
+ goto out;
+ }
+ 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 * (1UL << RDMA_REG_CHUNK_SHIFT));
+ /* 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);
+ ret = -ERANGE;
+ goto out;
+ }
+ }
+ chunk_start = ram_chunk_start(block, chunk);
+ chunk_end = ram_chunk_end(block, chunk + reg->chunks);
+ if (qemu_rdma_register_and_get_keys(rdma, block,
+ (uintptr_t)host_addr, NULL, ®_result->rkey,
+ chunk, chunk_start, chunk_end)) {
+ error_report("cannot get rkey");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ reg_result->host_addr = (uintptr_t)block->local_host_addr;
+
+ result_to_network(reg_result);
+ }
+
+ ret = qemu_rdma_post_send_control(rdma,
+ (uint8_t *) results, ®_resp);
+
+ if (ret < 0) {
+ error_report("Failed to send control buffer");
+ goto out;
+ }
break;
+
default:
error_report("Unknown control message %s",
control_desc(head.type));
ret = -EIO;
--
2.19.1
- [PATCH RFC 03/12] migration: Create the multi-rdma-channels parameter, (continued)
- [PATCH RFC 03/12] migration: Create the multi-rdma-channels parameter, Zhimin Feng, 2020/01/09
- [PATCH RFC 09/12] migration/rdma: Wait for all multiRDMA to complete registration, Zhimin Feng, 2020/01/09
- [PATCH RFC 04/12] migration/rdma: Create multiRDMA migration threads, Zhimin Feng, 2020/01/09
- [PATCH RFC 06/12] migration/rdma: Transmit initial package, Zhimin Feng, 2020/01/09
- [PATCH RFC 11/12] migration/rdma: use multiRDMA to send RAM block for NOT rdma-pin-all mode,
Zhimin Feng <=
- [PATCH RFC 01/12] migration: Add multiRDMA capability support, Zhimin Feng, 2020/01/09
- [PATCH RFC 10/12] migration/rdma: use multiRDMA to send RAM block for rdma-pin-all mode, Zhimin Feng, 2020/01/09
- [PATCH RFC 12/12] migration/rdma: only register the virt-ram block for MultiRDMA, Zhimin Feng, 2020/01/09