WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Remus: Buffer checkpoint data locally unt

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Remus: Buffer checkpoint data locally until domain has resumed execution.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 09 Nov 2009 12:00:35 -0800
Delivery-date: Mon, 09 Nov 2009 12:01:02 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1257794179 0
# Node ID 7cfe986d0cc69f29b3041e8900e3a71607944d6a
# Parent  139a8a2536589b8555ef16cc24dda2ddb6802530
Remus: Buffer checkpoint data locally until domain has resumed execution.

Signed-off-by: Brendan Cully <brendan@xxxxxxxxx>
---
 tools/libxc/xc_domain_save.c |  113 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 112 insertions(+), 1 deletion(-)

diff -r 139a8a253658 -r 7cfe986d0cc6 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Mon Nov 09 19:15:34 2009 +0000
+++ b/tools/libxc/xc_domain_save.c      Mon Nov 09 19:16:19 2009 +0000
@@ -52,6 +52,15 @@ static unsigned long m2p_mfn0;
 /* Address size of the guest */
 unsigned int guest_width;
 
+/* buffer for output */
+struct outbuf {
+    void* buf;
+    size_t size;
+    size_t pos;
+};
+
+#define OUTBUF_SIZE (16384 * 1024)
+
 /* grep fodder: machine_to_phys */
 
 #define mfn_to_pfn(_mfn)  (live_m2p[(_mfn)])
@@ -152,6 +161,85 @@ static int noncached_write(int fd, int l
     }
 
     return rc;
+}
+
+static int outbuf_init(struct outbuf* ob, size_t size)
+{
+    memset(ob, 0, sizeof(*ob));
+
+    if ( !(ob->buf = malloc(size)) ) {
+        DPRINTF("error allocating output buffer of size %zu\n", size);
+        return -1;
+    }
+
+    ob->size = size;
+
+    return 0;
+}
+
+static inline int outbuf_write(struct outbuf* ob, void* buf, size_t len)
+{
+    if ( len > ob->size - ob->pos ) {
+        DPRINTF("outbuf_write: %zu > %zu@%zu\n", len, ob->size - ob->pos, 
ob->pos);
+        return -1;
+    }
+
+    memcpy(ob->buf + ob->pos, buf, len);
+    ob->pos += len;
+
+    return 0;
+}
+
+/* prep for nonblocking I/O */
+static int outbuf_flush(struct outbuf* ob, int fd)
+{
+    int rc;
+    int cur = 0;
+
+    if ( !ob->pos )
+        return 0;
+
+    rc = write(fd, ob->buf, ob->pos);
+    while (rc < 0 || cur + rc < ob->pos) {
+        if (rc < 0 && errno != EAGAIN && errno != EINTR) {
+            DPRINTF("error flushing output: %d\n", errno);
+            return -1;
+        }
+        if (rc > 0)
+            cur += rc;
+
+        rc = write(fd, ob->buf + cur, ob->pos - cur);
+    }
+
+    ob->pos = 0;
+
+    return 0;
+}
+
+/* if there's no room in the buffer, flush it and try again. */
+static inline int outbuf_hardwrite(struct outbuf* ob, int fd, void* buf,
+                                   size_t len)
+{
+    if ( !len )
+        return 0;
+
+    if ( !outbuf_write(ob, buf, len) )
+        return 0;
+
+    if ( outbuf_flush(ob, fd) < 0 )
+        return -1;
+
+    return outbuf_write(ob, buf, len);
+}
+
+/* start buffering output once we've reached checkpoint mode. */
+static inline int write_buffer(int dobuf, struct outbuf* ob, int fd, void* buf,
+                               size_t len)
+{
+    if ( dobuf )
+        return outbuf_hardwrite(ob, fd, buf, len);
+    else
+        return write_exact(fd, buf, len);
 }
 
 #ifdef ADAPTIVE_SAVE
@@ -246,6 +334,16 @@ static int ratewrite(int io_fd, int live
 
 #endif
 
+/* like write_buffer for ratewrite, which returns number of bytes written */
+static inline int ratewrite_buffer(int dobuf, struct outbuf* ob, int fd,
+                                   int live, void* buf, size_t len)
+{
+    if ( dobuf )
+        return outbuf_hardwrite(ob, fd, buf, len) ? -1 : len;
+    else
+        return ratewrite(fd, live, buf, len);
+}
+
 static int print_stats(int xc_handle, uint32_t domid, int pages_sent,
                        xc_shadow_op_stats_t *stats, int print)
 {
@@ -796,6 +894,10 @@ int xc_domain_save(int xc_handle, int io
 
     unsigned long mfn;
 
+    struct outbuf ob;
+
+    outbuf_init(&ob, OUTBUF_SIZE);
+
     /* If no explicit control parameters given, use defaults */
     max_iters  = max_iters  ? : DEF_MAX_ITERS;
     max_factor = max_factor ? : DEF_MAX_FACTOR;
@@ -995,6 +1097,12 @@ int xc_domain_save(int xc_handle, int io
     }
 
   copypages:
+#define write_exact(fd, buf, len) write_buffer(last_iter, &ob, (fd), (buf), 
(len))
+#ifdef ratewrite
+#undef ratewrite
+#endif
+#define ratewrite(fd, live, buf, len) ratewrite_buffer(last_iter, &ob, (fd), 
(live), (buf), (len))
+
     /* Now write out each data page, canonicalising page tables as we go... */
     for ( ; ; )
     {
@@ -1594,7 +1702,10 @@ int xc_domain_save(int xc_handle, int io
         callbacks->postcopy(callbacks->data);
 
     /* Flush last write and discard cache for file. */
-    discard_file_cache(io_fd, 1 /* flush */);
+    if ( outbuf_flush(&ob, io_fd) < 0 ) {
+        ERROR("Error when flushing output buffer\n");
+        rc = 1;
+    }
 
     /* checkpoint_cb can spend arbitrarily long in between rounds */
     if (!rc && callbacks->checkpoint &&

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Remus: Buffer checkpoint data locally until domain has resumed execution., Xen patchbot-unstable <=