From patchwork Wed Aug 27 08:09:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tang Chen X-Patchwork-Id: 383375 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 733FA140093 for ; Wed, 27 Aug 2014 18:14:39 +1000 (EST) Received: from localhost ([::1]:58170 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMYNJ-0003Pi-GR for incoming@patchwork.ozlabs.org; Wed, 27 Aug 2014 04:14:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35855) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMYI2-0003AR-0N for qemu-devel@nongnu.org; Wed, 27 Aug 2014 04:09:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XMYHv-00032M-6W for qemu-devel@nongnu.org; Wed, 27 Aug 2014 04:09:09 -0400 Received: from [59.151.112.132] (port=62031 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMYHu-00032B-IR for qemu-devel@nongnu.org; Wed, 27 Aug 2014 04:09:03 -0400 X-IronPort-AV: E=Sophos;i="5.04,409,1406563200"; d="scan'208";a="35133151" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 27 Aug 2014 16:06:07 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (localhost.localdomain [127.0.0.1]) by edo.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id s7R88xY6000522; Wed, 27 Aug 2014 16:08:59 +0800 Received: from tangchen.fnst.cn.fujitsu.com (10.167.226.71) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Wed, 27 Aug 2014 16:09:05 +0800 From: Tang Chen To: , , , Date: Wed, 27 Aug 2014 16:09:47 +0800 Message-ID: <1409126988-22287-4-git-send-email-tangchen@cn.fujitsu.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1409126988-22287-1-git-send-email-tangchen@cn.fujitsu.com> References: <1409126988-22287-1-git-send-email-tangchen@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.71] X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 59.151.112.132 Cc: hutao@cn.fujitsu.com, isimatu.yasuaki@jp.fujitsu.com, zhugh.fnst@cn.fujitsu.com, tangchen@cn.fujitsu.com Subject: [Qemu-devel] [RFC PATCH v1 3/4] Introduce wait condition to catch guest OS memory hotplug error. 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 When acpi_memory_plug_cb() sends a SCI to guest OS, vcpu thread will handle it. And QEmu thread will return, who is not able to catch the error if guest OS failed to handle the SCI. Of course, if guest OS failed to handle SCI, it will give error messages. But QEmu will not output anything. Furthermore, if QEmu cannot catch these errors, applications based on QEmu, like Libvirt, will also not able to catch them. This could be trouble to end users. This patch introduces a condition variable named qemu_cond_memhp. QEmu will wait on qemu_cond_memhp after sending SCI, and vcpu thread will signal QEmu when OST status is written into ACPI register. This is used by the following patch. Signed-off-by: Tang Chen --- hw/acpi/memory_hotplug.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index fddb0fd..38d9654 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -4,6 +4,12 @@ #include "hw/boards.h" #include "trace.h" #include "qapi-event.h" +#include "qemu/thread.h" +#include "qemu/main-loop.h" + +/* _OST called by guest OS */ +static QemuCond qemu_memhp_cond; +static QemuMutex qemu_memhp_mutex; static ACPIOSTInfo *acpi_memory_device_status(int slot, MemStatus *mdev) { @@ -93,6 +99,8 @@ static void acpi_handle_insert(MemStatus *mdev) case ACPI_UNRECOGNIZED_NOTIFY: case ACPI_INSERT_DRIVER_LOAD_FAILURE: case ACPI_INSERT_NOT_SUPPORTED: + /* Signal QEmu to continue.*/ + qemu_cond_signal(&qemu_memhp_cond); case ACPI_INSERT_IN_PROGRESS: default: break; @@ -106,6 +114,9 @@ static void acpi_handle_eject(MemStatus *mdev) object_unparent(OBJECT(mdev->dimm)); mdev->is_removing = false; mdev->dimm = NULL; + + /* Signal QEmu to continue.*/ + qemu_cond_signal(&qemu_memhp_cond); break; case ACPI_EJECT_IN_PROGRESS: /* For ejection triggered by hardware (device_del command), @@ -126,6 +137,9 @@ static void acpi_handle_eject(MemStatus *mdev) case ACPI_EJECT_DEPENDENCY_BUSY: mdev->is_removing = false; mdev->is_enabled = true; + + /* Signal QEmu to catch errors. */ + qemu_cond_signal(&qemu_memhp_cond); break; default: break; @@ -181,12 +195,16 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, /* TODO: handle device remove OST event */ break; } + qemu_mutex_lock(&qemu_memhp_mutex); mdev->ost_event = data; + qemu_mutex_unlock(&qemu_memhp_mutex); trace_mhp_acpi_write_ost_ev(mem_st->selector, mdev->ost_event); break; case 0x8: /* _OST status */ mdev = &mem_st->devs[mem_st->selector]; + qemu_mutex_lock(&qemu_memhp_mutex); mdev->ost_status = data; + qemu_mutex_unlock(&qemu_memhp_mutex); trace_mhp_acpi_write_ost_status(mem_st->selector, mdev->ost_status); info = acpi_memory_device_status(mem_st->selector, mdev); @@ -234,6 +252,9 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state, "acpi-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN); memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io); + + qemu_cond_init(&qemu_memhp_cond); + qemu_mutex_init(&qemu_memhp_mutex); } void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, @@ -265,6 +286,23 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, /* do ACPI magic */ ar->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS; acpi_update_sci(ar, irq); + + /* When SCI is sent, wait for guest OS handling and catch errors. + * + * QEmu locked all the iothreads before handling monitor command in + * os_host_main_loop_wait(). Unlock them so that vcpu threads are able + * to handle ACPI register writing requests from guest OS. And relock + * them after we are signaled. + */ + qemu_mutex_unlock_iothread(); + qemu_mutex_lock(&qemu_memhp_mutex); + /* qemu_cond_wait() will release qemu_memhp_mutex and wait, + * and will relock it when signaled. + */ + qemu_cond_wait(&qemu_memhp_cond, &qemu_memhp_mutex); + qemu_mutex_unlock(&qemu_memhp_mutex); + qemu_mutex_lock_iothread(); + return; }