From patchwork Mon Nov 30 11:32:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 549953 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 E2BFB140187 for ; Mon, 30 Nov 2015 22:35:40 +1100 (AEDT) Received: from localhost ([::1]:40250 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3Mk6-0003L6-Pt for incoming@patchwork.ozlabs.org; Mon, 30 Nov 2015 06:35:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35465) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3MiQ-0000Ow-W1 for qemu-devel@nongnu.org; Mon, 30 Nov 2015 06:33:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a3MiP-0004vM-Mq for qemu-devel@nongnu.org; Mon, 30 Nov 2015 06:33:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50740) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3MiP-0004vI-FS for qemu-devel@nongnu.org; Mon, 30 Nov 2015 06:33:53 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 3912DC0D2257 for ; Mon, 30 Nov 2015 11:33:53 +0000 (UTC) Received: from pxdev.xzpeter.org.com (vpn1-4-252.pek2.redhat.com [10.72.4.252]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAUBWRiv012457; Mon, 30 Nov 2015 06:33:44 -0500 From: Peter Xu To: qemu-devel@nongnu.org Date: Mon, 30 Nov 2015 19:32:15 +0800 Message-Id: <1448883140-20249-8-git-send-email-peterx@redhat.com> In-Reply-To: <1448883140-20249-1-git-send-email-peterx@redhat.com> References: <1448883140-20249-1-git-send-email-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: drjones@redhat.com, lersek@redhat.com, armbru@redhat.com, peterx@redhat.com, lcapitulino@redhat.com, famz@redhat.com, pbonzini@redhat.com Subject: [Qemu-devel] [PATCH v3 07/12] dump-guest-memory: add "detach" support 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 If "detach" is provided, one thread is created to do the dump work, while main thread will return immediately. For each GuestPhysBlock, adding one more field "mr" to points to MemoryRegion that it belongs, also ref the mr before use. Signed-off-by: Peter Xu --- dump.c | 39 ++++++++++++++++++++++++++++++++------- include/sysemu/dump.h | 1 + include/sysemu/memory_mapping.h | 4 ++++ memory_mapping.c | 3 +++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/dump.c b/dump.c index 5b9def3..14fd41f 100644 --- a/dump.c +++ b/dump.c @@ -1615,6 +1615,28 @@ static void dump_process(DumpState *s, Error **errp) } else { create_vmcore(s, errp); } + + if (*errp) { + s->status = DUMP_STATUS_FAILED; + } else { + s->status = DUMP_STATUS_COMPLETED; + } + + dump_cleanup(s); +} + +static void *dump_thread(void *data) +{ + Error *err = NULL; + DumpState *s = (DumpState *)data; + + dump_process(s, &err); + + if (err) { + /* TODO: notify user the error */ + error_free(err); + } + return NULL; } void qmp_dump_guest_memory(bool paging, const char *file, @@ -1627,6 +1649,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, int fd = -1; DumpState *s; Error *local_err = NULL; + bool detach_p = false; if (runstate_check(RUN_STATE_INMIGRATE)) { error_setg(errp, "Dump not allowed during incoming migration."); @@ -1657,6 +1680,9 @@ void qmp_dump_guest_memory(bool paging, const char *file, error_setg(errp, QERR_MISSING_PARAMETER, "begin"); return; } + if (has_detach) { + detach_p = detach; + } /* check whether lzo/snappy is supported */ #ifndef CONFIG_LZO @@ -1706,15 +1732,14 @@ void qmp_dump_guest_memory(bool paging, const char *file, return; } - dump_process(s, errp); - - if (*errp) { - s->status = DUMP_STATUS_FAILED; + if (detach_p) { + /* detached dump */ + qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread, + s, QEMU_THREAD_DETACHED); } else { - s->status = DUMP_STATUS_COMPLETED; + /* sync dump */ + dump_process(s, errp); } - - dump_cleanup(s); } DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp) diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index d6f4a9c..31930c6 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -188,6 +188,7 @@ typedef struct DumpState { bool has_format; /* whether format is provided */ DumpGuestMemoryFormat format; /* valid only if has_format == true */ + QemuThread dump_thread; /* thread for detached dump */ } DumpState; uint16_t cpu_to_dump16(DumpState *s, uint16_t val); diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h index a75d59a..d46d879 100644 --- a/include/sysemu/memory_mapping.h +++ b/include/sysemu/memory_mapping.h @@ -16,6 +16,7 @@ #include "qemu/queue.h" #include "qemu/typedefs.h" +#include "exec/memory.h" typedef struct GuestPhysBlock { /* visible to guest, reflects PCI hole, etc */ @@ -27,6 +28,9 @@ typedef struct GuestPhysBlock { /* points into host memory */ uint8_t *host_addr; + /* points to the MemoryRegion that this block belongs to */ + MemoryRegion *mr; + QTAILQ_ENTRY(GuestPhysBlock) next; } GuestPhysBlock; diff --git a/memory_mapping.c b/memory_mapping.c index 36d6b26..f4f0622 100644 --- a/memory_mapping.c +++ b/memory_mapping.c @@ -177,6 +177,7 @@ void guest_phys_blocks_free(GuestPhysBlockList *list) QTAILQ_FOREACH_SAFE(p, &list->head, next, q) { QTAILQ_REMOVE(&list->head, p, next); + memory_region_unref(p->mr); g_free(p); } list->num = 0; @@ -240,6 +241,8 @@ static void guest_phys_blocks_region_add(MemoryListener *listener, block->target_start = target_start; block->target_end = target_end; block->host_addr = host_addr; + block->mr = section->mr; + memory_region_ref(section->mr); QTAILQ_INSERT_TAIL(&g->list->head, block, next); ++g->list->num;