[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save
From: |
Orit Wasserman |
Subject: |
Re: [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live |
Date: |
Sun, 29 Jul 2012 09:34:48 +0300 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20120717 Thunderbird/14.0 |
On 07/27/2012 01:20 AM, Eric Blake wrote:
> On 07/25/2012 08:50 AM, Orit Wasserman wrote:
>> In the outgoing migration check to see if the page is cached and
>> changed than send compressed page by using save_xbrle_page function.
>
> s/changed than/changed, then/
>
>> In the incoming migration check to see if RAM_SAVE_FLAG_XBZRLE is set
>> and decompress the page (by using load_xbrle function).
>>
>> Signed-off-by: Benoit Hudzia <address@hidden>
>> Signed-off-by: Petter Svard <address@hidden>
>> Signed-off-by: Aidan Shribman <address@hidden>
>> Signed-off-by: Orit Wasserman <address@hidden>
>
>> +/* struct contains XBZRLE cache and a static page
>> + used by the compression */
>> +static struct {
>> + /* buffer used for XBZRLE encoding */
>> + uint8_t *encoded_buf;
>> + /* buffer for storing page content */
>> + uint8_t *current_buf;
>> + /* buffer used for XBZRLE decoding */
>> + uint8_t *decoded_buf;
>> + /* Cache for XBZRLE */
>> + PageCache *cache;
>> +} XBZRLE = {
>> + .encoded_buf = NULL,
>> + .current_buf = NULL,
>> + .decoded_buf = NULL,
>> + .cache = NULL,
>> +};
>
> Explicit zero-initialization of a static object is pointless; C already
> guarantees that this will be the case without an initializer, due to the
> static lifetime.
You are right but as it harmless I will keep it.
>
>> +#define ENCODING_FLAG_XBZRLE 0x1
>> +
>> +static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
>> + ram_addr_t current_addr, RAMBlock *block,
>> + ram_addr_t offset, int cont)
>> +{
>> + int encoded_len = 0, bytes_sent = -1;
>> + XBZRLEHeader hdr = {
>> + .xh_len = 0,
>> + .xh_flags = 0,
>> + };
>
> [In contrast, this explicit zero-initialization of an automatic variable
> is essential.]
>
>> +
>> + /* we need to update the data in the cache, in order to get the same
>> data
>> + we cached we decode the encoded page on the cached data */
>> + memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
>
> Comment is out of date - a memcpy is not decoding onto the cache, but
> overwriting the entire cached page.
>
will be updated.
>> +
>> + hdr.xh_len = encoded_len;
>> + hdr.xh_flags |= ENCODING_FLAG_XBZRLE;
>> +
>> + /* Send XBZRLE based compressed page */
>> + save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
>> + qemu_put_byte(f, hdr.xh_flags);
>> + qemu_put_be16(f, hdr.xh_len);
>> + qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
>> + bytes_sent = encoded_len + sizeof(hdr);
>
> This looks like an off by one. sizeof(hdr) is 4 (2 bytes for xh_len, 1
> byte for xh_flags, then padded out to 2-byte multiple due to uint16_t
> member); but you really only sent 3 bytes (1 for xh_flags, 2 for
> xh_len), not 4.
correct, I was think of removing the header completely anyway.
>
>> @@ -321,7 +423,18 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
>> last_offset = 0;
>> sort_ram_list();
>>
>> - /* Make sure all dirty bits are set */
>
> Why are you losing this comment? It is still appropriate for the code
> in context after your insertion.
looks like bad merge I will fix it.
>
>> @@ -436,6 +549,49 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
>> return 0;
>> }
>>
>> +static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
>> +{
>> + int ret, rc = 0;
>> + XBZRLEHeader hdr = {
>> + .xh_len = 0,
>> + .xh_flags = 0,
>> + };
>> +
>> + if (!XBZRLE.decoded_buf) {
>> + XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE);
>> + }
>> +
>> + /* extract RLE header */
>> + hdr.xh_flags = qemu_get_byte(f);
>> + hdr.xh_len = qemu_get_be16(f);
>> +
>> + if (!(hdr.xh_flags & ENCODING_FLAG_XBZRLE)) {
>> + fprintf(stderr, "Failed to load XBZRLE page - wrong
>> compression!\n");
>
> Shouldn't you also validate that no other bits in xh_flags are set, so
> as to allow future versions of the protocol to define additional bits if
> we come up with further compression methods and gracefully be detected
> when the receiving end does not understand those bits? That is, this
> should be:
>
> if (hdr.xh_flags != ENCODING_FLAG_XBZRLE) {
>
ok
>> + return -1;
>> + }
>> +
>> + if (hdr.xh_len > TARGET_PAGE_SIZE) {
>> + fprintf(stderr, "Failed to load XBZRLE page - len overflow!\n");
>> + return -1;
>> + }
>> + /* load data and decode */
>> + qemu_get_buffer(f, XBZRLE.decoded_buf, hdr.xh_len);
>> +
>> + /* decode RLE */
>> + ret = xbzrle_decode_buffer(XBZRLE.decoded_buf, hdr.xh_len, host,
>> + TARGET_PAGE_SIZE);
>> + if (ret == -1) {
>> + fprintf(stderr, "Failed to load XBZRLE page - decode error!\n");
>> + rc = -1;
>> + } else if (ret > TARGET_PAGE_SIZE) {
>> + fprintf(stderr, "Failed to load XBZRLE page - size %d exceeds
>> %d!\n",
>> + ret, TARGET_PAGE_SIZE);
>
> Technically, this fprintf is unreachable; xbzrle_decode_buffer should
> return -1 instead of a value larger than its incoming dlen. You could
> abort() here to indicate a programming error.
ok
>
>> @@ -549,6 +705,19 @@ static int ram_load(QEMUFile *f, void *opaque, int
>> version_id)
>> }
>>
>> qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
>> + } else if (flags & RAM_SAVE_FLAG_XBZRLE) {
>> + if (!migrate_use_xbzrle()) {
>> + return -EINVAL;
>> + }
>> + void *host = host_from_stream_offset(f, addr, flags);
>> + if (!host) {
>> + return -EINVAL;
>> + }
>> +
>> + if (load_xbzrle(f, addr, host) < 0) {
>> + ret = -EINVAL;
>> + goto done;
>
> Is there any issue by returning early instead of using 'goto done' in
> all three error locations?
>
I think that it is written in this way for tracing ...
Thanks,
Orit
- [Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions, (continued)
- [Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 04/11] Add cache handling functions, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 00/11] Migration next v6, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 11/11] Restart optimization on stage3 update version, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 08/11] Add migrate_set_cachesize command, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 06/11] Add xbzrle_encode_buffer and xbzrle_decode_buffer functions, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 10/11] Add XBZRLE statistics, Orit Wasserman, 2012/07/25
- [Qemu-devel] [PATCH 09/11] Add migration accounting for normal and duplicate pages, Orit Wasserman, 2012/07/25