From patchwork Tue Apr 13 09:33:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Izik Eidus X-Patchwork-Id: 50051 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 579C2B7CF7 for ; Tue, 13 Apr 2010 19:29:30 +1000 (EST) Received: from localhost ([127.0.0.1]:41154 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O1cQ7-00088Q-UX for incoming@patchwork.ozlabs.org; Tue, 13 Apr 2010 05:28:35 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O1cPO-00088L-QN for qemu-devel@nongnu.org; Tue, 13 Apr 2010 05:27:50 -0400 Received: from [140.186.70.92] (port=35575 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O1cPE-00087J-7O for qemu-devel@nongnu.org; Tue, 13 Apr 2010 05:27:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O1cNx-0000xy-3Y for qemu-devel@nongnu.org; Tue, 13 Apr 2010 05:26:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58445) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1O1cNw-0000xg-SG for qemu-devel@nongnu.org; Tue, 13 Apr 2010 05:26:21 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o3D9QIRK028269 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 13 Apr 2010 05:26:19 -0400 Received: from localhost (dhcp-1-211.tlv.redhat.com [10.35.1.211]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o3D9QFph021982 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Tue, 13 Apr 2010 05:26:17 -0400 Date: Tue, 13 Apr 2010 12:33:18 +0300 From: Izik Eidus To: qemu-devel@nongnu.org Message-ID: <20100413123318.0f2cd334@redhat.com> Organization: redhat Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Subject: [Qemu-devel] [PATCH] fix migration with large mem X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From f881b371e08760a67bf1f5b992a586c3de600f7a Mon Sep 17 00:00:00 2001 From: Izik Eidus Date: Tue, 13 Apr 2010 12:24:57 +0300 Subject: [PATCH] fix migration with large mem In cases of guests with large mem that have pages that all their bytes content are the same, we will spend alot of time reading the memory from the guest (is_dup_page()) It is happening beacuse ram_save_live() function have limit of how much we can send to the dest but not how much we read from it, and in cases we have many is_dup_page() hits, we might read huge amount of data without updating important stuff like the timers... The guest lose all its repsonsibility and have many softlock ups inside itself. this patch add limit on the size we can read from the guest each iteration. Thanks. Signed-off-by: Izik Eidus Acked-by: Paolo Bonzini --- arch_init.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/arch_init.c b/arch_init.c index cfc03ea..e27b1a0 100644 --- a/arch_init.c +++ b/arch_init.c @@ -88,6 +88,8 @@ const uint32_t arch_type = QEMU_ARCH; #define RAM_SAVE_FLAG_PAGE 0x08 #define RAM_SAVE_FLAG_EOS 0x10 +#define MAX_SAVE_BLOCK_READ 10 * 1024 * 1024 + static int is_dup_page(uint8_t *page, uint8_t ch) { uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch; @@ -175,6 +177,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) uint64_t bytes_transferred_last; double bwidth = 0; uint64_t expected_time = 0; + int data_read = 0; if (stage < 0) { cpu_physical_memory_set_dirty_tracking(0); @@ -205,10 +208,11 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_transferred_last = bytes_transferred; bwidth = qemu_get_clock_ns(rt_clock); - while (!qemu_file_rate_limit(f)) { + while (!qemu_file_rate_limit(f) && data_read < MAX_SAVE_BLOCK_READ) { int ret; ret = ram_save_block(f); + data_read += ret * TARGET_PAGE_SIZE; bytes_transferred += ret * TARGET_PAGE_SIZE; if (ret == 0) { /* no more blocks */ break;