From patchwork Wed Aug 27 08:09:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tang Chen X-Patchwork-Id: 383373 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 8256F1400D2 for ; Wed, 27 Aug 2014 18:12:33 +1000 (EST) Received: from localhost ([::1]:58120 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMYLH-0008IG-Ke for incoming@patchwork.ozlabs.org; Wed, 27 Aug 2014 04:12:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35880) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMYI4-0003FH-AR for qemu-devel@nongnu.org; Wed, 27 Aug 2014 04:09:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XMYHz-00032s-HT for qemu-devel@nongnu.org; Wed, 27 Aug 2014 04:09:12 -0400 Received: from [59.151.112.132] (port=3041 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMYHy-00032a-T6 for qemu-devel@nongnu.org; Wed, 27 Aug 2014 04:09:07 -0400 X-IronPort-AV: E=Sophos;i="5.04,409,1406563200"; d="scan'208";a="35133161" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 27 Aug 2014 16:06:10 +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 s7R892cq000537; Wed, 27 Aug 2014 16:09:02 +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:09 +0800 From: Tang Chen To: , , , Date: Wed, 27 Aug 2014 16:09:48 +0800 Message-ID: <1409126988-22287-5-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 4/4] Handle memory hotplug error from guest OS in QEmu. 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 Before this patch, QEmu is not aware of guest OS error when hotplugging memory devices. Even if guest OS failed to hot-add memory, the pc-dimm device will be added to QEmu. Even if guest OS failed to hot-remove memory, QEmu will remove the pc-dimm device. For example, for a Linux guest, the Linux kernel limited that the size of hot-added memory should be mutiple of memory section (128MB by default). If we add 130MB memory, the Linux kernel won't add it. We are not able to handle the size check in QEmu commmand line because different OS may have different limits. And also, QEmu outputs nothing but guest OS failed to hot-add memory will confuse users. We should at least report an error. So, we should report the error to users, and cancel the memory hotplug progress in QEmu. Since after previous patch, QEmu will wait on qemu_cond_memhp after sending SCI, and will be signaled by vcpu thread after OST status is written to ACPI register, this patch checks OST status, and report an error to users, and cancel hotplug progress if necessary. Signed-off-by: Tang Chen --- hw/acpi/memory_hotplug.c | 83 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 38d9654..59917c3 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -257,25 +257,95 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, qemu_mutex_init(&qemu_memhp_mutex); } +static void acpi_handle_memory_insert_error(MemStatus *mdev, char *dev_path, + Error **errp) +{ + switch (mdev->ost_status) { + case ACPI_FAILURE: + error_setg(errp, "Failed to insert device [%s]", dev_path); + break; + case ACPI_UNRECOGNIZED_NOTIFY: + error_setg(errp, "Unrecongnized notification"); + break; + case ACPI_INSERT_DRIVER_LOAD_FAILURE: + error_setg(errp, "Failed to load driver for device [%s]", dev_path); + break; + case ACPI_INSERT_NOT_SUPPORTED: + error_setg(errp, "Insertion is not supported for device [%s]", + dev_path); + break; + default: + error_setg(errp, "Unknown error on insertion of device [%s]", dev_path); + break; + } +} + +static void acpi_handle_memory_eject_error(MemStatus *mdev, char *dev_path, + Error **errp) +{ + switch (mdev->ost_status) { + case ACPI_FAILURE: + error_setg(errp, "Failed to eject device [%s]", dev_path); + break; + case ACPI_UNRECOGNIZED_NOTIFY: + error_setg(errp, "Unrecongnized notification"); + break; + case ACPI_EJECT_DEVICE_IN_USE: + case ACPI_EJECT_DEVICE_BUSY: + error_setg(errp, "Device [%s] is busy", dev_path); + break; + case ACPI_EJECT_DEPENDENCY_BUSY: + error_setg(errp, "Ejection dependency is busy or not supported" + " for device [%s]", dev_path); + break; + case ACPI_EJECT_NOT_SUPPORTED: + error_setg(errp, "Ejection is not supported for device [%s]", + dev_path); + break; + default: + error_setg(errp, "Unknown error on ejection of device [%s]", dev_path); + break; + } +} + +static void acpi_handle_memory_error(MemStatus *mdev, char *dev_path, + Error **errp) +{ + if (mdev->ost_status == ACPI_SUCCESS) + return; + + switch (mdev->ost_event) { + case ACPI_NOTIFY_DEVICE_CHECK: + case ACPI_OSPM_INSERT: + acpi_handle_memory_insert_error(mdev, dev_path, errp); + break; + case ACPI_NOTIFY_EJECT_REQUEST: + case ACPI_OSPM_EJECT: + acpi_handle_memory_eject_error(mdev, dev_path, errp); + break; + default: + break; + } +} + void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, DeviceState *dev, Error **errp) { MemStatus *mdev; Error *local_err = NULL; int slot = object_property_get_int(OBJECT(dev), "slot", &local_err); + char *dev_path = object_get_canonical_path(OBJECT(dev)); if (local_err) { error_propagate(errp, local_err); - return; + goto ret; } if (slot >= mem_st->dev_count) { - char *dev_path = object_get_canonical_path(OBJECT(dev)); error_setg(errp, "acpi_memory_plug_cb: " "device [%s] returned invalid memory slot[%d]", dev_path, slot); - g_free(dev_path); - return; + goto ret; } mdev = &mem_st->devs[slot]; @@ -300,9 +370,14 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, * and will relock it when signaled. */ qemu_cond_wait(&qemu_memhp_cond, &qemu_memhp_mutex); + + acpi_handle_memory_error(mdev, dev_path, errp); + qemu_mutex_unlock(&qemu_memhp_mutex); qemu_mutex_lock_iothread(); +ret: + g_free(dev_path); return; }