From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47276) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VYSbx-0005WW-2V for qemu-devel@nongnu.org; Mon, 21 Oct 2013 23:26:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VYSbo-0004YH-5A for qemu-devel@nongnu.org; Mon, 21 Oct 2013 23:26:25 -0400 Received: from e28smtp04.in.ibm.com ([122.248.162.4]:60212) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VYSbn-0004Y1-IL for qemu-devel@nongnu.org; Mon, 21 Oct 2013 23:26:16 -0400 Received: from /spool/local by e28smtp04.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 22 Oct 2013 08:56:14 +0530 Received: from d28relay05.in.ibm.com (d28relay05.in.ibm.com [9.184.220.62]) by d28dlp01.in.ibm.com (Postfix) with ESMTP id 73BFBE004A for ; Tue, 22 Oct 2013 08:57:42 +0530 (IST) Received: from d28av04.in.ibm.com (d28av04.in.ibm.com [9.184.220.66]) by d28relay05.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r9M3Q9fY40173674 for ; Tue, 22 Oct 2013 08:56:09 +0530 Received: from d28av04.in.ibm.com (localhost [127.0.0.1]) by d28av04.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id r9M3QBhx023450 for ; Tue, 22 Oct 2013 08:56:11 +0530 From: Lei Li Date: Tue, 22 Oct 2013 11:25:34 +0800 Message-Id: <1382412341-1173-11-git-send-email-lilei@linux.vnet.ibm.com> In-Reply-To: <1382412341-1173-1-git-send-email-lilei@linux.vnet.ibm.com> References: <1382412341-1173-1-git-send-email-lilei@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 10/17] migration-local: override save_page for page transmit List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aarcange@redhat.com, aliguori@us.ibm.com, Lei Li , quintela@redhat.com, mdroth@linux.vnet.ibm.com, mrhines@linux.vnet.ibm.com, lagarcia@br.ibm.com, pbonzini@redhat.com, rcj@linux.vnet.ibm.com This patch implements save_page callback for the outside of page flipping. It will write the address of the page on the Unix socket and flip the page data on pipe by vmsplice(). Every page address would have a header flag RAM_SAVE_FLAG_HOOK. Signed-off-by: Lei Li --- migration-local.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/migration-local.c b/migration-local.c index 92c661c..7ccec30 100644 --- a/migration-local.c +++ b/migration-local.c @@ -139,6 +139,59 @@ static int qemu_local_send_pipefd(QEMUFile *f, void *opaque, return 0; } +static size_t qemu_local_save_ram(QEMUFile *f, void *opaque, + ram_addr_t block_offset, ram_addr_t offset, + size_t size, int *bytes_sent) +{ + QEMUFileLocal *s = opaque; + ram_addr_t current_addr = block_offset + offset; + void *ram_addr; + ssize_t ret; + + if (s->unix_page_flipping) { + qemu_fflush(s->file); + qemu_put_be64(s->file, RAM_SAVE_FLAG_HOOK); + + /* Write page address to unix socket */ + qemu_put_be64(s->file, current_addr); + + ram_addr = qemu_get_ram_ptr(current_addr); + + /* vmsplice page data to pipe */ + struct iovec iov = { + .iov_base = ram_addr, + .iov_len = size, + }; + + /* + * The flag SPLICE_F_MOVE is introduced in kernel for the page + * flipping feature in QEMU, which will movie pages rather than + * copying, previously unused. + * + * If a move is not possible the kernel will transparently falls + * back to copying data. + * + * For older kernels the SPLICE_F_MOVE would be ignored and a copy + * would occur. + */ + ret = vmsplice(s->pipefd[1], &iov, 1, SPLICE_F_GIFT | SPLICE_F_MOVE); + if (ret == -1) { + if (errno != EAGAIN && errno != EINTR) { + fprintf(stderr, "vmsplice save error: %s\n", strerror(errno)); + return ret; + } + } else { + if (bytes_sent) { + *bytes_sent = 1; + } + DPRINTF("block_offset: %lu, offset: %lu\n", block_offset, offset); + return 0; + } + } + + return RAM_SAVE_CONTROL_NOT_SUPP; +} + static const QEMUFileOps pipe_read_ops = { .get_fd = qemu_local_get_sockfd, .get_buffer = qemu_local_get_buffer, @@ -150,6 +203,7 @@ static const QEMUFileOps pipe_write_ops = { .writev_buffer = qemu_local_writev_buffer, .close = qemu_local_close, .before_ram_iterate = qemu_local_send_pipefd, + .save_page = qemu_local_save_ram }; QEMUFile *qemu_fopen_socket_local(int sockfd, const char *mode) -- 1.7.7.6