Revision f36d55af

b/arch_init.c
206 206
    uint64_t dup_pages;
207 207
    uint64_t norm_pages;
208 208
    uint64_t iterations;
209
    uint64_t xbzrle_bytes;
210
    uint64_t xbzrle_pages;
211
    uint64_t xbzrle_cache_miss;
212
    uint64_t xbzrle_overflows;
209 213
} AccountingInfo;
210 214

  
211 215
static AccountingInfo acct_info;
......
235 239
    return acct_info.norm_pages;
236 240
}
237 241

  
242
uint64_t xbzrle_mig_bytes_transferred(void)
243
{
244
    return acct_info.xbzrle_bytes;
245
}
246

  
247
uint64_t xbzrle_mig_pages_transferred(void)
248
{
249
    return acct_info.xbzrle_pages;
250
}
251

  
252
uint64_t xbzrle_mig_pages_cache_miss(void)
253
{
254
    return acct_info.xbzrle_cache_miss;
255
}
256

  
257
uint64_t xbzrle_mig_pages_overflow(void)
258
{
259
    return acct_info.xbzrle_overflows;
260
}
261

  
238 262
static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
239 263
        int cont, int flag)
240 264
{
......
259 283
    if (!cache_is_cached(XBZRLE.cache, current_addr)) {
260 284
        cache_insert(XBZRLE.cache, current_addr,
261 285
                     g_memdup(current_data, TARGET_PAGE_SIZE));
286
        acct_info.xbzrle_cache_miss++;
262 287
        return -1;
263 288
    }
264 289

  
......
276 301
        return 0;
277 302
    } else if (encoded_len == -1) {
278 303
        DPRINTF("Overflow\n");
304
        acct_info.xbzrle_overflows++;
279 305
        /* update data in the cache */
280 306
        memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
281 307
        return -1;
......
290 316
    qemu_put_be16(f, encoded_len);
291 317
    qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
292 318
    bytes_sent = encoded_len + 1 + 2;
319
    acct_info.xbzrle_pages++;
320
    acct_info.xbzrle_bytes += bytes_sent;
293 321

  
294 322
    return bytes_sent;
295 323
}
b/hmp.c
177 177
                       info->disk->total >> 10);
178 178
    }
179 179

  
180
    if (info->has_xbzrle_cache) {
181
        monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
182
                       info->xbzrle_cache->cache_size);
183
        monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
184
                       info->xbzrle_cache->bytes >> 10);
185
        monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
186
                       info->xbzrle_cache->pages);
187
        monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
188
                       info->xbzrle_cache->cache_miss);
189
        monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
190
                       info->xbzrle_cache->overflow);
191
    }
192

  
180 193
    qapi_free_MigrationInfo(info);
181 194
    qapi_free_MigrationCapabilityStatusList(caps);
182 195
}
b/migration.c
141 141
    return head;
142 142
}
143 143

  
144
static void get_xbzrle_cache_stats(MigrationInfo *info)
145
{
146
    if (migrate_use_xbzrle()) {
147
        info->has_xbzrle_cache = true;
148
        info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache));
149
        info->xbzrle_cache->cache_size = migrate_xbzrle_cache_size();
150
        info->xbzrle_cache->bytes = xbzrle_mig_bytes_transferred();
151
        info->xbzrle_cache->pages = xbzrle_mig_pages_transferred();
152
        info->xbzrle_cache->cache_miss = xbzrle_mig_pages_cache_miss();
153
        info->xbzrle_cache->overflow = xbzrle_mig_pages_overflow();
154
    }
155
}
156

  
144 157
MigrationInfo *qmp_query_migrate(Error **errp)
145 158
{
146 159
    MigrationInfo *info = g_malloc0(sizeof(*info));
......
172 185
            info->disk->remaining = blk_mig_bytes_remaining();
173 186
            info->disk->total = blk_mig_bytes_total();
174 187
        }
188

  
189
        get_xbzrle_cache_stats(info);
175 190
        break;
176 191
    case MIG_STATE_COMPLETED:
192
        get_xbzrle_cache_stats(info);
193

  
177 194
        info->has_status = true;
178 195
        info->status = g_strdup("completed");
179 196

  
b/migration.h
91 91
uint64_t dup_mig_pages_transferred(void);
92 92
uint64_t norm_mig_bytes_transferred(void);
93 93
uint64_t norm_mig_pages_transferred(void);
94
uint64_t xbzrle_mig_bytes_transferred(void);
95
uint64_t xbzrle_mig_pages_transferred(void);
96
uint64_t xbzrle_mig_pages_overflow(void);
97
uint64_t xbzrle_mig_pages_cache_miss(void);
94 98

  
95 99
/**
96 100
 * @migrate_add_blocker - prevent migration from proceeding
b/qapi-schema.json
278 278
           'normal-bytes': 'int' } }
279 279

  
280 280
##
281
# @XBZRLECacheStats
282
#
283
# Detailed XBZRLE migration cache statistics
284
#
285
# @cache-size: XBZRLE cache size
286
#
287
# @bytes: amount of bytes already transferred to the target VM
288
#
289
# @pages: amount of pages transferred to the target VM
290
#
291
# @cache-miss: number of cache miss
292
#
293
# @overflow: number of overflows
294
#
295
# Since: 1.2
296
##
297
{ 'type': 'XBZRLECacheStats',
298
  'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',
299
           'cache-miss': 'int', 'overflow': 'int' } }
300

  
301
##
281 302
# @MigrationInfo
282 303
#
283 304
# Information about current migration process.
......
295 316
#        status, only returned if status is 'active' and it is a block
296 317
#        migration
297 318
#
319
# @xbzrle-cache: #optional @XBZRLECacheStats containing detailed XBZRLE
320
#                migration statistics, only returned if XBZRLE feature is on and
321
#                status is 'active' or 'completed' (since 1.2)
322
#
298 323
# Since: 0.14.0
299 324
##
300 325
{ 'type': 'MigrationInfo',
301 326
  'data': {'*status': 'str', '*ram': 'MigrationStats',
302
           '*disk': 'MigrationStats'} }
327
           '*disk': 'MigrationStats',
328
           '*xbzrle-cache': 'XBZRLECacheStats'} }
303 329

  
304 330
##
305 331
# @query-migrate
b/qmp-commands.hx
2133 2133
         - "transferred": amount transferred (json-int)
2134 2134
         - "remaining": amount remaining (json-int)
2135 2135
         - "total": total (json-int)
2136

  
2136
- "xbzrle-cache": only present if XBZRLE is active.
2137
  It is a json-object with the following XBZRLE information:
2138
         - "cache-size": XBZRLE cache size
2139
         - "bytes": total XBZRLE bytes transferred
2140
         - "pages": number of XBZRLE compressed pages
2141
         - "cache-miss": number of cache misses
2142
         - "overflow": number of XBZRLE overflows
2137 2143
Examples:
2138 2144

  
2139 2145
1. Before the first migration
......
2204 2210
      }
2205 2211
   }
2206 2212

  
2213
6. Migration is being performed and XBZRLE is active:
2214

  
2215
-> { "execute": "query-migrate" }
2216
<- {
2217
      "return":{
2218
         "status":"active",
2219
         "capabilities" : [ { "capability": "xbzrle", "state" : true } ],
2220
         "ram":{
2221
            "total":1057024,
2222
            "remaining":1053304,
2223
            "transferred":3720,
2224
            "total-time":12345,
2225
            "duplicate":10,
2226
            "normal":3333,
2227
            "normal-bytes":3412992
2228
         },
2229
         "xbzrle-cache":{
2230
            "cache-size":67108864,
2231
            "bytes":20971520,
2232
            "pages":2444343,
2233
            "cache-miss":2244,
2234
            "overflow":34434
2235
         }
2236
      }
2237
   }
2238

  
2207 2239
EQMP
2208 2240

  
2209 2241
    {

Also available in: Unified diff