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] Fix some issues for HVM log dirty:

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Fix some issues for HVM log dirty:
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 07 Sep 2009 01:05:13 -0700
Delivery-date: Mon, 07 Sep 2009 01:05:17 -0700
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 1252309078 -3600
# Node ID 49b561416efca3b5ebe143ce6349f892f249b5f4
# Parent  ead107bc25cb18143213d271b4122bf87d790228
Fix some issues for HVM log dirty:
* Add necessary logging dirty in qemu to avoid guest error with
intensive disk access when live migration
* Take place of shared memory between qemu and migration tools by new
added hypercall, which is clean and simple

Signed-Off-By: Zhai, Edwin <edwin.zhai@xxxxxxxxx>
---
 tools/libxc/ia64/xc_ia64_linux_save.c |   38 +--------
 tools/libxc/xc_domain_save.c          |   41 +---------
 tools/libxc/xenguest.h                |    3 
 tools/xcutils/xc_save.c               |  133 ++++++++++------------------------
 4 files changed, 53 insertions(+), 162 deletions(-)

diff -r ead107bc25cb -r 49b561416efc tools/libxc/ia64/xc_ia64_linux_save.c
--- a/tools/libxc/ia64/xc_ia64_linux_save.c     Fri Sep 04 08:43:05 2009 +0100
+++ b/tools/libxc/ia64/xc_ia64_linux_save.c     Mon Sep 07 08:37:58 2009 +0100
@@ -382,8 +382,7 @@ int
 int
 xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
                uint32_t max_factor, uint32_t flags, int (*suspend)(void),
-               int hvm, void *(*init_qemu_maps)(int, unsigned),
-               void (*qemu_flip_buffer)(int, int))
+               int hvm, void (*switch_qemu_logdirty)(int, unsigned))
 {
     DECLARE_DOMCTL;
     xc_dominfo_t info;
@@ -423,11 +422,6 @@ xc_domain_save(int xc_handle, int io_fd,
     unsigned long *to_skip = NULL;
 
     char *mem;
-
-    /* HVM: shared-memory bitmaps for getting log-dirty bits from qemu-dm */
-    unsigned long *qemu_bitmaps[2];
-    int qemu_active = 0;
-    int qemu_non_active = 1;
 
     /* for foreign p2m exposure */
     unsigned long memmap_info_num_pages;
@@ -545,14 +539,9 @@ xc_domain_save(int xc_handle, int io_fd,
             goto out;
         }
 
-        if (hvm) {
-            /* Get qemu-dm logging dirty pages too */
-            void *seg = init_qemu_maps(dom, bitmap_size);
-            qemu_bitmaps[0] = seg;
-            qemu_bitmaps[1] = seg + bitmap_size;
-            qemu_active = 0;
-            qemu_non_active = 1;
-        }
+        /* Enable qemu-dm logging dirty pages to xen */
+        if (hvm)
+            switch_qemu_logdirty(dom, 1);
     } else {
 
         /* This is a non-live suspend. Issue the call back to get the
@@ -703,23 +692,6 @@ xc_domain_save(int xc_handle, int io_fd,
                 goto out;
             }
 
-            if (hvm) {
-                unsigned int j;
-                /* Pull in the dirty bits from qemu-dm too */
-                if (!last_iter) {
-                    qemu_active = qemu_non_active;
-                    qemu_non_active = qemu_active ? 0 : 1;
-                    qemu_flip_buffer(dom, qemu_active);
-                    for (j = 0; j < bitmap_size / sizeof(unsigned long); j++) {
-                        to_send[j] |= qemu_bitmaps[qemu_non_active][j];
-                        qemu_bitmaps[qemu_non_active][j] = 0;
-                    }
-                } else {
-                    for (j = 0; j < bitmap_size / sizeof(unsigned long); j++)
-                        to_send[j] |= qemu_bitmaps[qemu_active][j];
-                }
-            }
-
             sent_last_iter = sent_this_iter;
 
             //print_stats(xc_handle, dom, sent_this_iter, &stats, 1);
@@ -762,6 +734,8 @@ xc_domain_save(int xc_handle, int io_fd,
                               NULL, 0, NULL, 0, NULL ) < 0) {
             DPRINTF("Warning - couldn't disable shadow mode");
         }
+        if ( hvm )
+            switch_qemu_logdirty(dom, 0);
     }
 
     unlock_pages(to_send, bitmap_size);
diff -r ead107bc25cb -r 49b561416efc tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Fri Sep 04 08:43:05 2009 +0100
+++ b/tools/libxc/xc_domain_save.c      Mon Sep 07 08:37:58 2009 +0100
@@ -38,11 +38,6 @@ static unsigned long hvirt_start;
 
 /* #levels of page tables used by the current guest */
 static unsigned int pt_levels;
-
-/* HVM: shared-memory bitmaps for getting log-dirty bits from qemu-dm */
-static unsigned long *qemu_bitmaps[2];
-static int qemu_active;
-static int qemu_non_active;
 
 /* number of pfns this guest has (i.e. number of entries in the P2M) */
 static unsigned long p2m_size;
@@ -748,8 +743,7 @@ static xen_pfn_t *map_and_save_p2m_table
 
 int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
                    uint32_t max_factor, uint32_t flags, int (*suspend)(void),
-                   int hvm, void *(*init_qemu_maps)(int, unsigned), 
-                   void (*qemu_flip_buffer)(int, int))
+                   int hvm, void (*switch_qemu_logdirty)(int, unsigned))
 {
     xc_dominfo_t info;
     DECLARE_DOMCTL;
@@ -863,15 +857,9 @@ int xc_domain_save(int xc_handle, int io
             }
         }
 
+        /* Enable qemu-dm logging dirty pages to xen */
         if ( hvm )
-        {
-            /* Get qemu-dm logging dirty pages too */
-            void *seg = init_qemu_maps(dom, BITMAP_SIZE);
-            qemu_bitmaps[0] = seg;
-            qemu_bitmaps[1] = seg + BITMAP_SIZE;
-            qemu_active = 0;
-            qemu_non_active = 1;
-        }
+            switch_qemu_logdirty(dom, 1);
     }
     else
     {
@@ -1341,27 +1329,6 @@ int xc_domain_save(int xc_handle, int io
                 goto out;
             }
 
-            if ( hvm ) 
-            {
-                /* Pull in the dirty bits from qemu-dm too */
-                if ( !last_iter )
-                {
-                    qemu_active = qemu_non_active;
-                    qemu_non_active = qemu_active ? 0 : 1;
-                    qemu_flip_buffer(dom, qemu_active);
-                    for ( j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++ )
-                    {
-                        to_send[j] |= qemu_bitmaps[qemu_non_active][j];
-                        qemu_bitmaps[qemu_non_active][j] = 0;
-                    }
-                }
-                else
-                {
-                    for ( j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++ )
-                        to_send[j] |= qemu_bitmaps[qemu_active][j];
-                }
-            }
-
             sent_last_iter = sent_this_iter;
 
             print_stats(xc_handle, dom, sent_this_iter, &stats, 1);
@@ -1629,6 +1596,8 @@ int xc_domain_save(int xc_handle, int io
                                XEN_DOMCTL_SHADOW_OP_OFF,
                                NULL, 0, NULL, 0, NULL) < 0 )
             DPRINTF("Warning - couldn't disable shadow mode");
+        if ( hvm )
+            switch_qemu_logdirty(dom, 0);
     }
 
     /* Flush last write and discard cache for file. */
diff -r ead107bc25cb -r 49b561416efc tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Fri Sep 04 08:43:05 2009 +0100
+++ b/tools/libxc/xenguest.h    Mon Sep 07 08:37:58 2009 +0100
@@ -26,8 +26,7 @@ int xc_domain_save(int xc_handle, int io
 int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
                    uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
                    int (*suspend)(void), int hvm,
-                   void *(*init_qemu_maps)(int, unsigned),  /* HVM only */
-                   void (*qemu_flip_buffer)(int, int));     /* HVM only */
+                   void (*switch_qemu_logdirty)(int, unsigned)); /* HVM only */
 
 
 /**
diff -r ead107bc25cb -r 49b561416efc tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c   Fri Sep 04 08:43:05 2009 +0100
+++ b/tools/xcutils/xc_save.c   Mon Sep 07 08:37:58 2009 +0100
@@ -101,115 +101,64 @@ static int suspend(void)
  * the new active buffer.  xc_save can then process and clear the old
  * active buffer. */
 
-static char *qemu_active_path;
-static char *qemu_next_active_path;
-static int qemu_shmid = -1;
-static struct xs_handle *xs;
-
-
-/* Mark the shared-memory segment for destruction */
-static void qemu_destroy_buffer(void)
-{
-    if (qemu_shmid != -1)
-        shmctl(qemu_shmid, IPC_RMID, NULL);
-    qemu_shmid = -1;
-}
-
-/* Get qemu to change buffers. */
-static void qemu_flip_buffer(int domid, int next_active)
-{
-    char digit = '0' + next_active;
+
+static void switch_qemu_logdirty(int domid, unsigned int enable)
+{
+    struct xs_handle *xs;
+    char *path, *p, *ret_str, *cmd_str, **watch;
     unsigned int len;
-    char *active_str, **watch;
     struct timeval tv;
     fd_set fdset;
 
-    /* Tell qemu that we want it to start writing log-dirty bits to the
-     * other buffer */
-    if (!xs_write(xs, XBT_NULL, qemu_next_active_path, &digit, 1))
-        errx(1, "can't write next-active to store path (%s)\n", 
-             qemu_next_active_path);
-
-    /* Wait a while for qemu to signal that it has switched to the new 
-     * active buffer */
- read_again: 
-    tv.tv_sec = 5;
-    tv.tv_usec = 0;
-    FD_ZERO(&fdset);
-    FD_SET(xs_fileno(xs), &fdset);
-    if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1)
-        errx(1, "timed out waiting for qemu to switch buffers\n");
-    watch = xs_read_watch(xs, &len);
-    free(watch);
-    
-    active_str = xs_read(xs, XBT_NULL, qemu_active_path, &len);
-    if (active_str == NULL || active_str[0] - '0' != next_active) 
-        /* Watch fired but value is not yet right */
-        goto read_again;
-}
-
-static void *init_qemu_maps(int domid, unsigned int bitmap_size)
-{
-    key_t key;
-    char key_ascii[17] = {0,};
-    void *seg; 
-    char *path, *p;
-
-    /* Make a shared-memory segment */
-    do {
-        key = rand(); /* No security, just a sequence of numbers */
-        qemu_shmid = shmget(key, 2 * bitmap_size, 
-                       IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
-        if (qemu_shmid == -1 && errno != EEXIST)
-            errx(1, "can't get shmem to talk to qemu-dm");
-    } while (qemu_shmid == -1);
-
-    /* Remember to tidy up after ourselves */
-    atexit(qemu_destroy_buffer);
-
-    /* Map it into our address space */
-    seg = shmat(qemu_shmid, NULL, 0);
-    if (seg == (void *) -1) 
-        errx(1, "can't map shmem to talk to qemu-dm");
-    memset(seg, 0, 2 * bitmap_size);
-
-    /* Write the size of it into the first 32 bits */
-    *(uint32_t *)seg = bitmap_size;
-
-    /* Tell qemu about it */
     if ((xs = xs_daemon_open()) == NULL)
         errx(1, "Couldn't contact xenstore");
     if (!(path = strdup("/local/domain/0/device-model/")))
         errx(1, "can't get domain path in store");
     if (!(path = realloc(path, strlen(path) 
                          + 10 
-                         + strlen("/logdirty/next-active") + 1))) 
+                         + strlen("/logdirty/cmd") + 1)))
         errx(1, "no memory for constructing xenstore path");
     snprintf(path + strlen(path), 11, "%i", domid);
     strcat(path, "/logdirty/");
     p = path + strlen(path);
 
-    strcpy(p, "key");
-    snprintf(key_ascii, 17, "%16.16llx", (unsigned long long) key);
-    if (!xs_write(xs, XBT_NULL, path, key_ascii, 16))
-        errx(1, "can't write key (%s) to store path (%s)\n", key_ascii, path);
-
-    /* Watch for qemu's indication of the active buffer, and request it 
-     * to start writing to buffer 0 */
-    strcpy(p, "active");
-    if (!xs_watch(xs, path, "qemu-active-buffer"))
+
+    /* Watch for qemu's return value */
+    strcpy(p, "ret");
+    if (!xs_watch(xs, path, "qemu-logdirty-ret"))
         errx(1, "can't set watch in store (%s)\n", path);
-    if (!(qemu_active_path = strdup(path)))
-        errx(1, "no memory for copying xenstore path");
-
-    strcpy(p, "next-active");
-    if (!(qemu_next_active_path = strdup(path)))
-        errx(1, "no memory for copying xenstore path");
-
-    qemu_flip_buffer(domid, 0);
+
+    if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable")))
+        errx(1, "can't get logdirty cmd path in store");
+
+    /* Tell qemu that we want it to start logging dirty page to Xen */
+    strcpy(p, "cmd");
+    if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str)))
+        errx(1, "can't write  to store path (%s)\n",
+             path);
+
+    /* Wait a while for qemu to signal that it has service logdirty command */
+ read_again:
+    tv.tv_sec = 5;
+    tv.tv_usec = 0;
+    FD_ZERO(&fdset);
+    FD_SET(xs_fileno(xs), &fdset);
+
+    if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1)
+        errx(1, "timed out waiting for qemu logdirty response.\n");
+
+    watch = xs_read_watch(xs, &len);
+    free(watch);
+
+    strcpy(p, "ret");
+    ret_str = xs_read(xs, XBT_NULL, path, &len);
+    if (ret_str == NULL || strcmp(ret_str, cmd_str))
+        /* Watch fired but value is not yet right */
+        goto read_again;
 
     free(path);
-    return seg;
+    free(cmd_str);
+    free(ret_str);
 }
 
 int
@@ -255,7 +204,7 @@ main(int argc, char **argv)
     }
     ret = xc_domain_save(si.xc_fd, io_fd, si.domid, maxit, max_f, si.flags, 
                          &suspend, !!(si.flags & XCFLAGS_HVM),
-                         &init_qemu_maps, &qemu_flip_buffer);
+                         &switch_qemu_logdirty);
 
     if (si.suspend_evtchn > 0)
         xc_suspend_evtchn_release(si.xce, si.suspend_evtchn);

_______________________________________________
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] Fix some issues for HVM log dirty:, Xen patchbot-unstable <=