Patchwork [2/4] savevm: Implement block_writev_buffer()

login
register
mail settings
Submitter Kevin Wolf
Date April 5, 2013, 7:27 p.m.
Message ID <1365190076-20268-3-git-send-email-kwolf@redhat.com>
Download mbox | patch
Permalink /patch/234263/
State New
Headers show

Comments

Kevin Wolf - April 5, 2013, 7:27 p.m.
Instead of breaking up RAM state into many small chunks, pass the iovec
to the block layer for better performance.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 include/migration/qemu-file.h |  2 +-
 savevm.c                      | 25 +++++++++++++++++++++----
 2 files changed, 22 insertions(+), 5 deletions(-)

Patch

diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index 623c434..7519464 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -55,7 +55,7 @@  typedef int (QEMUFileGetFD)(void *opaque);
  * This function writes an iovec to file.
  */
 typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
-                                           int iovcnt);
+                                           int iovcnt, int64_t pos);
 
 typedef struct QEMUFileOps {
     QEMUFilePutBufferFunc *put_buffer;
diff --git a/savevm.c b/savevm.c
index b1d8988..88fe985 100644
--- a/savevm.c
+++ b/savevm.c
@@ -176,7 +176,8 @@  static void coroutine_fn yield_until_fd_readable(int fd)
     qemu_coroutine_yield();
 }
 
-static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt)
+static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                    int64_t pos)
 {
     QEMUFileSocket *s = opaque;
     ssize_t len;
@@ -458,6 +459,21 @@  fail:
     return NULL;
 }
 
+static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                   int64_t pos)
+{
+    int ret;
+    QEMUIOVector qiov;
+
+    qemu_iovec_init_external(&qiov, iov, iovcnt);
+    ret = bdrv_writev_vmstate(opaque, &qiov, pos);
+    if (ret < 0) {
+        return ret;
+    }
+
+    return qiov.size;
+}
+
 static int block_put_buffer(void *opaque, const uint8_t *buf,
                            int64_t pos, int size)
 {
@@ -481,8 +497,9 @@  static const QEMUFileOps bdrv_read_ops = {
 };
 
 static const QEMUFileOps bdrv_write_ops = {
-    .put_buffer = block_put_buffer,
-    .close =      bdrv_fclose
+    .put_buffer     = block_put_buffer,
+    .writev_buffer  = block_writev_buffer,
+    .close          = bdrv_fclose
 };
 
 static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
@@ -533,7 +550,7 @@  static void qemu_fflush(QEMUFile *f)
 
     if (f->is_write && f->iovcnt > 0) {
         if (f->ops->writev_buffer) {
-            ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt);
+            ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
             if (ret >= 0) {
                 f->pos += ret;
             }