27af7d6ea5
Avoid hot pages being replaced by others to remarkably decrease cache misses Sample results with the test program which quote from xbzrle.txt ran in vm:(migrate bandwidth:1GE and xbzrle cache size 8MB) the test program: include <stdlib.h> include <stdio.h> int main() { char *buf = (char *) calloc(4096, 4096); while (1) { int i; for (i = 0; i < 4096 * 4; i++) { buf[i * 4096 / 4]++; } printf("."); } } before this patch: virsh qemu-monitor-command test_vm '{"execute": "query-migrate"}' {"return":{"expected-downtime":1020,"xbzrle-cache":{"bytes":1108284, "cache-size":8388608,"cache-miss-rate":0.987013,"pages":18297,"overflow":8, "cache-miss":1228737},"status":"active","setup-time":10,"total-time":52398, "ram":{"total":12466991104,"remaining":1695744,"mbps":935.559472, "transferred":5780760580,"dirty-sync-counter":271,"duplicate":2878530, "dirty-pages-rate":29130,"skipped":0,"normal-bytes":5748592640, "normal":1403465}},"id":"libvirt-706"} 18k pages sent compressed in 52 seconds. cache-miss-rate is 98.7%, totally miss. after optimizing: virsh qemu-monitor-command test_vm '{"execute": "query-migrate"}' {"return":{"expected-downtime":2054,"xbzrle-cache":{"bytes":5066763, "cache-size":8388608,"cache-miss-rate":0.485924,"pages":194823,"overflow":0, "cache-miss":210653},"status":"active","setup-time":11,"total-time":18729, "ram":{"total":12466991104,"remaining":3895296,"mbps":937.663549, "transferred":1615042219,"dirty-sync-counter":98,"duplicate":2869840, "dirty-pages-rate":58781,"skipped":0,"normal-bytes":1588404224, "normal":387794}},"id":"libvirt-266"} 194k pages sent compressed in 18 seconds. The value of cache-miss-rate decrease to 48.59%. Signed-off-by: ChenLiang <chenliang88@huawei.com> Signed-off-by: Gonglei <arei.gonglei@huawei.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Amit Shah <amit.shah@redhat.com>
87 lines
2.2 KiB
C
87 lines
2.2 KiB
C
/*
|
|
* Page cache for QEMU
|
|
* The cache is base on a hash of the page address
|
|
*
|
|
* Copyright 2012 Red Hat, Inc. and/or its affiliates
|
|
*
|
|
* Authors:
|
|
* Orit Wasserman <owasserm@redhat.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*
|
|
*/
|
|
|
|
#ifndef PAGE_CACHE_H
|
|
#define PAGE_CACHE_H
|
|
|
|
/* Page cache for storing guest pages */
|
|
typedef struct PageCache PageCache;
|
|
|
|
/**
|
|
* cache_init: Initialize the page cache
|
|
*
|
|
*
|
|
* Returns new allocated cache or NULL on error
|
|
*
|
|
* @cache pointer to the PageCache struct
|
|
* @num_pages: cache maximal number of cached pages
|
|
* @page_size: cache page size
|
|
*/
|
|
PageCache *cache_init(int64_t num_pages, unsigned int page_size);
|
|
|
|
/**
|
|
* cache_fini: free all cache resources
|
|
* @cache pointer to the PageCache struct
|
|
*/
|
|
void cache_fini(PageCache *cache);
|
|
|
|
/**
|
|
* cache_is_cached: Checks to see if the page is cached
|
|
*
|
|
* Returns %true if page is cached
|
|
*
|
|
* @cache pointer to the PageCache struct
|
|
* @addr: page addr
|
|
* @current_age: current bitmap generation
|
|
*/
|
|
bool cache_is_cached(const PageCache *cache, uint64_t addr,
|
|
uint64_t current_age);
|
|
|
|
/**
|
|
* get_cached_data: Get the data cached for an addr
|
|
*
|
|
* Returns pointer to the data cached or NULL if not cached
|
|
*
|
|
* @cache pointer to the PageCache struct
|
|
* @addr: page addr
|
|
*/
|
|
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 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,
|
|
uint64_t current_age);
|
|
|
|
/**
|
|
* cache_resize: resize the page cache. In case of size reduction the extra
|
|
* pages will be freed
|
|
*
|
|
* Returns -1 on error new cache size on success
|
|
*
|
|
* @cache pointer to the PageCache struct
|
|
* @num_pages: new page cache size (in pages)
|
|
*/
|
|
int64_t cache_resize(PageCache *cache, int64_t num_pages);
|
|
|
|
#endif
|