From patchwork Wed Feb 19 07:54:01 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Tao X-Patchwork-Id: 321769 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4E7262C02FC for ; Wed, 19 Feb 2014 18:59:17 +1100 (EST) Received: from localhost ([::1]:57000 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WG23n-0003ba-Av for incoming@patchwork.ozlabs.org; Wed, 19 Feb 2014 02:59:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49612) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WG20y-0007Vr-9j for qemu-devel@nongnu.org; Wed, 19 Feb 2014 02:56:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WG20p-0003Wj-Ay for qemu-devel@nongnu.org; Wed, 19 Feb 2014 02:56:20 -0500 Received: from [222.73.24.84] (port=1409 helo=song.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WG20o-0003Vd-Lz for qemu-devel@nongnu.org; Wed, 19 Feb 2014 02:56:11 -0500 X-IronPort-AV: E=Sophos;i="4.97,504,1389715200"; d="scan'208";a="9558778" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 19 Feb 2014 15:52:06 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id s1J7trHG012639; Wed, 19 Feb 2014 15:55:55 +0800 Received: from G08FNSTD100614.fnst.cn.fujitsu.com ([10.167.226.102]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2014021915534235-35705 ; Wed, 19 Feb 2014 15:53:42 +0800 From: Hu Tao To: qemu-devel@nongnu.org Date: Wed, 19 Feb 2014 15:54:01 +0800 Message-Id: X-Mailer: git-send-email 1.8.5.2.229.g4448466 In-Reply-To: References: X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2014/02/19 15:53:42, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2014/02/19 15:53:46, Serialize complete at 2014/02/19 15:53:46 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 222.73.24.84 Cc: pbonzini@redhat.com, lersek@redhat.com, Wanlong Gao , imammedo@redhat.com Subject: [Qemu-devel] [PATCH v18 10/14] numa: add -numa node, memdev= option 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 From: Paolo Bonzini This option provides the infrastructure for binding guest NUMA nodes to host NUMA nodes. For example: -object memory-ram,size=1024M,policy=membind,host-nodes=0,id=ram-node0 \ -numa node,nodeid=0,cpus=0,memdev=ram-node0 \ -object memory-ram,size=1024M,policy=interleave,host-nodes=1-3,id=ram-node1 \ -numa node,nodeid=1,cpus=1,memdev=ram-node1 The option replaces "-numa mem". Signed-off-by: Paolo Bonzini Conflicts: include/sysemu/sysemu.h numa.c Signed-off-by: Hu Tao --- include/sysemu/sysemu.h | 2 ++ numa.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++-- qapi-schema.json | 6 ++++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index e9da760..acfc0c7 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -12,6 +12,7 @@ #include "qemu/bitmap.h" #include "qom/object.h" #include "hw/boards.h" +#include "sysemu/hostmem.h" /* vl.c */ @@ -140,6 +141,7 @@ extern int nb_numa_nodes; typedef struct node_info { uint64_t node_mem; DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS); + HostMemoryBackend *node_memdev; } NodeInfo; extern NodeInfo numa_info[MAX_NODES]; void set_numa_nodes(void); diff --git a/numa.c b/numa.c index 403b08b..ca55ad7 100644 --- a/numa.c +++ b/numa.c @@ -27,6 +27,8 @@ #include "qapi-visit.h" #include "qapi/opts-visitor.h" #include "qapi/dealloc-visitor.h" +#include "qapi/qmp/qerror.h" + QemuOptsList qemu_numa_opts = { .name = "numa", .implied_opt_name = "type", @@ -34,10 +36,13 @@ QemuOptsList qemu_numa_opts = { .desc = { { 0 } } /* validated with OptsVisitor */ }; +static int have_memdevs = -1; + static int numa_node_parse(NumaNodeOptions *opts) { uint16_t nodenr; uint16List *cpus = NULL; + Error *local_err = NULL; if (opts->has_nodeid) { nodenr = opts->nodeid; @@ -60,6 +65,19 @@ static int numa_node_parse(NumaNodeOptions *opts) bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1); } + if (opts->has_mem && opts->has_memdev) { + fprintf(stderr, "qemu: cannot specify both mem= and memdev=\n"); + return -1; + } + + if (have_memdevs == -1) { + have_memdevs = opts->has_memdev; + } + if (opts->has_memdev != have_memdevs) { + fprintf(stderr, "qemu: memdev option must be specified for either " + "all or no nodes\n"); + } + if (opts->has_mem) { int64_t mem_size; char *endptr; @@ -70,7 +88,19 @@ static int numa_node_parse(NumaNodeOptions *opts) } numa_info[nodenr].node_mem = mem_size; } + if (opts->has_memdev) { + Object *o; + o = object_resolve_path_type(opts->memdev, TYPE_MEMORY_BACKEND, NULL); + if (!o) { + error_setg(&local_err, "memdev=%s is ambiguous", opts->memdev); + qerror_report_err(local_err); + return -1; + } + object_ref(o); + numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL); + numa_info[nodenr].node_memdev = MEMORY_BACKEND(o); + } return 0; } @@ -189,12 +219,42 @@ void set_numa_modes(void) } } +static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner, + const char *name, + QEMUMachineInitArgs *args) +{ + uint64_t ram_size = args->ram_size; + + memory_region_init_ram(mr, owner, name, ram_size); + vmstate_register_ram_global(mr); +} + void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, const char *name, QEMUMachineInitArgs *args) { uint64_t ram_size = args->ram_size; + uint64_t addr = 0; + int i; - memory_region_init_ram(mr, owner, name, ram_size); - vmstate_register_ram_global(mr); + if (nb_numa_nodes == 0 || !have_memdevs) { + allocate_system_memory_nonnuma(mr, owner, name, args); + return; + } + + memory_region_init(mr, owner, name, ram_size); + for (i = 0; i < nb_numa_nodes; i++) { + Error *local_err = NULL; + uint64_t size = numa_info[i].node_mem; + HostMemoryBackend *backend = numa_info[i].node_memdev; + MemoryRegion *seg = host_memory_backend_get_memory(backend, &local_err); + if (local_err) { + qerror_report_err(local_err); + exit(1); + } + + memory_region_add_subregion(mr, addr, seg); + vmstate_register_ram_global(seg); + addr += size; + } } diff --git a/qapi-schema.json b/qapi-schema.json index a2839b8..498ea9b 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4441,7 +4441,10 @@ # # @cpus: #optional VCPUs belong to this node # -# @mem: #optional memory size of this node +# @memdev: #optional memory backend object. If specified for one node, +# it must be specified for all nodes. +# +# @mem: #optional memory size of this node; mutually exclusive with @memdev. # # Since: 2.0 ## @@ -4449,4 +4452,5 @@ 'data': { '*nodeid': 'uint16', '*cpus': ['uint16'], + '*memdev': 'str', '*mem': 'str' }}