* [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.