From patchwork Wed Feb 19 07:54:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Tao X-Patchwork-Id: 321766 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 D38C02C02FA for ; Wed, 19 Feb 2014 18:57:27 +1100 (EST) Received: from localhost ([::1]:56974 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WG21f-0007nV-QR for incoming@patchwork.ozlabs.org; Wed, 19 Feb 2014 02:57:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49631) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WG20z-0007XK-6S for qemu-devel@nongnu.org; Wed, 19 Feb 2014 02:56:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WG20r-0003XR-4A for qemu-devel@nongnu.org; Wed, 19 Feb 2014 02:56:21 -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 1WG20q-0003Vd-4j for qemu-devel@nongnu.org; Wed, 19 Feb 2014 02:56:13 -0500 X-IronPort-AV: E=Sophos;i="4.97,504,1389715200"; d="scan'208";a="9558781" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 19 Feb 2014 15:52:07 +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 s1J7tplZ012638; Wed, 19 Feb 2014 15:55:56 +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 2014021915534258-35708 ; Wed, 19 Feb 2014 15:53:42 +0800 From: Hu Tao To: qemu-devel@nongnu.org Date: Wed, 19 Feb 2014 15:54:04 +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:47, Serialize complete at 2014/02/19 15:53:47 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 13/14] memory backend: fill memory backend ram fields 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 Thus makes user control how to allocate memory for ram backend. Signed-off-by: Hu Tao --- backends/hostmem-ram.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++ include/sysemu/sysemu.h | 2 + 2 files changed, 160 insertions(+) diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c index a496dbd..2da9341 100644 --- a/backends/hostmem-ram.c +++ b/backends/hostmem-ram.c @@ -10,23 +10,179 @@ * See the COPYING file in the top-level directory. */ #include "sysemu/hostmem.h" +#include "sysemu/sysemu.h" +#include "qemu/bitmap.h" +#include "qapi-visit.h" +#include "qemu/config-file.h" +#include "qapi/opts-visitor.h" #define TYPE_MEMORY_BACKEND_RAM "memory-ram" +#define MEMORY_BACKEND_RAM(obj) \ + OBJECT_CHECK(HostMemoryBackendRam, (obj), TYPE_MEMORY_BACKEND_RAM) +typedef struct HostMemoryBackendRam HostMemoryBackendRam; + +/** + * @HostMemoryBackendRam + * + * @parent: opaque parent object container + * @host_nodes: host nodes bitmap used for memory policy + * @policy: host memory policy + * @relative: if the host nodes bitmap is relative + */ +struct HostMemoryBackendRam { + /* private */ + HostMemoryBackend parent; + + DECLARE_BITMAP(host_nodes, MAX_NODES); + HostMemPolicy policy; + bool relative; +}; + +static void +get_host_nodes(Object *obj, Visitor *v, void *opaque, const char *name, + Error **errp) +{ + HostMemoryBackendRam *ram_backend = MEMORY_BACKEND_RAM(obj); + uint16List *host_nodes = NULL; + uint16List **node = &host_nodes; + unsigned long value; + + value = find_first_bit(ram_backend->host_nodes, MAX_NODES); + if (value == MAX_NODES) { + return; + } + + *node = g_malloc0(sizeof(**node)); + (*node)->value = value; + node = &(*node)->next; + + do { + value = find_next_bit(ram_backend->host_nodes, MAX_NODES, value + 1); + if (value == MAX_NODES) { + break; + } + + *node = g_malloc0(sizeof(**node)); + (*node)->value = value; + node = &(*node)->next; + } while (true); + + visit_type_uint16List(v, &host_nodes, name, errp); +} + +static void +set_host_nodes(Object *obj, Visitor *v, void *opaque, const char *name, + Error **errp) +{ + HostMemoryBackendRam *ram_backend = MEMORY_BACKEND_RAM(obj); + uint16List *l = NULL; + + visit_type_uint16List(v, &l, name, errp); + + while (l) { + bitmap_set(ram_backend->host_nodes, l->value, 1); + l = l->next; + } +} + +static const char *policies[HOST_MEM_POLICY_MAX + 1] = { + [HOST_MEM_POLICY_DEFAULT] = "default", + [HOST_MEM_POLICY_PREFERRED] = "preferred", + [HOST_MEM_POLICY_MEMBIND] = "membind", + [HOST_MEM_POLICY_INTERLEAVE] = "interleave", + [HOST_MEM_POLICY_MAX] = NULL, +}; + +static void +get_policy(Object *obj, Visitor *v, void *opaque, const char *name, + Error **errp) +{ + HostMemoryBackendRam *ram_backend = MEMORY_BACKEND_RAM(obj); + int policy = ram_backend->policy; + + visit_type_enum(v, &policy, policies, NULL, name, errp); +} + +static void +set_policy(Object *obj, Visitor *v, void *opaque, const char *name, + Error **errp) +{ + HostMemoryBackendRam *ram_backend = MEMORY_BACKEND_RAM(obj); + int policy; + + visit_type_enum(v, &policy, policies, NULL, name, errp); + ram_backend->policy = policy; +} + + +static bool get_relative(Object *obj, Error **errp) +{ + HostMemoryBackendRam *ram_backend = MEMORY_BACKEND_RAM(obj); + + return ram_backend->relative; +} + +static void set_relative(Object *obj, bool value, Error **errp) +{ + HostMemoryBackendRam *ram_backend = MEMORY_BACKEND_RAM(obj); + + ram_backend->relative = value; +} + +#include +#ifndef MPOL_F_RELATIVE_NODES +#define MPOL_F_RELATIVE_NODES (1 << 14) +#define MPOL_F_STATIC_NODES (1 << 15) +#endif static int ram_backend_memory_init(HostMemoryBackend *backend, Error **errp) { + HostMemoryBackendRam *ram_backend = MEMORY_BACKEND_RAM(backend); + int mode = ram_backend->policy; + void *p; + unsigned long maxnode; + if (!memory_region_size(&backend->mr)) { memory_region_init_ram(&backend->mr, OBJECT(backend), object_get_canonical_path(OBJECT(backend)), backend->size); + + p = memory_region_get_ram_ptr(&backend->mr); + maxnode = find_last_bit(ram_backend->host_nodes, MAX_NODES); + + mode |= ram_backend->relative ? MPOL_F_RELATIVE_NODES : + MPOL_F_STATIC_NODES; + + /* This is a workaround for a long standing bug in Linux' + * mbind implementation, which cuts off the last specified + * node. To stay compatible should this bug be fixed, we + * specify one more node and zero this one out. + */ + if (syscall(SYS_mbind, p, backend->size, mode, + ram_backend->host_nodes, maxnode + 2, 0)) { + return -1; + } } return 0; } static void +ram_backend_initfn(Object *obj) +{ + object_property_add(obj, "host-nodes", "int", + get_host_nodes, + set_host_nodes, NULL, NULL, NULL); + object_property_add(obj, "policy", "string", + get_policy, + set_policy, NULL, NULL, NULL); + object_property_add_bool(obj, "relative", + get_relative, set_relative, NULL); +} + +static void ram_backend_class_init(ObjectClass *oc, void *data) { HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc); @@ -38,6 +194,8 @@ static const TypeInfo ram_backend_info = { .name = TYPE_MEMORY_BACKEND_RAM, .parent = TYPE_MEMORY_BACKEND, .class_init = ram_backend_class_init, + .instance_size = sizeof(HostMemoryBackendRam), + .instance_init = ram_backend_initfn, }; static void register_types(void) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index acfc0c7..a3d8c02 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -152,6 +152,8 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, const char *name, QEMUMachineInitArgs *args); +extern QemuOptsList qemu_memdev_opts; + #define MAX_OPTION_ROMS 16 typedef struct QEMUOptionRom { const char *name;