All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Orit Wasserman <owasserm@redhat.com>
Cc: peter.maydell@linaro.org, aliguori@us.ibm.com,
	quintela@redhat.com, stefanha@gmail.com, qemu-devel@nongnu.org,
	mdroth@linux.vnet.ibm.com, blauwirbel@gmail.com,
	Petter Svard <petters@cs.umu.se>,
	Benoit Hudzia <benoit.hudzia@sap.com>,
	avi@redhat.com, Aidan Shribman <aidan.shribman@sap.com>,
	pbonzini@redhat.com, lcapitulino@redhat.com, chegu_vinod@hp.com
Subject: Re: [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live
Date: Thu, 26 Jul 2012 16:20:21 -0600	[thread overview]
Message-ID: <5011C2A5.7000401@redhat.com> (raw)
In-Reply-To: <1343227834-5400-9-git-send-email-owasserm@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 5786 bytes --]

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 <benoit.hudzia@sap.com>
> Signed-off-by: Petter Svard <petters@cs.umu.se>
> Signed-off-by: Aidan Shribman <aidan.shribman@sap.com>
> Signed-off-by: Orit Wasserman <owasserm@redhat.com>

> +/* 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.

> +#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.

> +
> +    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.

> @@ -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.

> @@ -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) {

> +        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.

> @@ -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?

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]

  reply	other threads:[~2012-07-26 22:20 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-25 14:50 [Qemu-devel] [PATCH 00/11] Migration next v6 Orit Wasserman
2012-07-25 14:50 ` Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 01/11] Add migration capabilities Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 03/11] Add XBZRLE documentation Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 04/11] Add cache handling functions Orit Wasserman
2012-07-26 21:51   ` Eric Blake
2012-07-29  6:16     ` Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 06/11] Add xbzrle_encode_buffer and xbzrle_decode_buffer functions Orit Wasserman
2012-07-26 21:58   ` Eric Blake
2012-08-15 16:22   ` Igor Mitsyanko
2012-08-15 16:36     ` Eric Blake
2012-07-25 14:50 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
2012-07-26 22:20   ` Eric Blake [this message]
2012-07-29  6:34     ` Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 08/11] Add migrate_set_cachesize command Orit Wasserman
2012-07-26 22:22   ` Eric Blake
2012-07-25 14:50 ` [Qemu-devel] [PATCH 09/11] Add migration accounting for normal and duplicate pages Orit Wasserman
2012-07-26 22:41   ` Eric Blake
2012-07-29  6:57     ` Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 10/11] Add XBZRLE statistics Orit Wasserman
2012-07-26 22:48   ` Eric Blake
2012-07-29  7:10     ` Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 11/11] Restart optimization on stage3 update version Orit Wasserman
2012-07-25 15:41   ` Vinod, Chegu
2012-07-26  5:03     ` Orit Wasserman
  -- strict thread matches above, loose matches on Subject: below --
2012-08-05  9:13 [Qemu-devel] [PATCH 00/11] Migration next v10 Orit Wasserman
2012-08-05  9:13 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
2012-08-02 12:44 [Qemu-devel] [PATCH 00/11] Migration next v9 Orit Wasserman
2012-08-02 12:44 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
2012-08-01 18:01 [Qemu-devel] [PULL 00/11] Migration next Juan Quintela
2012-08-01 18:01 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Juan Quintela
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
2012-07-29  9:42 [Qemu-devel] [PATCH 00/11] Migration next v7 Orit Wasserman
2012-07-29  9:42 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
2012-07-24 18:19 [Qemu-devel] [PATCH 00/11] Migration next v5 Juan Quintela
2012-07-24 18:19 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Juan Quintela

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5011C2A5.7000401@redhat.com \
    --to=eblake@redhat.com \
    --cc=aidan.shribman@sap.com \
    --cc=aliguori@us.ibm.com \
    --cc=avi@redhat.com \
    --cc=benoit.hudzia@sap.com \
    --cc=blauwirbel@gmail.com \
    --cc=chegu_vinod@hp.com \
    --cc=lcapitulino@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=owasserm@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=petters@cs.umu.se \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=stefanha@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.