From 0db65d624e0211a43c011579d6607a50d8f06082 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Mon, 25 Feb 2013 19:12:01 +0200 Subject: Fix page_cache leak in cache_resize Signed-off-by: Orit Wasserman Reviewed-by: Peter Maydell Signed-off-by: Juan Quintela --- page_cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'page_cache.c') diff --git a/page_cache.c b/page_cache.c index ba5640bd73..748957bc42 100644 --- a/page_cache.c +++ b/page_cache.c @@ -208,6 +208,7 @@ int64_t cache_resize(PageCache *cache, int64_t new_num_pages) } } + g_free(cache->page_cache); cache->page_cache = new_cache->page_cache; cache->max_num_items = new_cache->max_num_items; cache->num_items = new_cache->num_items; -- cgit v1.2.3 From a0ee2031dbf5f0183412d4b20a30cbfd404616a8 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Mon, 25 Feb 2013 19:12:02 +0200 Subject: Fix cache_resize to keep old entry age Instead of using cache_insert do the update itself Signed-off-by: Orit Wasserman Reviewed-by: Peter Maydell Signed-off-by: Juan Quintela --- page_cache.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'page_cache.c') diff --git a/page_cache.c b/page_cache.c index 748957bc42..e5717d53c9 100644 --- a/page_cache.c +++ b/page_cache.c @@ -192,18 +192,17 @@ int64_t cache_resize(PageCache *cache, int64_t new_num_pages) if (old_it->it_addr != -1) { /* check for collision, if there is, keep MRU page */ new_it = cache_get_by_addr(new_cache, old_it->it_addr); - if (new_it->it_data) { + if (new_it->it_data && new_it->it_age >= old_it->it_age) { /* keep the MRU page */ - if (new_it->it_age >= old_it->it_age) { - g_free(old_it->it_data); - } else { - g_free(new_it->it_data); - new_it->it_data = old_it->it_data; - new_it->it_age = old_it->it_age; - new_it->it_addr = old_it->it_addr; - } + g_free(old_it->it_data); } else { - cache_insert(new_cache, old_it->it_addr, old_it->it_data); + if (!new_it->it_data) { + new_cache->num_items++; + } + g_free(new_it->it_data); + new_it->it_data = old_it->it_data; + new_it->it_age = old_it->it_age; + new_it->it_addr = old_it->it_addr; } } } -- cgit v1.2.3 From 32a1c08b60a8ac0e63b54a5793a26b5e32b36618 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 25 Feb 2013 19:12:03 +0200 Subject: page_cache: fix memory leak XBZRLE encoded migration introduced a MRU page cache meachnism. Unfortunately, cached items where never freed in case of a collision in the page cache on cache_insert(). This lead to out of memory conditions during XBZRLE migration if the page cache was small and there where a lot of collisions in the cache. Signed-off-by: Peter Lieven Signed-off-by: Orit Wasserman Reviewed-by: Peter Maydell Signed-off-by: Juan Quintela --- page_cache.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'page_cache.c') diff --git a/page_cache.c b/page_cache.c index e5717d53c9..809dadc7eb 100644 --- a/page_cache.c +++ b/page_cache.c @@ -152,6 +152,9 @@ void cache_insert(PageCache *cache, uint64_t addr, uint8_t *pdata) /* actual update of entry */ it = cache_get_by_addr(cache, addr); + /* free old cached data if any */ + g_free(it->it_data); + if (!it->it_data) { cache->num_items++; } -- cgit v1.2.3 From ee0b44aa9d9450e873a761ca2030b2fa3ec52eb0 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 25 Feb 2013 19:12:04 +0200 Subject: page_cache: dup memory on insert The page cache frees all data on finish, on resize and if there is collision on insert. So it should be the caches responsibility to dup the data that is stored in the cache. Signed-off-by: Peter Lieven Signed-off-by: Orit Wasserman Reviewed-by: Peter Maydell Signed-off-by: Juan Quintela --- page_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'page_cache.c') diff --git a/page_cache.c b/page_cache.c index 809dadc7eb..938a79c9ea 100644 --- a/page_cache.c +++ b/page_cache.c @@ -159,7 +159,7 @@ void cache_insert(PageCache *cache, uint64_t addr, uint8_t *pdata) cache->num_items++; } - it->it_data = pdata; + it->it_data = g_memdup(pdata, cache->page_size); it->it_age = ++cache->max_item_age; it->it_addr = addr; } -- cgit v1.2.3