Commit e68cba36 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/amit-migration/tags/mig-2.3-1' into staging



A set of patches collected over the holidays.  Mix of optimizations and
fixes.

# gpg: Signature made Fri 16 Jan 2015 07:42:00 GMT using RSA key ID 854083B6
# gpg: Good signature from "Amit Shah <amit@amitshah.net>"
# gpg:                 aka "Amit Shah <amit@kernel.org>"
# gpg:                 aka "Amit Shah <amitshah@gmx.net>"

* remotes/amit-migration/tags/mig-2.3-1:
  vmstate: type-check sub-arrays
  migration_cancel: shutdown migration socket
  Handle bi-directional communication for fd migration
  socket shutdown
  Tests: QEMUSizedBuffer/QEMUBuffer
  QEMUSizedBuffer: only free qsb that qemu_bufopen allocated
  xbzrle: rebuild the cache_is_cached function
  xbzrle: optimize XBZRLE to decrease the cache misses

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents df58887b ea987c2c
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -346,7 +346,8 @@ static void xbzrle_cache_zero_page(ram_addr_t current_addr)

    /* We don't care if this fails to allocate a new cache page
     * as long as it updated an old one */
    cache_insert(XBZRLE.cache, current_addr, ZERO_TARGET_PAGE);
    cache_insert(XBZRLE.cache, current_addr, ZERO_TARGET_PAGE,
                 bitmap_sync_count);
}

#define ENCODING_FLAG_XBZRLE 0x1
@@ -358,10 +359,11 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t **current_data,
    int encoded_len = 0, bytes_sent = -1;
    uint8_t *prev_cached_page;

    if (!cache_is_cached(XBZRLE.cache, current_addr)) {
    if (!cache_is_cached(XBZRLE.cache, current_addr, bitmap_sync_count)) {
        acct_info.xbzrle_cache_miss++;
        if (!last_stage) {
            if (cache_insert(XBZRLE.cache, current_addr, *current_data) == -1) {
            if (cache_insert(XBZRLE.cache, current_addr, *current_data,
                             bitmap_sync_count) == -1) {
                return -1;
            } else {
                /* update *current_data when the page has been
+8 −0
Original line number Diff line number Diff line
@@ -71,6 +71,14 @@ encoded buffer:
encoded length 24
e9 07 0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 03 01 67 01 01 69

Cache update strategy
=====================
Keeping the hot pages in the cache is effective for decreased cache
misses. XBZRLE uses a counter as the age of each page. The counter will
increase after each ram dirty bitmap sync. When a cache conflict is
detected, XBZRLE will only evict pages in the cache that are older than
a threshold.

Usage
======================
1. Verify the destination QEMU version is able to decode the new format.
+7 −3
Original line number Diff line number Diff line
@@ -43,8 +43,10 @@ void cache_fini(PageCache *cache);
 *
 * @cache pointer to the PageCache struct
 * @addr: page addr
 * @current_age: current bitmap generation
 */
bool cache_is_cached(const PageCache *cache, uint64_t addr);
bool cache_is_cached(const PageCache *cache, uint64_t addr,
                     uint64_t current_age);

/**
 * get_cached_data: Get the data cached for an addr
@@ -60,13 +62,15 @@ uint8_t *get_cached_data(const PageCache *cache, uint64_t addr);
 * cache_insert: insert the page into the cache. the page cache
 * will dup the data on insert. the previous value will be overwritten
 *
 * Returns -1 on error
 * Returns -1 when the page isn't inserted into cache
 *
 * @cache pointer to the PageCache struct
 * @addr: page address
 * @pdata: pointer to the page
 * @current_age: current bitmap generation
 */
int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata);
int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata,
                 uint64_t current_age);

/**
 * cache_resize: resize the page cache. In case of size reduction the extra
+10 −0
Original line number Diff line number Diff line
@@ -84,6 +84,14 @@ typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque,
                               size_t size,
                               int *bytes_sent);

/*
 * Stop any read or write (depending on flags) on the underlying
 * transport on the QEMUFile.
 * Existing blocking reads/writes must be woken
 * Returns 0 on success, -err on error
 */
typedef int (QEMUFileShutdownFunc)(void *opaque, bool rd, bool wr);

typedef struct QEMUFileOps {
    QEMUFilePutBufferFunc *put_buffer;
    QEMUFileGetBufferFunc *get_buffer;
@@ -94,6 +102,7 @@ typedef struct QEMUFileOps {
    QEMURamHookFunc *after_ram_iterate;
    QEMURamHookFunc *hook_ram_load;
    QEMURamSaveFunc *save_page;
    QEMUFileShutdownFunc *shut_down;
} QEMUFileOps;

struct QEMUSizedBuffer {
@@ -177,6 +186,7 @@ void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
int64_t qemu_file_get_rate_limit(QEMUFile *f);
int qemu_file_get_error(QEMUFile *f);
void qemu_file_set_error(QEMUFile *f, int ret);
int qemu_file_shutdown(QEMUFile *f);
void qemu_fflush(QEMUFile *f);

static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
+1 −1
Original line number Diff line number Diff line
@@ -189,7 +189,7 @@ extern const VMStateInfo vmstate_info_bitmap;
     type_check_2darray(_type, typeof_field(_state, _field), _n1, _n2))

#define vmstate_offset_sub_array(_state, _field, _type, _start)      \
    (offsetof(_state, _field[_start]))
    vmstate_offset_value(_state, _field[_start], _type)

#define vmstate_offset_buffer(_state, _field)                        \
    vmstate_offset_array(_state, _field, uint8_t,                    \
Loading