From patchwork Tue Dec 18 12:41:54 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vasilis Liaskovitis X-Patchwork-Id: 207123 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 75BC22C0085 for ; Wed, 19 Dec 2012 00:59:58 +1100 (EST) Received: from localhost ([::1]:58477 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkwWb-0001UJ-PT for incoming@patchwork.ozlabs.org; Tue, 18 Dec 2012 07:43:57 -0500 Received: from eggs.gnu.org ([208.118.235.92]:46427) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkwVi-0000OB-4o for qemu-devel@nongnu.org; Tue, 18 Dec 2012 07:43:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TkwVd-00008l-Fn for qemu-devel@nongnu.org; Tue, 18 Dec 2012 07:43:02 -0500 Received: from mail-bk0-f47.google.com ([209.85.214.47]:61659) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TkwVd-00008d-5H for qemu-devel@nongnu.org; Tue, 18 Dec 2012 07:42:57 -0500 Received: by mail-bk0-f47.google.com with SMTP id j4so284953bkw.20 for ; Tue, 18 Dec 2012 04:42:56 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=8yb2dHqBEwv2eZkjuZBDaVOhMlOYiG6dObxeHhANZv4=; b=aI+uGaypRaYHOcxQjAX3IUUu6x+Y8kpz7I6GvbroiSKB3M/i23ndOBrg1d0AtrGsov krqoJyekVzutxi7/n4hrSaCT5ecrZ4ziqNUgZEu/Cmd828TIFhtstqjQwD99GHyaVbWx PQCGAETpXVwdvCxAuahtaL/U3gKbE+/Ixj4wuFqmA4sD0BqWqHIPsgWIqifPT2RuThB3 bmKuq1tsaewDbdsO+u6+tICWLiF+bJLtx6huypdS28fFVHUlOed8a9QwZH5OCBN2CNvd s9tJDSDi6kkhgoem0u26vVc8QrHGkPs92dBpGfmNcKhNJzip3uqCajIX6HWf+HVjuCpX 3DxQ== X-Received: by 10.204.147.8 with SMTP id j8mr673347bkv.105.1355834576079; Tue, 18 Dec 2012 04:42:56 -0800 (PST) Received: from dhcp-192-168-178-175.ri.profitbricks.localdomain ([62.217.45.26]) by mx.google.com with ESMTPS id f24sm1169954bkv.7.2012.12.18.04.42.53 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 18 Dec 2012 04:42:55 -0800 (PST) From: Vasilis Liaskovitis To: qemu-devel@nongnu.org, seabios@seabios.org Date: Tue, 18 Dec 2012 13:41:54 +0100 Message-Id: <1355834518-17989-27-git-send-email-vasilis.liaskovitis@profitbricks.com> X-Mailer: git-send-email 1.7.9 In-Reply-To: <1355834518-17989-1-git-send-email-vasilis.liaskovitis@profitbricks.com> References: <1355834518-17989-1-git-send-email-vasilis.liaskovitis@profitbricks.com> X-Gm-Message-State: ALoCoQnnUPisQMwsXEkwfBybQRK1/ruCD2CNv+GKdtc+Oa1sXlOkD5YCRTCHCZovh7ovOSXrDFF9 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.214.47 Cc: Vasilis Liaskovitis , pingfank@linux.vnet.ibm.com, gleb@redhat.com, stefanha@gmail.com, jbaron@redhat.com, blauwirbel@gmail.com, kevin@koconnor.net, kraxel@redhat.com, anthony@codemonkey.ws Subject: [Qemu-devel] [RFC PATCH v4 26/30] Implement qmp and hmp commands for notification lists 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 Guest can respond to ACPI hotplug events e.g. with _EJ or _OST method. This patch implements a tail queue to store guest notifications for memory hot-add and hot-remove requests. Guest responses for memory hotplug command on a per-dimm basis can be detected with the new hmp command "info memory-hotplug" or the new qmp command "query-memory-hotplug" Examples: (qemu) device_add dimm,id=ram0 (qemu) info memory-hotplug dimm: ram0 hot-add success or dimm: ram0 hot-add failure (qemu) device_del ram3 (qemu) info memory-hotplug dimm: ram3 hot-remove success or dimm: ram3 hot-remove failure Results are removed from the queue once read. This patch only queues _EJ events that signal hot-remove success. For _OST event queuing, which cover the hot-remove failure and hot-add success/failure cases, the _OST patches in this series are are also needed. These notification items should probably be part of migration state (not yet implemented). Signed-off-by: Vasilis Liaskovitis --- hmp-commands.hx | 2 + hmp.c | 17 +++++++++++++++ hmp.h | 1 + hw/dimm.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/dimm.h | 1 + monitor.c | 7 ++++++ qapi-schema.json | 26 +++++++++++++++++++++++ qmp-commands.hx | 37 ++++++++++++++++++++++++++++++++ 8 files changed, 152 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 65d799e..b94b7a2 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1574,6 +1574,8 @@ show roms show memory-total @item info dimm show dimm +@item info memory-hotplug +show memory-hotplug @end table ETEXI diff --git a/hmp.c b/hmp.c index f8456fd..727ed80 100644 --- a/hmp.c +++ b/hmp.c @@ -652,6 +652,23 @@ void hmp_info_dimm(Monitor *mon) qapi_free_DimmInfoList(info); } +void hmp_info_memory_hotplug(Monitor *mon) +{ + MemHpInfoList *info; + MemHpInfoList *item; + MemHpInfo *dimm; + + info = qmp_query_memory_hotplug(NULL); + for (item = info; item; item = item->next) { + dimm = item->value; + monitor_printf(mon, "dimm: %s %s %s\n", dimm->dimm, + dimm->request, dimm->result); + dimm->dimm = NULL; + } + + qapi_free_MemHpInfoList(info); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index 74ac061..92095df 100644 --- a/hmp.h +++ b/hmp.h @@ -38,6 +38,7 @@ void hmp_info_pci(Monitor *mon); void hmp_info_block_jobs(Monitor *mon); void hmp_info_memory_total(Monitor *mon); void hmp_info_dimm(Monitor *mon); +void hmp_info_memory_hotplug(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/hw/dimm.c b/hw/dimm.c index 0b4e22d..4670ae6 100644 --- a/hw/dimm.c +++ b/hw/dimm.c @@ -67,6 +67,7 @@ static void dimm_bus_initfn(Object *obj) DimmBus *bus = DIMM_BUS(obj); QTAILQ_INIT(&bus->dimmconfig_list); QTAILQ_INIT(&bus->dimmlist); + QTAILQ_INIT(&bus->dimm_hp_result_queue); } static const TypeInfo dimm_bus_info = { @@ -278,6 +279,58 @@ DimmInfoList *qmp_query_dimm_info(Error **errp) return head; } +MemHpInfoList *qmp_query_memory_hotplug(Error **errp) +{ + DimmBus *bus; + MemHpInfoList *head = NULL, *cur_item = NULL, *info; + struct dimm_hp_result *item, *nextitem; + + QLIST_FOREACH(bus, &memory_buses, next) { + QTAILQ_FOREACH_SAFE(item, &bus->dimm_hp_result_queue, next, nextitem) { + + info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->dimm = g_malloc0(sizeof(char) * 32); + info->value->request = g_malloc0(sizeof(char) * 16); + info->value->result = g_malloc0(sizeof(char) * 16); + switch (item->ret) { + case DIMM_REMOVE_SUCCESS: + strcpy(info->value->request, "hot-remove"); + strcpy(info->value->result, "success"); + break; + case DIMM_REMOVE_FAIL: + strcpy(info->value->request, "hot-remove"); + strcpy(info->value->result, "failure"); + break; + case DIMM_ADD_SUCCESS: + strcpy(info->value->request, "hot-add"); + strcpy(info->value->result, "success"); + break; + case DIMM_ADD_FAIL: + strcpy(info->value->request, "hot-add"); + strcpy(info->value->result, "failure"); + break; + default: + break; + } + strcpy(info->value->dimm, item->dimmname); + /* XXX: waiting for the qapi to support GSList */ + if (!cur_item) { + head = cur_item = info; + } else { + cur_item->next = info; + cur_item = info; + } + + /* hotplug notification copied to qmp list, delete original item */ + QTAILQ_REMOVE(&bus->dimm_hp_result_queue, item, next); + g_free(item); + } + } + + return head; +} + static int dimm_init(DeviceState *s) { DimmBus *bus = DIMM_BUS(qdev_get_parent_bus(s)); @@ -311,17 +364,25 @@ void dimm_notify(uint32_t idx, uint32_t event) { DimmBus *bus; DimmDevice *slot; + DimmConfig *slotcfg; + struct dimm_hp_result *result; slot = dimm_find_from_idx(idx); assert(slot != NULL); bus = DIMM_BUS(qdev_get_parent_bus(&slot->qdev)); + result = g_malloc0(sizeof(*result)); + slotcfg = dimmcfg_find_from_name(bus, slot->qdev.id); + result->dimmname = slotcfg->name; + switch (event) { case DIMM_REMOVE_SUCCESS: qdev_unplug_complete((DeviceState *)slot, NULL); QTAILQ_REMOVE(&bus->dimmlist, slot, nextdimm); + QTAILQ_INSERT_TAIL(&bus->dimm_hp_result_queue, result, next); break; default: + g_free(result); break; } } diff --git a/hw/dimm.h b/hw/dimm.h index 86c7cd5..8f9546b 100644 --- a/hw/dimm.h +++ b/hw/dimm.h @@ -69,6 +69,7 @@ typedef struct DimmBus { dimm_hotplug_fn dimm_hotplug; DimmConfiglist dimmconfig_list; QTAILQ_HEAD(Dimmlist, DimmDevice) dimmlist; + QTAILQ_HEAD(dimm_hp_result_head, dimm_hp_result) dimm_hp_result_queue; QLIST_ENTRY(DimmBus) next; } DimmBus; diff --git a/monitor.c b/monitor.c index de1dcf1..40a7b7e 100644 --- a/monitor.c +++ b/monitor.c @@ -2715,6 +2715,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.info = hmp_info_memory_total, }, { + .name = "memory-hotplug", + .args_type = "", + .params = "", + .help = "show memory hotplug status", + .mhandler.info = hmp_info_memory_hotplug, + }, + { .name = "qtree", .args_type = "", .params = "", diff --git a/qapi-schema.json b/qapi-schema.json index 5a20577..d2e9831 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2940,6 +2940,32 @@ { 'command': 'query-dimm-info', 'returns': ['DimmInfo'] } ## +# @MemHpInfo: +# +# Information about status of a memory hotplug command +# +# @dimm: the Dimm associated with the result +# +# @result: the result of the hotplug command +# +# Since: 1.4 +# +## +{ 'type': 'MemHpInfo', + 'data': {'dimm': 'str', 'request': 'str', 'result': 'str'} } + +## +# @query-memory-hotplug: +# +# Returns a list of information about pending hotplug commands +# +# Returns: a list of @MemhpInfo +# +# Since: 1.4 +## +{ 'command': 'query-memory-hotplug', 'returns': ['MemHpInfo'] } + +## # @QKeyCode: # # An enumeration of key name. diff --git a/qmp-commands.hx b/qmp-commands.hx index a99117a..ad0dac7 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2674,3 +2674,40 @@ Example: } EQMP + { + .name = "query-memory-hotplug", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_memory_hotplug + }, +SQMP +query-memory-hotplug +---------- + +Show memory hotplug command notifications. + +Return a json-array. Each DIMM that has a pending notification is represented +by a json-object, which contains: + +- "dimm": Dimm name (json-str) +- "request": type of hot request: hot-add or hot-remove (json-str) +- "result": result of the hotplug request for this Dimm success or failure (json-str) + +Example: + +-> { "execute": "query-memory-hotplug" } +<- { + "return":[ + { + "result": "failure", + "request": "hot-remove", + "dimm": "dimm10" + }, + { + "result": "success", + "request": "hot-add", + "dimm": "dimm3" + } + ] + } + +EQMP