From patchwork Fri Jun 5 15:15:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 481393 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 370231401DE for ; Sat, 6 Jun 2015 01:23:02 +1000 (AEST) Received: from localhost ([::1]:48020 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0tSW-0000uv-9n for incoming@patchwork.ozlabs.org; Fri, 05 Jun 2015 11:23:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59365) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0tML-0002Jt-Io for qemu-devel@nongnu.org; Fri, 05 Jun 2015 11:16:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z0tMI-00085T-GC for qemu-devel@nongnu.org; Fri, 05 Jun 2015 11:16:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39702) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0tMI-00085L-2u for qemu-devel@nongnu.org; Fri, 05 Jun 2015 11:16:34 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id CABD23620B8 for ; Fri, 5 Jun 2015 15:16:33 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-29.ams2.redhat.com [10.36.112.29]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t55FG4kS012808 for ; Fri, 5 Jun 2015 11:16:32 -0400 From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 5 Jun 2015 17:15:17 +0200 Message-Id: <1433517363-32335-17-git-send-email-pbonzini@redhat.com> In-Reply-To: <1433517363-32335-1-git-send-email-pbonzini@redhat.com> References: <1433517363-32335-1-git-send-email-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 16/62] memory: include DIRTY_MEMORY_MIGRATION in the dirty log mask X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The separate handling of DIRTY_MEMORY_MIGRATION, which does not call log_start/log_stop callbacks when it changes in a region's dirty logging mask, has caused several bugs. One recent example is commit 4cc856f (kvm-all: Sync dirty-bitmap from kvm before kvm destroy the corresponding dirty_bitmap, 2015-04-02). Another performance problem is that KVM keeps tracking dirty pages after a failed live migration, which causes bad performance due to disallowing huge page mapping. This patch removes the root cause of the problem by reporting DIRTY_MEMORY_MIGRATION changes via log_start and log_stop. Note that we now have to rebuild the FlatView when global dirty logging is enabled or disabled; this ensures that log_start and log_stop callbacks are invoked. This will also be used to make the setting of bitmaps conditional. In general, this patch lets users of the memory API ignore the global state of dirty logging if they handle dirty logging generically per region. Reviewed-by: Fam Zheng Signed-off-by: Paolo Bonzini --- memory.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/memory.c b/memory.c index 47cc181..b7ca987 100644 --- a/memory.c +++ b/memory.c @@ -588,7 +588,7 @@ static void render_memory_region(FlatView *view, remain = clip.size; fr.mr = mr; - fr.dirty_log_mask = mr->dirty_log_mask; + fr.dirty_log_mask = memory_region_get_dirty_log_mask(mr); fr.romd_mode = mr->romd_mode; fr.readonly = readonly; @@ -1400,7 +1400,11 @@ bool memory_region_is_skip_dump(MemoryRegion *mr) uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr) { - return mr->dirty_log_mask; + uint8_t mask = mr->dirty_log_mask; + if (global_dirty_log) { + mask |= (1 << DIRTY_MEMORY_MIGRATION); + } + return mask; } bool memory_region_is_logging(MemoryRegion *mr, uint8_t client) @@ -1962,12 +1966,24 @@ void address_space_sync_dirty_bitmap(AddressSpace *as) void memory_global_dirty_log_start(void) { global_dirty_log = true; + MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward); + + /* Refresh DIRTY_LOG_MIGRATION bit. */ + memory_region_transaction_begin(); + memory_region_update_pending = true; + memory_region_transaction_commit(); } void memory_global_dirty_log_stop(void) { global_dirty_log = false; + + /* Refresh DIRTY_LOG_MIGRATION bit. */ + memory_region_transaction_begin(); + memory_region_update_pending = true; + memory_region_transaction_commit(); + MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse); }