Move the per-iov QEMUFile control-byte send loop out of qio_channel_rdma_writev() into a reusable qemu_rdma_write_file() helper, and route the consumer's RDMA_CMD_FILE command through the same helper. No functional change to writev, which still sends inline.
Signed-off-by: Dmitrii Omelchenko <[email protected]> --- migration/rdma.c | 62 ++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/migration/rdma.c b/migration/rdma.c index d11f6e0da8..5ec6a87819 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -2523,6 +2523,34 @@ static RDMAContext *qemu_rdma_data_init(InetSocketAddress *saddr, Error **errp) * SEND messages for control only. * VM's ram is handled with regular RDMA messages. */ +static ssize_t qemu_rdma_write_file(RDMAContext *rdma, const struct iovec *iov, + size_t niov, Error **errp) +{ + ssize_t done = 0; + + for (size_t i = 0; i < niov; i++) { + size_t remaining = iov[i].iov_len; + uint8_t *data = iov[i].iov_base; + + while (remaining) { + RDMAControlHeader head = {}; + size_t len = MIN(remaining, RDMA_SEND_INCREMENT); + + remaining -= len; + head.len = len; + head.type = RDMA_CONTROL_QEMU_FILE; + + if (qemu_rdma_exchange_send(rdma, &head, data, + NULL, NULL, NULL, errp) < 0) { + return -1; + } + data += len; + done += len; + } + } + return done; +} + static ssize_t qio_channel_rdma_writev(QIOChannel *ioc, const struct iovec *iov, size_t niov, @@ -2535,7 +2563,6 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc, RDMAContext *rdma; int ret; ssize_t done = 0; - size_t len; RCU_READ_LOCK_GUARD(); rdma = qatomic_rcu_read(&rioc->rdmaout); @@ -2561,29 +2588,10 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc, return -1; } - for (int i = 0; i < niov; i++) { - size_t remaining = iov[i].iov_len; - uint8_t * data = (void *)iov[i].iov_base; - while (remaining) { - RDMAControlHeader head = {}; - - len = MIN(remaining, RDMA_SEND_INCREMENT); - remaining -= len; - - head.len = len; - head.type = RDMA_CONTROL_QEMU_FILE; - - ret = qemu_rdma_exchange_send(rdma, &head, - data, NULL, NULL, NULL, errp); - - if (ret < 0) { - rdma->errored = true; - return -1; - } - - data += len; - done += len; - } + done = qemu_rdma_write_file(rdma, iov, niov, errp); + if (done < 0) { + rdma->errored = true; + return -1; } return done; @@ -2928,12 +2936,14 @@ static int rdma_consumer_dispatch(RDMAContext *rdma, const RDMACmd *cmd, case RDMA_CMD_REG_STOP: ret = rdma_consumer_reg_stop(rdma, cmd->flags, &err); break; + case RDMA_CMD_FILE: + ret = qemu_rdma_write_file(rdma, cmd->iov, cmd->niov, &err) < 0 ? + -1 : 0; + break; case RDMA_CMD_FINISH: ret = qemu_rdma_drain_cq(rdma, &err); *stop = true; break; - default: - break; } if (ret < 0 && err) { error_report_err(err); -- 2.39.5
