From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38209) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aRzBm-0002pN-Kr for qemu-devel@nongnu.org; Sat, 06 Feb 2016 04:29:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aRzBl-0001SW-1h for qemu-devel@nongnu.org; Sat, 06 Feb 2016 04:29:58 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:22492) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aRzBk-0001Re-FT for qemu-devel@nongnu.org; Sat, 06 Feb 2016 04:29:56 -0500 From: zhanghailiang Date: Sat, 6 Feb 2016 17:28:38 +0800 Message-ID: <1454750932-7556-27-git-send-email-zhang.zhanghailiang@huawei.com> In-Reply-To: <1454750932-7556-1-git-send-email-zhang.zhanghailiang@huawei.com> References: <1454750932-7556-1-git-send-email-zhang.zhanghailiang@huawei.com> MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [PATCH COLO-Frame v14 26/40] savevm: Introduce two helper functions for save/find loadvm_handlers entry List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: xiecl.fnst@cn.fujitsu.com, lizhijian@cn.fujitsu.com, quintela@redhat.com, armbru@redhat.com, yunhong.jiang@intel.com, eddie.dong@intel.com, peter.huangpeng@huawei.com, dgilbert@redhat.com, zhanghailiang , arei.gonglei@huawei.com, stefanha@redhat.com, amit.shah@redhat.com, zhangchen.fnst@cn.fujitsu.com, hongyang.yang@easystack.cn For COLO's checkpoint process, we will do savevm/loadvm repeatedly. So every time we call qemu_loadvm_section_start_full(), we will add all sections information into loadvm_handlers list for one time. There will be many instances in loadvm_handlers for one section, and this will lead to memory leak. We need to check if we have the section info in loadvm_handlers list before save it. For normal migration, it is harmless. Signed-off-by: zhanghailiang Reviewed-by: Dr. David Alan Gilbert --- v14: - Add Reviewed-by tag - v13: - New patch --- migration/savevm.c | 56 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/migration/savevm.c b/migration/savevm.c index 00be5fe..48e1615 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1718,6 +1718,37 @@ void loadvm_free_handlers(MigrationIncomingState *mis) } } +static LoadStateEntry *loadvm_save_section_entry(MigrationIncomingState *mis, + SaveStateEntry *se, + uint32_t section_id, + uint32_t version_id) +{ + LoadStateEntry *le; + + /* Add entry */ + le = g_malloc0(sizeof(*le)); + + le->se = se; + le->section_id = section_id; + le->version_id = version_id; + QLIST_INSERT_HEAD(&mis->loadvm_handlers, le, entry); + return le; +} + +static LoadStateEntry *loadvm_find_section_entry(MigrationIncomingState *mis, + uint32_t section_id) +{ + LoadStateEntry *le; + + QLIST_FOREACH(le, &mis->loadvm_handlers, entry) { + if (le->section_id == section_id) { + break; + } + } + + return le; +} + static int qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis) { @@ -1753,16 +1784,12 @@ qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis) version_id, idstr, se->version_id); return -EINVAL; } - - /* Add entry */ - le = g_malloc0(sizeof(*le)); - - le->se = se; - le->section_id = section_id; - le->version_id = version_id; - QLIST_INSERT_HEAD(&mis->loadvm_handlers, le, entry); - - ret = vmstate_load(f, le->se, le->version_id); + /* Check if we have saved this section info before, if not, save it */ + le = loadvm_find_section_entry(mis, section_id); + if (!le) { + le = loadvm_save_section_entry(mis, se, section_id, version_id); + } + ret = vmstate_load(f, se, version_id); if (ret < 0) { error_report("error while loading state for instance 0x%x of" " device '%s'", instance_id, idstr); @@ -1785,12 +1812,9 @@ qemu_loadvm_section_part_end(QEMUFile *f, MigrationIncomingState *mis) section_id = qemu_get_be32(f); trace_qemu_loadvm_state_section_partend(section_id); - QLIST_FOREACH(le, &mis->loadvm_handlers, entry) { - if (le->section_id == section_id) { - break; - } - } - if (le == NULL) { + + le = loadvm_find_section_entry(mis, section_id); + if (!le) { error_report("Unknown savevm section %d", section_id); return -EINVAL; } -- 1.8.3.1