All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name
       [not found] <0100608191447.4451.47795.stgit@localhost.localdomain>
@ 2010-06-08 21:11   ` Alex Williamson
  0 siblings, 0 replies; 6+ messages in thread
From: Alex Williamson @ 2010-06-08 21:11 UTC (permalink / raw)
  To: qemu-devel, anthony; +Cc: kvm, quintela, chrisw, alex.williamson

Allows us to compress the protocol a bit.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---

 arch_init.c |   77 +++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 5780195..8ae6a10 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -87,6 +87,7 @@ const uint32_t arch_type = QEMU_ARCH;
 #define RAM_SAVE_FLAG_MEM_SIZE	0x04
 #define RAM_SAVE_FLAG_PAGE	0x08
 #define RAM_SAVE_FLAG_EOS	0x10
+#define RAM_SAVE_FLAG_CONTINUE	0x20
 
 static int is_dup_page(uint8_t *page, uint8_t ch)
 {
@@ -120,6 +121,7 @@ static int ram_save_block(QEMUFile *f)
     do {
         if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
             uint8_t *p;
+            int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
 
             cpu_physical_memory_reset_dirty(current_addr,
                                             current_addr + TARGET_PAGE_SIZE,
@@ -128,13 +130,17 @@ static int ram_save_block(QEMUFile *f)
             p = block->host + offset;
 
             if (is_dup_page(p, *p)) {
-                qemu_put_be64(f, offset | RAM_SAVE_FLAG_COMPRESS);
-                qemu_put_buffer(f, (uint8_t *)block->name, sizeof(block->name));
+                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
+                if (!cont)
+                    qemu_put_buffer(f, (uint8_t *)block->name,
+                                    sizeof(block->name));
                 qemu_put_byte(f, *p);
                 bytes_sent = 1;
             } else {
-                qemu_put_be64(f, offset | RAM_SAVE_FLAG_PAGE);
-                qemu_put_buffer(f, (uint8_t *)block->name, sizeof(block->name));
+                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE);
+                if (!cont)
+                    qemu_put_buffer(f, (uint8_t *)block->name,
+                                    sizeof(block->name));
                 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
                 bytes_sent = TARGET_PAGE_SIZE;
             }
@@ -284,6 +290,33 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
     return (stage == 2) && (expected_time <= migrate_max_downtime());
 }
 
+static inline void *host_from_stream_offset(QEMUFile *f,
+                                            ram_addr_t offset,
+                                            int flags)
+{
+    static RAMBlock *block = NULL;
+    char name[64];
+
+    if (flags & RAM_SAVE_FLAG_CONTINUE) {
+        if (!block) {
+            fprintf(stderr, "Ack, bad migration stream!\n");
+            return NULL;
+        }
+
+        return block->host + offset;
+    }
+
+    qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
+
+    QLIST_FOREACH(block, &ram.blocks, next) {
+        if (!strncmp(name, block->name, sizeof(name)))
+            return block->host + offset;
+    }
+
+    fprintf(stderr, "Can't find block %s!\n", name);
+    return NULL;
+}
+
 int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
     ram_addr_t addr;
@@ -337,23 +370,11 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
             void *host;
             uint8_t ch;
 
-            if (version_id == 3) {
+            if (version_id == 3)
                 host = qemu_get_ram_ptr(addr);
-            } else {
-                RAMBlock *block;
-                char name[64];
-
-                qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
+            else
+                host = host_from_stream_offset(f, addr, flags);
 
-                QLIST_FOREACH(block, &ram.blocks, next) {
-                    if (!strncmp(name, block->name, sizeof(name)))
-                        break;
-                }
-                if (!block)
-                    return -EINVAL;
-
-                host = block->host + addr;
-            }
             ch = qemu_get_byte(f);
             memset(host, ch, TARGET_PAGE_SIZE);
 #ifndef _WIN32
@@ -365,23 +386,11 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
         } else if (flags & RAM_SAVE_FLAG_PAGE) {
             void *host;
 
-            if (version_id == 3) {
+            if (version_id == 3)
                 host = qemu_get_ram_ptr(addr);
-            } else {
-                RAMBlock *block;
-                char name[64];
+            else
+                host = host_from_stream_offset(f, addr, flags);
 
-                qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
-
-                QLIST_FOREACH(block, &ram.blocks, next) {
-                    if (!strncmp(name, block->name, sizeof(name)))
-                        break;
-                }
-                if (!block)
-                    return -EINVAL;
-
-                host = block->host + addr;
-            }
             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
         }
         if (qemu_file_has_error(f)) {


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name
@ 2010-06-08 21:11   ` Alex Williamson
  0 siblings, 0 replies; 6+ messages in thread
From: Alex Williamson @ 2010-06-08 21:11 UTC (permalink / raw)
  To: qemu-devel, anthony; +Cc: chrisw, alex.williamson, kvm, quintela

Allows us to compress the protocol a bit.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---

 arch_init.c |   77 +++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 5780195..8ae6a10 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -87,6 +87,7 @@ const uint32_t arch_type = QEMU_ARCH;
 #define RAM_SAVE_FLAG_MEM_SIZE	0x04
 #define RAM_SAVE_FLAG_PAGE	0x08
 #define RAM_SAVE_FLAG_EOS	0x10
+#define RAM_SAVE_FLAG_CONTINUE	0x20
 
 static int is_dup_page(uint8_t *page, uint8_t ch)
 {
@@ -120,6 +121,7 @@ static int ram_save_block(QEMUFile *f)
     do {
         if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
             uint8_t *p;
+            int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
 
             cpu_physical_memory_reset_dirty(current_addr,
                                             current_addr + TARGET_PAGE_SIZE,
@@ -128,13 +130,17 @@ static int ram_save_block(QEMUFile *f)
             p = block->host + offset;
 
             if (is_dup_page(p, *p)) {
-                qemu_put_be64(f, offset | RAM_SAVE_FLAG_COMPRESS);
-                qemu_put_buffer(f, (uint8_t *)block->name, sizeof(block->name));
+                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
+                if (!cont)
+                    qemu_put_buffer(f, (uint8_t *)block->name,
+                                    sizeof(block->name));
                 qemu_put_byte(f, *p);
                 bytes_sent = 1;
             } else {
-                qemu_put_be64(f, offset | RAM_SAVE_FLAG_PAGE);
-                qemu_put_buffer(f, (uint8_t *)block->name, sizeof(block->name));
+                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE);
+                if (!cont)
+                    qemu_put_buffer(f, (uint8_t *)block->name,
+                                    sizeof(block->name));
                 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
                 bytes_sent = TARGET_PAGE_SIZE;
             }
@@ -284,6 +290,33 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
     return (stage == 2) && (expected_time <= migrate_max_downtime());
 }
 
+static inline void *host_from_stream_offset(QEMUFile *f,
+                                            ram_addr_t offset,
+                                            int flags)
+{
+    static RAMBlock *block = NULL;
+    char name[64];
+
+    if (flags & RAM_SAVE_FLAG_CONTINUE) {
+        if (!block) {
+            fprintf(stderr, "Ack, bad migration stream!\n");
+            return NULL;
+        }
+
+        return block->host + offset;
+    }
+
+    qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
+
+    QLIST_FOREACH(block, &ram.blocks, next) {
+        if (!strncmp(name, block->name, sizeof(name)))
+            return block->host + offset;
+    }
+
+    fprintf(stderr, "Can't find block %s!\n", name);
+    return NULL;
+}
+
 int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
     ram_addr_t addr;
@@ -337,23 +370,11 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
             void *host;
             uint8_t ch;
 
-            if (version_id == 3) {
+            if (version_id == 3)
                 host = qemu_get_ram_ptr(addr);
-            } else {
-                RAMBlock *block;
-                char name[64];
-
-                qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
+            else
+                host = host_from_stream_offset(f, addr, flags);
 
-                QLIST_FOREACH(block, &ram.blocks, next) {
-                    if (!strncmp(name, block->name, sizeof(name)))
-                        break;
-                }
-                if (!block)
-                    return -EINVAL;
-
-                host = block->host + addr;
-            }
             ch = qemu_get_byte(f);
             memset(host, ch, TARGET_PAGE_SIZE);
 #ifndef _WIN32
@@ -365,23 +386,11 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
         } else if (flags & RAM_SAVE_FLAG_PAGE) {
             void *host;
 
-            if (version_id == 3) {
+            if (version_id == 3)
                 host = qemu_get_ram_ptr(addr);
-            } else {
-                RAMBlock *block;
-                char name[64];
+            else
+                host = host_from_stream_offset(f, addr, flags);
 
-                qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
-
-                QLIST_FOREACH(block, &ram.blocks, next) {
-                    if (!strncmp(name, block->name, sizeof(name)))
-                        break;
-                }
-                if (!block)
-                    return -EINVAL;
-
-                host = block->host + addr;
-            }
             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
         }
         if (qemu_file_has_error(f)) {

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name
  2010-06-08 21:11   ` [Qemu-devel] " Alex Williamson
@ 2010-06-08 21:32     ` Alex Williamson
  -1 siblings, 0 replies; 6+ messages in thread
From: Alex Williamson @ 2010-06-08 21:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: anthony, kvm, quintela, chrisw

On Tue, 2010-06-08 at 15:11 -0600, Alex Williamson wrote:
> Allows us to compress the protocol a bit.
...
> @@ -284,6 +290,33 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
>      return (stage == 2) && (expected_time <= migrate_max_downtime());
>  }
>  
> +static inline void *host_from_stream_offset(QEMUFile *f,
> +                                            ram_addr_t offset,
> +                                            int flags)

This probably shouldn't be inline.  When sending, we'll continue from
COMPRESS or PAGE.  We'd get out of sync on the recv if the compiler
created separate static blocks.  Compiler folks correct me if this can't
happen.

Alex


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] Re: [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name
@ 2010-06-08 21:32     ` Alex Williamson
  0 siblings, 0 replies; 6+ messages in thread
From: Alex Williamson @ 2010-06-08 21:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: chrisw, kvm, quintela

On Tue, 2010-06-08 at 15:11 -0600, Alex Williamson wrote:
> Allows us to compress the protocol a bit.
...
> @@ -284,6 +290,33 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
>      return (stage == 2) && (expected_time <= migrate_max_downtime());
>  }
>  
> +static inline void *host_from_stream_offset(QEMUFile *f,
> +                                            ram_addr_t offset,
> +                                            int flags)

This probably shouldn't be inline.  When sending, we'll continue from
COMPRESS or PAGE.  We'd get out of sync on the recv if the compiler
created separate static blocks.  Compiler folks correct me if this can't
happen.

Alex

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name
  2010-06-08 21:32     ` [Qemu-devel] " Alex Williamson
@ 2010-06-08 22:29       ` Paolo Bonzini
  -1 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2010-06-08 22:29 UTC (permalink / raw)
  To: Alex Williamson; +Cc: qemu-devel, anthony, kvm, quintela, chrisw

On 06/08/2010 11:32 PM, Alex Williamson wrote:
> On Tue, 2010-06-08 at 15:11 -0600, Alex Williamson wrote:
>> Allows us to compress the protocol a bit.
> ...
>> @@ -284,6 +290,33 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
>>       return (stage == 2)&&  (expected_time<= migrate_max_downtime());
>>   }
>>
>> +static inline void *host_from_stream_offset(QEMUFile *f,
>> +                                            ram_addr_t offset,
>> +                                            int flags)
>
> This probably shouldn't be inline.  When sending, we'll continue from
> COMPRESS or PAGE.  We'd get out of sync on the recv if the compiler
> created separate static blocks.  Compiler folks correct me if this can't
> happen.

There is only one static variable even if the inlining happens in 
multiple places.  In fact, inlining is totally transparent.

Example:

$ cat > x.c <<\EOF
#ifndef force_inline
#define force_inline inline __attribute__((always_inline))
#endif

static force_inline int f()
{
	static int i;
	return i++;
}

int main()
{
	printf ("%d\n", f());
	printf ("%d\n", f());
	printf ("%d\n", f());
	printf ("%d\n", f());
}
EOF
$ gcc -o - -Dforce_inline= -S x.c | egrep -cw _?f
7
$ gcc -o - -S x.c | egrep -cw _?f
0
$ gcc x.c && ./a.out
0
1
2
3

Paolo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] Re: [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name
@ 2010-06-08 22:29       ` Paolo Bonzini
  0 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2010-06-08 22:29 UTC (permalink / raw)
  To: Alex Williamson; +Cc: chrisw, quintela, qemu-devel, kvm

On 06/08/2010 11:32 PM, Alex Williamson wrote:
> On Tue, 2010-06-08 at 15:11 -0600, Alex Williamson wrote:
>> Allows us to compress the protocol a bit.
> ...
>> @@ -284,6 +290,33 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
>>       return (stage == 2)&&  (expected_time<= migrate_max_downtime());
>>   }
>>
>> +static inline void *host_from_stream_offset(QEMUFile *f,
>> +                                            ram_addr_t offset,
>> +                                            int flags)
>
> This probably shouldn't be inline.  When sending, we'll continue from
> COMPRESS or PAGE.  We'd get out of sync on the recv if the compiler
> created separate static blocks.  Compiler folks correct me if this can't
> happen.

There is only one static variable even if the inlining happens in 
multiple places.  In fact, inlining is totally transparent.

Example:

$ cat > x.c <<\EOF
#ifndef force_inline
#define force_inline inline __attribute__((always_inline))
#endif

static force_inline int f()
{
	static int i;
	return i++;
}

int main()
{
	printf ("%d\n", f());
	printf ("%d\n", f());
	printf ("%d\n", f());
	printf ("%d\n", f());
}
EOF
$ gcc -o - -Dforce_inline= -S x.c | egrep -cw _?f
7
$ gcc -o - -S x.c | egrep -cw _?f
0
$ gcc x.c && ./a.out
0
1
2
3

Paolo

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-06-08 22:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <0100608191447.4451.47795.stgit@localhost.localdomain>
2010-06-08 21:11 ` [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name Alex Williamson
2010-06-08 21:11   ` [Qemu-devel] " Alex Williamson
2010-06-08 21:32   ` Alex Williamson
2010-06-08 21:32     ` [Qemu-devel] " Alex Williamson
2010-06-08 22:29     ` Paolo Bonzini
2010-06-08 22:29       ` [Qemu-devel] " Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.