Patchwork [v5,04/12] rdma: introduce qemu_get_max_size()

login
register
mail settings
Submitter mrhines@linux.vnet.ibm.com
Date April 23, 2013, 1:55 a.m.
Message ID <1366682139-22122-5-git-send-email-mrhines@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/238712/
State New
Headers show

Comments

mrhines@linux.vnet.ibm.com - April 23, 2013, 1:55 a.m.
From: "Michael R. Hines" <mrhines@us.ibm.com>

This functions allows you to perform your own per-QEMUFileOps
calculation for the value of 'max_size'.

For RDMA, this calculation artificially limits migration throughput
and needs to be done differently for high-throughput links.

Signed-off-by: Michael R. Hines <mrhines@us.ibm.com>
---
 include/migration/qemu-file.h |   12 ++++++++++++
 migration.c                   |    3 ++-
 savevm.c                      |   19 +++++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

Patch

diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index 70eb9bd..1803aeb 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -57,12 +57,22 @@  typedef int (QEMUFileGetFD)(void *opaque);
 typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
                                            int iovcnt, int64_t pos);
 
+/*
+ * This function allows override of how to calculate max_size
+ * after each iteration.
+ */
+typedef size_t (QEMUFileMaxSizeFunc)(QEMUFile *f, void *opaque,
+                               uint64_t transferred_bytes,
+                               uint64_t time_spent,
+                               uint64_t max_downtime);
+
 typedef struct QEMUFileOps {
     QEMUFilePutBufferFunc *put_buffer;
     QEMUFileGetBufferFunc *get_buffer;
     QEMUFileCloseFunc *close;
     QEMUFileGetFD *get_fd;
     QEMUFileWritevBufferFunc *writev_buffer;
+    QEMUFileMaxSizeFunc *get_max_size;
 } QEMUFileOps;
 
 QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
@@ -81,6 +91,8 @@  void qemu_put_byte(QEMUFile *f, int v);
  */
 void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size);
 double qemu_get_mbps(void);
+size_t qemu_get_max_size(QEMUFile *f, uint64_t transferred_bytes,
+                         uint64_t time_spent, uint64_t max_downtime);
 
 
 static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
diff --git a/migration.c b/migration.c
index e2d73c4..48b5174 100644
--- a/migration.c
+++ b/migration.c
@@ -545,7 +545,8 @@  static void *migration_thread(void *opaque)
             uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes;
             uint64_t time_spent = current_time - initial_time - sleep_time;
             double bandwidth = transferred_bytes / time_spent;
-            max_size = bandwidth * migrate_max_downtime() / 1000000;
+            max_size = qemu_get_max_size(s->file, transferred_bytes,
+                    time_spent, migrate_max_downtime());
 
             DPRINTF("transferred %" PRIu64 " time_spent %" PRIu64
                     " bandwidth %g max_size %" PRId64 "\n",
diff --git a/savevm.c b/savevm.c
index 6fcad19..60776e5 100644
--- a/savevm.c
+++ b/savevm.c
@@ -647,6 +647,25 @@  int qemu_get_fd(QEMUFile *f)
     return -1;
 }
 
+size_t qemu_get_max_size(QEMUFile *f, uint64_t transferred_bytes,
+                         uint64_t time_spent, uint64_t max_downtime)
+{
+    if (time_spent) {
+        mbps = (((double) transferred_bytes * 8.0) /
+            ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
+    } else {
+        mbps = -1.0;
+    }
+
+    if (f->ops->get_max_size) {
+        return f->ops->get_max_size(f, f->opaque,
+            transferred_bytes, time_spent, max_downtime);
+    }
+
+    return ((double) (transferred_bytes / (double) time_spent)) *
+                    (double) max_downtime / 1000000.0;
+}
+
 /** Closes the file
  *
  * Returns negative error value if any error happened on previous operations or