qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 10/17] migration-local: override save_page for p


From: Lei Li
Subject: Re: [Qemu-devel] [PATCH 10/17] migration-local: override save_page for page transmit
Date: Tue, 26 Nov 2013 20:10:12 +0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0

On 11/26/2013 07:22 PM, Paolo Bonzini wrote:
Il 21/11/2013 10:11, Lei Li ha scritto:
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, which will trigger the load hook to
receive it in incoming side as well.

Signed-off-by: Lei Li <address@hidden>
---
  migration-local.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++++++++
  1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/migration-local.c b/migration-local.c
index 0f0896b..14207e9 100644
--- a/migration-local.c
+++ b/migration-local.c
@@ -200,6 +200,59 @@ static int qemu_local_send_pipefd(QEMUFile *f, void 
*opaque,
      return 0;
  }
+static size_t qemu_local_save_ram(QEMUFile *f, void *opaque,
+                                  MemoryRegion *mr, ram_addr_t offset,
+                                  size_t size, int *bytes_sent)
+{
+    QEMUFileLocal *s = opaque;
+    ram_addr_t current_addr = mr->ram_addr + 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);
+
You can write current_addr | RAM_SAVE_FLAG_HOOK.  The value will be in
the flags argument of the hook_ram_load, you can extract it with "flags
& ~RAM_SAVE_FLAG_HOOK".  This cuts by half the data written to the Unix
socket.

OK, thanks.

Paolo

+        ram_addr = memory_region_get_ram_ptr(mr) + offset;
+
+        /* 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,
@@ -211,6 +264,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)




--
Lei




reply via email to

[Prev in Thread] Current Thread [Next in Thread]