From patchwork Wed Jul 11 10:32:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vasilis Liaskovitis X-Patchwork-Id: 170448 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 65E262C0089 for ; Wed, 11 Jul 2012 22:02:03 +1000 (EST) Received: from localhost ([::1]:42078 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SouEr-0005LP-JD for incoming@patchwork.ozlabs.org; Wed, 11 Jul 2012 06:33:45 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44401) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SouDi-0003pg-SJ for qemu-devel@nongnu.org; Wed, 11 Jul 2012 06:32:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SouDb-0005uq-6Z for qemu-devel@nongnu.org; Wed, 11 Jul 2012 06:32:34 -0400 Received: from mail-bk0-f45.google.com ([209.85.214.45]:52569) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SouDb-0005nz-07 for qemu-devel@nongnu.org; Wed, 11 Jul 2012 06:32:27 -0400 Received: by mail-bk0-f45.google.com with SMTP id ji1so712845bkc.4 for ; Wed, 11 Jul 2012 03:32:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=lRR8b+plJcrY18V3Jk9HsmcSTJ/H6YkjKtGBDYAiAX8=; b=mNy2weJJaJlw+CBBAutvoAWoRmbYHB6XZI+Xxl+yCZaEqzIiVECfagjqxSfDtpickX 2OELeEbqRcENykcSaGqQClXDd0dVxnVW29bIV1o9A42OFFV9AQxT8fTUSuGWkMI6K0d/ bCrmBIqaDyV7sTpSx5YXeewBUBXKMTupprjUP8y3MNAOUn5ZPnXhD1HPwUcjDHlDpoXj CFhV8PwcQLcEDk14NcIcOJmB5KUWHkofHZUuo3NMphAiqn2pG3IN8RrorlJ/VG4Xnl5f nVqTCLLlLk3ZUuYeSvH1/UeaPfIilTceMctRLei3X8YK4wqh9ekho5duxQ6GpaY3kf86 AdEw== Received: by 10.204.157.7 with SMTP id z7mr16814999bkw.14.1342002745783; Wed, 11 Jul 2012 03:32:25 -0700 (PDT) Received: from dhcp-192-168-178-175.ri.profitbricks.localdomain ([62.217.45.26]) by mx.google.com with ESMTPS id e20sm794740bkv.10.2012.07.11.03.32.25 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 11 Jul 2012 03:32:25 -0700 (PDT) From: Vasilis Liaskovitis To: qemu-devel@nongnu.org, kvm@vger.kernel.org, seabios@seabios.org Date: Wed, 11 Jul 2012 12:32:06 +0200 Message-Id: <1342002726-18258-22-git-send-email-vasilis.liaskovitis@profitbricks.com> X-Mailer: git-send-email 1.7.9 In-Reply-To: <1342002726-18258-1-git-send-email-vasilis.liaskovitis@profitbricks.com> References: <1342002726-18258-1-git-send-email-vasilis.liaskovitis@profitbricks.com> X-Gm-Message-State: ALoCoQnsh8POjHuyxQv7FKrwpAmSCz8XW/ld+o7mEm6DKjHh28R1yBlsT/Sehv7DWZq/GWJoWmSr X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.214.45 Cc: gleb@redhat.com, Vasilis Liaskovitis , kevin@koconnor.net, avi@redhat.com, anthony@codemonkey.ws, imammedo@redhat.com Subject: [Qemu-devel] [RFC PATCH v2 21/21] Implement mem_increase, mem_decrease hmp/qmp commands 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 This implements batch monitor operations for hot-add and hot-remove. These are probably better suited for a higher-level management layer, but are useful for testing. Let me know if there is interest for such commands upstream. syntax: mem_increase poolid num will hotplug num dimms from pool poolid. This starts from lowest unpopulated physical memory (dimm) and trying to cover any existing physical holes. syntax: mem_decrease poolid num will hot-unplug num dimms from pool poolid, This starts from highest populated physical memory (dimm). Respective qmp commands are "mem-increase", "mem-decrease". Signed-off-by: Vasilis Liaskovitis --- hmp-commands.hx | 31 ++++++++++++++++ hw/dimm.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/dimm.h | 7 ++++ monitor.c | 10 +++++ monitor.h | 2 + qmp-commands.hx | 40 +++++++++++++++++++++ 6 files changed, 194 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 016062e..e0c1cf4 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -648,6 +648,37 @@ STEXI Hot-add dimm. ETEXI + { + .name = "mem_increase", + .args_type = "pfx:s,num:s", + .params = "pfx num", + .help = "hot-plug num dimms of memory pool pfx", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_dimm_add_range, + }, + +STEXI +@item mem_increase @var{config} +@findex mem_increase + +Hotplug dimms. +ETEXI + + { + .name = "mem_decrease", + .args_type = "pfx:s,num:s", + .params = "pfx num", + .help = "hot-unplug num dimms of memory pool pfx", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_dimm_del_range, + }, + +STEXI +@item mem_decrease @var{config} +@findex mem_decrease + +Hot-unplug dimms. +ETEXI { .name = "device_del", diff --git a/hw/dimm.c b/hw/dimm.c index b544173..48542ba 100644 --- a/hw/dimm.c +++ b/hw/dimm.c @@ -166,6 +166,110 @@ int dimm_do(Monitor *mon, const QDict *qdict, bool add) return 0; } +/* Find for dimm_do_range operation + DIMM_MIN_UNPOPULATED: used for finding next DIMM to hotplug + DIMM_MAX_POPULATED: used for finding next DIMM for hot-unplug + */ + +DimmState *dimm_find_next(char *pfx, uint32_t mode) +{ + DeviceState *dev; + DimmState *slot, *ret; + const char *type; + uint32_t idx; + + Error *err = NULL; + BusChild *kid; + BusState *bus = sysbus_get_default(); + ret = NULL; + + if (mode == DIMM_MIN_UNPOPULATED) + idx = MAX_DIMMS; + else if (mode == DIMM_MAX_POPULATED) + idx = 0; + else + return false; + + QTAILQ_FOREACH(kid, &bus->children, sibling) { + dev = kid->child; + type = object_property_get_str(OBJECT(dev), "type", &err); + if (err) { + error_free(err); + fprintf(stderr, "error getting device type\n"); + exit(1); + } + + if (!strcmp(type, "dimm")) { + slot = DIMM(dev); + if (strstr(dev->id, pfx) && strcmp(dev->id, pfx)) { + if (mode == DIMM_MIN_UNPOPULATED && + (slot->populated == false) && + (slot->pending == false) && + (idx > slot->idx)) { + idx = slot->idx; + ret = slot; + } + else if (mode == DIMM_MAX_POPULATED && + (slot->populated == true) && + (slot->pending == false) && + (idx <= slot->idx)) { + idx = slot->idx; + ret = slot; + } + } + } + } + return ret; +} + +int dimm_do_range(Monitor *mon, const QDict *qdict, bool add) +{ + DimmState *slot = NULL; + uint32_t mode; + uint32_t idx; + int num, ndimms; + + char *pfx = (char*) qdict_get_try_str(qdict, "pfx"); + if (!pfx) { + fprintf(stderr, "ERROR %s invalid pfx\n",__FUNCTION__); + return 1; + } + + char *value = (char*) qdict_get_try_str(qdict, "num"); + if (!value) { + fprintf(stderr, "ERROR %s invalid pfx\n",__FUNCTION__); + return 1; + } + num = atoi(value); + + if (add) + mode = DIMM_MIN_UNPOPULATED; + else + mode = DIMM_MAX_POPULATED; + + ndimms = 0; + while (ndimms < num) { + slot = dimm_find_next(pfx, mode); + if (slot == NULL) { + fprintf(stderr, "%s no further slot found for pool %s\n", + __FUNCTION__, pfx); + fprintf(stderr, "%s operated on %d / %d requested dimms\n", + __FUNCTION__, ndimms, num); + return 1; + } + + if (add) { + dimm_activate(slot); + } + else { + dimm_deactivate(slot); + } + ndimms++; + idx++; + } + + return 0; +} DimmState *dimm_find_from_idx(uint32_t idx) { DimmState *slot; diff --git a/hw/dimm.h b/hw/dimm.h index 0fdf59b..7c456fa 100644 --- a/hw/dimm.h +++ b/hw/dimm.h @@ -11,6 +11,11 @@ #define DIMM_BITMAP_BYTES (MAX_DIMMS + 7) / 8 #define DEFAULT_DIMMSIZE 1024*1024*1024 +enum { + DIMM_MIN_UNPOPULATED= 0, + DIMM_MAX_POPULATED = 1 +}; + typedef enum { DIMM_REMOVE_SUCCESS = 0, DIMM_REMOVE_FAIL = 1, @@ -61,5 +66,7 @@ void dimm_deactivate(DimmState *slot); void dimm_scan_populated(void); void dimm_notify(uint32_t idx, uint32_t event); int dimm_set_populated(DimmState *s); +DimmState *dimm_find_next(char *pfx, uint32_t mode); +int dimm_do_range(Monitor *mon, const QDict *qdict, bool add); #endif diff --git a/monitor.c b/monitor.c index 1dd646c..2e0ce1f 100644 --- a/monitor.c +++ b/monitor.c @@ -4838,3 +4838,13 @@ int do_dimm_del(Monitor *mon, const QDict *qdict, QObject **ret_data) { return dimm_do(mon, qdict, false); } + +int do_dimm_add_range(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + return dimm_do_range(mon, qdict, true); +} + +int do_dimm_del_range(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + return dimm_do_range(mon, qdict, false); +} diff --git a/monitor.h b/monitor.h index afdd721..8224301 100644 --- a/monitor.h +++ b/monitor.h @@ -88,5 +88,7 @@ int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret); int do_dimm_add(Monitor *mon, const QDict *qdict, QObject **ret_data); int do_dimm_del(Monitor *mon, const QDict *qdict, QObject **ret_data); +int do_dimm_add_range(Monitor *mon, const QDict *qdict, QObject **ret_data); +int do_dimm_del_range(Monitor *mon, const QDict *qdict, QObject **ret_data); #endif /* !MONITOR_H */ diff --git a/qmp-commands.hx b/qmp-commands.hx index 6c71696..c3f74ea 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2306,3 +2306,43 @@ Example: } EQMP + + { + .name = "mem-increase", + .args_type = "pfx:s,num:s", + .mhandler.cmd_new = do_dimm_add_range, + }, +SQMP +mem-increase +------------- + +Hotplug memory DIMMs from memory pool + +Will hotplug num memory DIMMs from pool with name pfx. + +Example: + +-> { "execute": "mem-increase", "arguments": { "pfx" : "pool", "num": "10" } } +<- { "return": {} } + +EQMP + + { + .name = "mem-decrease", + .args_type = "pfx:s,num:s", + .mhandler.cmd_new = do_dimm_del_range, + }, +SQMP +mem-decrease +------------- + +Hot-unplug memory DIMMs from memory pool + +Will hot-unplug num memory DIMMs from pool with name pfx. + +Example: + +-> { "execute": "mem-decrease", "arguments": { "pfx" : "pool", "num": "10" } } +<- { "return": {} } + +EQMP