* [Qemu-devel] [PATCH v3 02/34] NUMA: check if the total numa memory size is equal to ram_size
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 01/34] NUMA: move numa related code to new file numa.c hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 05/34] NUMA: expand MAX_NODES from 64 to 128 hutao
` (31 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
If the total number of the assigned numa nodes memory is not
equal to the assigned ram size, it will write the wrong data
to ACPI table, then the guest will ignore the wrong ACPI table
and recognize all memory to one node. It's buggy, we should
check it to ensure that we write the right data to ACPI table.
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
numa.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/numa.c b/numa.c
index 395c14f..1d2f761 100644
--- a/numa.c
+++ b/numa.c
@@ -27,6 +27,8 @@
#include "exec/cpu-common.h"
#include "qemu/bitmap.h"
#include "qom/cpu.h"
+#include "qemu/error-report.h"
+#include "include/exec/cpu-common.h" /* for RAM_ADDR_FMT */
static void numa_node_parse_cpus(int nodenr, const char *cpus)
{
@@ -127,6 +129,7 @@ void numa_add(const char *optarg)
void set_numa_nodes(void)
{
if (nb_numa_nodes > 0) {
+ uint64_t numa_total;
int i;
if (nb_numa_nodes > MAX_NODES) {
@@ -154,6 +157,17 @@ void set_numa_nodes(void)
node_mem[i] = ram_size - usedmem;
}
+ numa_total = 0;
+ for (i = 0; i < nb_numa_nodes; i++) {
+ numa_total += node_mem[i];
+ }
+ if (numa_total != ram_size) {
+ error_report("qemu: total memory size for NUMA nodes (%" PRIu64 ")"
+ " should equal to ram_size (" RAM_ADDR_FMT ")\n",
+ numa_total, ram_size);
+ exit(1);
+ }
+
for (i = 0; i < nb_numa_nodes; i++) {
if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) {
break;
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 01/34] NUMA: move numa related code to new file numa.c
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 02/34] NUMA: check if the total numa memory size is equal to ram_size hutao
` (32 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
Makefile.target | 2 +-
cpus.c | 14 ----
include/exec/cpu-all.h | 2 -
include/exec/cpu-common.h | 2 +
include/sysemu/cpus.h | 1 -
include/sysemu/sysemu.h | 3 +
numa.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++
vl.c | 139 +---------------------------------
8 files changed, 193 insertions(+), 156 deletions(-)
create mode 100644 numa.c
diff --git a/Makefile.target b/Makefile.target
index ba12340..234d9cd 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -109,7 +109,7 @@ endif #CONFIG_BSD_USER
#########################################################
# System emulator target
ifdef CONFIG_SOFTMMU
-obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o
+obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
obj-y += qtest.o
obj-y += hw/
obj-$(CONFIG_FDT) += device_tree.o
diff --git a/cpus.c b/cpus.c
index 1104d61..a21bcde 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1313,20 +1313,6 @@ static void tcg_exec_all(void)
exit_request = 0;
}
-void set_numa_modes(void)
-{
- CPUState *cpu;
- int i;
-
- CPU_FOREACH(cpu) {
- for (i = 0; i < nb_numa_nodes; i++) {
- if (test_bit(cpu->cpu_index, node_cpumask[i])) {
- cpu->numa_node = i;
- }
- }
- }
-}
-
void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
{
/* XXX: implement xxx_cpu_list for targets that still miss it */
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index fb649a4..758a928 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -414,8 +414,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
/* memory API */
-extern ram_addr_t ram_size;
-
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
#define RAM_PREALLOC_MASK (1 << 0)
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index a21b65a..e8c7970 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -45,6 +45,8 @@ typedef uintptr_t ram_addr_t;
# define RAM_ADDR_FMT "%" PRIxPTR
#endif
+extern ram_addr_t ram_size;
+
/* memory API */
typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 6502488..4f79081 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -23,7 +23,6 @@ extern int smp_threads;
#define smp_threads 1
#endif
-void set_numa_modes(void);
void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
#endif
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ba5c7f8..565c8f6 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -144,6 +144,9 @@ extern QEMUClockType rtc_clock;
extern int nb_numa_nodes;
extern uint64_t node_mem[MAX_NODES];
extern unsigned long *node_cpumask[MAX_NODES];
+void numa_add(const char *optarg);
+void set_numa_nodes(void);
+void set_numa_modes(void);
#define MAX_OPTION_ROMS 16
typedef struct QEMUOptionRom {
diff --git a/numa.c b/numa.c
new file mode 100644
index 0000000..395c14f
--- /dev/null
+++ b/numa.c
@@ -0,0 +1,186 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2013 Fujitsu Ltd.
+ * Author: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "sysemu/sysemu.h"
+#include "exec/cpu-common.h"
+#include "qemu/bitmap.h"
+#include "qom/cpu.h"
+
+static void numa_node_parse_cpus(int nodenr, const char *cpus)
+{
+ char *endptr;
+ unsigned long long value, endvalue;
+
+ /* Empty CPU range strings will be considered valid, they will simply
+ * not set any bit in the CPU bitmap.
+ */
+ if (!*cpus) {
+ return;
+ }
+
+ if (parse_uint(cpus, &value, &endptr, 10) < 0) {
+ goto error;
+ }
+ if (*endptr == '-') {
+ if (parse_uint_full(endptr + 1, &endvalue, 10) < 0) {
+ goto error;
+ }
+ } else if (*endptr == '\0') {
+ endvalue = value;
+ } else {
+ goto error;
+ }
+
+ if (endvalue >= MAX_CPUMASK_BITS) {
+ endvalue = MAX_CPUMASK_BITS - 1;
+ fprintf(stderr,
+ "qemu: NUMA: A max of %d VCPUs are supported\n",
+ MAX_CPUMASK_BITS);
+ }
+
+ if (endvalue < value) {
+ goto error;
+ }
+
+ bitmap_set(node_cpumask[nodenr], value, endvalue-value+1);
+ return;
+
+error:
+ fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus);
+ exit(1);
+}
+
+void numa_add(const char *optarg)
+{
+ char option[128];
+ char *endptr;
+ unsigned long long nodenr;
+
+ optarg = get_opt_name(option, 128, optarg, ',');
+ if (*optarg == ',') {
+ optarg++;
+ }
+ if (!strcmp(option, "node")) {
+
+ if (nb_numa_nodes >= MAX_NODES) {
+ fprintf(stderr, "qemu: too many NUMA nodes\n");
+ exit(1);
+ }
+
+ if (get_param_value(option, 128, "nodeid", optarg) == 0) {
+ nodenr = nb_numa_nodes;
+ } else {
+ if (parse_uint_full(option, &nodenr, 10) < 0) {
+ fprintf(stderr, "qemu: Invalid NUMA nodeid: %s\n", option);
+ exit(1);
+ }
+ }
+
+ if (nodenr >= MAX_NODES) {
+ fprintf(stderr, "qemu: invalid NUMA nodeid: %llu\n", nodenr);
+ exit(1);
+ }
+
+ if (get_param_value(option, 128, "mem", optarg) == 0) {
+ node_mem[nodenr] = 0;
+ } else {
+ int64_t sval;
+ sval = strtosz(option, &endptr);
+ if (sval < 0 || *endptr) {
+ fprintf(stderr, "qemu: invalid numa mem size: %s\n", optarg);
+ exit(1);
+ }
+ node_mem[nodenr] = sval;
+ }
+ if (get_param_value(option, 128, "cpus", optarg) != 0) {
+ numa_node_parse_cpus(nodenr, option);
+ }
+ nb_numa_nodes++;
+ } else {
+ fprintf(stderr, "Invalid -numa option: %s\n", option);
+ exit(1);
+ }
+}
+
+void set_numa_nodes(void)
+{
+ if (nb_numa_nodes > 0) {
+ int i;
+
+ if (nb_numa_nodes > MAX_NODES) {
+ nb_numa_nodes = MAX_NODES;
+ }
+
+ /* If no memory size if given for any node, assume the default case
+ * and distribute the available memory equally across all nodes
+ */
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (node_mem[i] != 0) {
+ break;
+ }
+ }
+ if (i == nb_numa_nodes) {
+ uint64_t usedmem = 0;
+
+ /* On Linux, the each node's border has to be 8MB aligned,
+ * the final node gets the rest.
+ */
+ for (i = 0; i < nb_numa_nodes - 1; i++) {
+ node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
+ usedmem += node_mem[i];
+ }
+ node_mem[i] = ram_size - usedmem;
+ }
+
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) {
+ break;
+ }
+ }
+ /* assigning the VCPUs round-robin is easier to implement, guest OSes
+ * must cope with this anyway, because there are BIOSes out there in
+ * real machines which also use this scheme.
+ */
+ if (i == nb_numa_nodes) {
+ for (i = 0; i < max_cpus; i++) {
+ set_bit(i, node_cpumask[i % nb_numa_nodes]);
+ }
+ }
+ }
+}
+
+void set_numa_modes(void)
+{
+ CPUState *cpu;
+ int i;
+
+ CPU_FOREACH(cpu) {
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (test_bit(cpu->cpu_index, node_cpumask[i])) {
+ cpu->numa_node = i;
+ }
+ }
+ }
+}
diff --git a/vl.c b/vl.c
index 2355227..c05b099 100644
--- a/vl.c
+++ b/vl.c
@@ -1260,102 +1260,6 @@ char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
return list;
}
-static void numa_node_parse_cpus(int nodenr, const char *cpus)
-{
- char *endptr;
- unsigned long long value, endvalue;
-
- /* Empty CPU range strings will be considered valid, they will simply
- * not set any bit in the CPU bitmap.
- */
- if (!*cpus) {
- return;
- }
-
- if (parse_uint(cpus, &value, &endptr, 10) < 0) {
- goto error;
- }
- if (*endptr == '-') {
- if (parse_uint_full(endptr + 1, &endvalue, 10) < 0) {
- goto error;
- }
- } else if (*endptr == '\0') {
- endvalue = value;
- } else {
- goto error;
- }
-
- if (endvalue >= MAX_CPUMASK_BITS) {
- endvalue = MAX_CPUMASK_BITS - 1;
- fprintf(stderr,
- "qemu: NUMA: A max of %d VCPUs are supported\n",
- MAX_CPUMASK_BITS);
- }
-
- if (endvalue < value) {
- goto error;
- }
-
- bitmap_set(node_cpumask[nodenr], value, endvalue-value+1);
- return;
-
-error:
- fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus);
- exit(1);
-}
-
-static void numa_add(const char *optarg)
-{
- char option[128];
- char *endptr;
- unsigned long long nodenr;
-
- optarg = get_opt_name(option, 128, optarg, ',');
- if (*optarg == ',') {
- optarg++;
- }
- if (!strcmp(option, "node")) {
-
- if (nb_numa_nodes >= MAX_NODES) {
- fprintf(stderr, "qemu: too many NUMA nodes\n");
- exit(1);
- }
-
- if (get_param_value(option, 128, "nodeid", optarg) == 0) {
- nodenr = nb_numa_nodes;
- } else {
- if (parse_uint_full(option, &nodenr, 10) < 0) {
- fprintf(stderr, "qemu: Invalid NUMA nodeid: %s\n", option);
- exit(1);
- }
- }
-
- if (nodenr >= MAX_NODES) {
- fprintf(stderr, "qemu: invalid NUMA nodeid: %llu\n", nodenr);
- exit(1);
- }
-
- if (get_param_value(option, 128, "mem", optarg) == 0) {
- node_mem[nodenr] = 0;
- } else {
- int64_t sval;
- sval = strtosz(option, &endptr);
- if (sval < 0 || *endptr) {
- fprintf(stderr, "qemu: invalid numa mem size: %s\n", optarg);
- exit(1);
- }
- node_mem[nodenr] = sval;
- }
- if (get_param_value(option, 128, "cpus", optarg) != 0) {
- numa_node_parse_cpus(nodenr, option);
- }
- nb_numa_nodes++;
- } else {
- fprintf(stderr, "Invalid -numa option: %s\n", option);
- exit(1);
- }
-}
-
static QemuOptsList qemu_smp_opts = {
.name = "smp-opts",
.implied_opt_name = "cpus",
@@ -4286,48 +4190,7 @@ int main(int argc, char **argv, char **envp)
register_savevm_live(NULL, "ram", 0, 4, &savevm_ram_handlers, NULL);
- if (nb_numa_nodes > 0) {
- int i;
-
- if (nb_numa_nodes > MAX_NODES) {
- nb_numa_nodes = MAX_NODES;
- }
-
- /* If no memory size if given for any node, assume the default case
- * and distribute the available memory equally across all nodes
- */
- for (i = 0; i < nb_numa_nodes; i++) {
- if (node_mem[i] != 0)
- break;
- }
- if (i == nb_numa_nodes) {
- uint64_t usedmem = 0;
-
- /* On Linux, the each node's border has to be 8MB aligned,
- * the final node gets the rest.
- */
- for (i = 0; i < nb_numa_nodes - 1; i++) {
- node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
- usedmem += node_mem[i];
- }
- node_mem[i] = ram_size - usedmem;
- }
-
- for (i = 0; i < nb_numa_nodes; i++) {
- if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) {
- break;
- }
- }
- /* assigning the VCPUs round-robin is easier to implement, guest OSes
- * must cope with this anyway, because there are BIOSes out there in
- * real machines which also use this scheme.
- */
- if (i == nb_numa_nodes) {
- for (i = 0; i < max_cpus; i++) {
- set_bit(i, node_cpumask[i % nb_numa_nodes]);
- }
- }
- }
+ set_numa_nodes();
if (qemu_opts_foreach(qemu_find_opts("mon"), mon_init_func, NULL, 1) != 0) {
exit(1);
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 00/34] NUMA series v3
@ 2014-03-26 10:36 hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 01/34] NUMA: move numa related code to new file numa.c hutao
` (33 more replies)
0 siblings, 34 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
changes to v2.1:
- switch all boards to memory_region_allocate_system_memory
- make string input/output visitor parse int list
- add hmp info memdev
- tweaks to get pass of checkpatch.pl.
You can search `Current state of NUMA series, and hostmem improvements'
for the link of v2.1. Sorry for not giving the link directly as my
network is down at the time I am sending the series.
Hu Tao (8):
hostmem: add properties for NUMA memory policy
hw: switch all boards to use memory_region_allocate_system_memory
Introduce signed range.
qapi: make string input visitor parse int list
qapi: make string output visitor parse int list
qom: introduce object_property_get_enum and
object_property_get_uint16List
qmp: add query-memdev
hmp: add info memdev
Igor Mammedov (3):
vl: convert -m to QemuOpts
qmp: allow object-add completion handler to get canonical path
add memdev backend infrastructure
Luiz Capitulino (1):
man: improve -numa doc
Paolo Bonzini (16):
qemu-option: introduce qemu_find_opts_singleton
vl: redo -object parsing
qmp: improve error reporting for -object and object-add
pc: pass QEMUMachineInitArgs to pc_memory_init
numa: introduce memory_region_allocate_system_memory
numa: add -numa node,memdev= option
memory: reorganize file-based allocation
memory: move mem_path handling to memory_region_allocate_system_memory
memory: add error propagation to file-based RAM allocation
memory: move preallocation code out of exec.c
memory: move RAM_PREALLOC_MASK to exec.c, rename
hostmem: add file-based HostMemoryBackend
hostmem: separate allocation from UserCreatable complete method
hostmem: add merge and dump properties
hostmem: allow preallocation of any memory region
hostmem: add property to map memory with MAP_SHARED
Wanlong Gao (6):
NUMA: move numa related code to new file numa.c
NUMA: check if the total numa memory size is equal to ram_size
NUMA: Add numa_info structure to contain numa nodes info
NUMA: convert -numa option to use OptsVisitor
NUMA: expand MAX_NODES from 64 to 128
configure: add Linux libnuma detection
Makefile.target | 2 +-
backends/Makefile.objs | 3 +
backends/hostmem-file.c | 134 ++++++++++++
backends/hostmem-ram.c | 50 +++++
backends/hostmem.c | 349 ++++++++++++++++++++++++++++++
configure | 33 +++
cpus.c | 14 --
exec.c | 211 +++++++++---------
hmp.c | 36 ++++
hmp.h | 1 +
hw/alpha/typhoon.c | 4 +-
hw/arm/cubieboard.c | 5 +-
hw/arm/digic_boards.c | 3 +-
hw/arm/exynos4210.c | 18 +-
hw/arm/highbank.c | 3 +-
hw/arm/integratorcp.c | 4 +-
hw/arm/kzm.c | 3 +-
hw/arm/musicpal.c | 4 +-
hw/arm/omap1.c | 5 +-
hw/arm/omap2.c | 5 +-
hw/arm/pxa2xx.c | 9 +-
hw/arm/realview.c | 11 +-
hw/arm/strongarm.c | 5 +-
hw/arm/versatilepb.c | 4 +-
hw/arm/vexpress.c | 8 +-
hw/arm/virt.c | 4 +-
hw/arm/xilinx_zynq.c | 4 +-
hw/block/onenand.c | 7 +-
hw/cris/axis_dev88.c | 4 +-
hw/i386/pc.c | 27 +--
hw/i386/pc_piix.c | 8 +-
hw/i386/pc_q35.c | 4 +-
hw/lm32/lm32_boards.c | 8 +-
hw/lm32/milkymist.c | 4 +-
hw/m68k/an5206.c | 4 +-
hw/m68k/dummy_m68k.c | 4 +-
hw/m68k/mcf5208.c | 4 +-
hw/microblaze/petalogix_ml605_mmu.c | 5 +-
hw/microblaze/petalogix_s3adsp1800_mmu.c | 5 +-
hw/mips/mips_fulong2e.c | 4 +-
hw/mips/mips_jazz.c | 4 +-
hw/mips/mips_malta.c | 4 +-
hw/mips/mips_mipssim.c | 4 +-
hw/mips/mips_r4k.c | 4 +-
hw/moxie/moxiesim.c | 4 +-
hw/openrisc/openrisc_sim.c | 3 +-
hw/ppc/e500.c | 4 +-
hw/ppc/mac_newworld.c | 4 +-
hw/ppc/mac_oldworld.c | 4 +-
hw/ppc/ppc405_boards.c | 22 +-
hw/ppc/ppc4xx_devs.c | 38 +++-
hw/ppc/prep.c | 3 +-
hw/ppc/spapr.c | 15 +-
hw/ppc/virtex_ml507.c | 3 +-
hw/s390x/s390-virtio-ccw.c | 4 +-
hw/s390x/s390-virtio.c | 4 +-
hw/sh4/r2d.c | 4 +-
hw/sh4/shix.c | 12 +-
hw/sparc/leon3.c | 3 +-
hw/sparc/sun4m.c | 4 +-
hw/sparc64/sun4u.c | 4 +-
hw/unicore32/puv3.c | 4 +-
hw/xtensa/xtensa_lx60.c | 4 +-
hw/xtensa/xtensa_sim.c | 4 +-
include/exec/cpu-all.h | 8 -
include/exec/cpu-common.h | 2 +
include/exec/memory.h | 33 +++
include/exec/ram_addr.h | 4 +
include/hw/boards.h | 6 +-
include/hw/i386/pc.h | 7 +-
include/qemu/config-file.h | 2 +
include/qemu/osdep.h | 12 ++
include/qemu/range.h | 119 +++++++++++
include/qom/object.h | 18 ++
include/sysemu/cpus.h | 1 -
include/sysemu/hostmem.h | 67 ++++++
include/sysemu/sysemu.h | 18 +-
memory.c | 29 +++
monitor.c | 9 +-
numa.c | 355 +++++++++++++++++++++++++++++++
qapi-schema.json | 91 ++++++++
qapi/string-input-visitor.c | 158 +++++++++++++-
qapi/string-output-visitor.c | 236 +++++++++++++++++++-
qemu-options.hx | 25 ++-
qmp-commands.hx | 32 +++
qmp.c | 11 +-
qom/object.c | 35 +++
tests/test-string-input-visitor.c | 34 +++
tests/test-string-output-visitor.c | 35 +++
util/oslib-posix.c | 73 +++++++
util/qemu-config.c | 14 ++
vl.c | 320 +++++++++-------------------
92 files changed, 2395 insertions(+), 542 deletions(-)
create mode 100644 backends/hostmem-file.c
create mode 100644 backends/hostmem-ram.c
create mode 100644 backends/hostmem.c
create mode 100644 include/sysemu/hostmem.h
create mode 100644 numa.c
--
1.8.5.2.229.g4448466
^ permalink raw reply [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 09/34] vl: redo -object parsing
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (4 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 07/34] qemu-option: introduce qemu_find_opts_singleton hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 06/34] man: improve -numa doc hutao
` (27 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Follow the lines of the HMP implementation, using OptsVisitor
to parse the options. This gives access to OptsVisitor's
rich parsing of integer lists.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
vl.c | 87 +++++++++++++++++++++++++++-----------------------------------------
1 file changed, 35 insertions(+), 52 deletions(-)
diff --git a/vl.c b/vl.c
index 37d9973..9b761d5 100644
--- a/vl.c
+++ b/vl.c
@@ -115,8 +115,7 @@ int main(int argc, char **argv)
#include "qemu/osdep.h"
#include "ui/qemu-spice.h"
-#include "qapi/string-input-visitor.h"
-#include "qom/object_interfaces.h"
+#include "qapi/opts-visitor.h"
#define DEFAULT_RAM_SIZE 128
@@ -2768,69 +2767,53 @@ static void free_and_trace(gpointer mem)
free(mem);
}
-static int object_set_property(const char *name, const char *value, void *opaque)
-{
- Object *obj = OBJECT(opaque);
- StringInputVisitor *siv;
- Error *local_err = NULL;
-
- if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0) {
- return 0;
- }
-
- siv = string_input_visitor_new(value);
- object_property_set(obj, string_input_get_visitor(siv), name, &local_err);
- string_input_visitor_cleanup(siv);
-
- if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
- }
-
- return 0;
-}
-
static int object_create(QemuOpts *opts, void *opaque)
{
- const char *type = qemu_opt_get(opts, "qom-type");
- const char *id = qemu_opts_id(opts);
- Error *local_err = NULL;
- Object *obj;
-
- g_assert(type != NULL);
-
- if (id == NULL) {
- qerror_report(QERR_MISSING_PARAMETER, "id");
- return -1;
+ Error *err = NULL;
+ char *type = NULL;
+ char *id = NULL;
+ void *dummy = NULL;
+ OptsVisitor *ov;
+ QDict *pdict;
+
+ ov = opts_visitor_new(opts);
+ pdict = qemu_opts_to_qdict(opts, NULL);
+
+ visit_start_struct(opts_get_visitor(ov), &dummy, NULL, NULL, 0, &err);
+ if (err) {
+ goto out;
}
- obj = object_new(type);
- if (qemu_opt_foreach(opts, object_set_property, obj, 1) < 0) {
- object_unref(obj);
- return -1;
+ qdict_del(pdict, "qom-type");
+ visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err);
+ if (err) {
+ goto out;
}
- if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
- error_setg(&local_err, "object '%s' isn't supported by -object",
- id);
+ qdict_del(pdict, "id");
+ visit_type_str(opts_get_visitor(ov), &id, "id", &err);
+ if (err) {
goto out;
}
- user_creatable_complete(obj, &local_err);
- if (local_err) {
+ object_add(type, id, pdict, opts_get_visitor(ov), &err);
+ if (err) {
goto out;
}
-
- object_property_add_child(container_get(object_get_root(), "/objects"),
- id, obj, &local_err);
+ visit_end_struct(opts_get_visitor(ov), &err);
+ if (err) {
+ qmp_object_del(id, NULL);
+ }
out:
- object_unref(obj);
- if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
+ opts_visitor_cleanup(ov);
+
+ QDECREF(pdict);
+ g_free(id);
+ g_free(type);
+ g_free(dummy);
+ if (err) {
+ qerror_report_err(err);
}
return 0;
}
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 05/34] NUMA: expand MAX_NODES from 64 to 128
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 01/34] NUMA: move numa related code to new file numa.c hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 02/34] NUMA: check if the total numa memory size is equal to ram_size hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 08/34] vl: convert -m to QemuOpts hutao
` (30 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
libnuma choosed 128 for MAX_NODES, so we follow libnuma here.
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/sysemu.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 4102be3..423d49e 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -133,7 +133,7 @@ extern size_t boot_splash_filedata_size;
extern uint8_t qemu_extra_params_fw[2];
extern QEMUClockType rtc_clock;
-#define MAX_NODES 64
+#define MAX_NODES 128
/* The following shall be true for all CPUs:
* cpu->cpu_index < max_cpus <= MAX_CPUMASK_BITS
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 08/34] vl: convert -m to QemuOpts
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (2 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 05/34] NUMA: expand MAX_NODES from 64 to 128 hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 07/34] qemu-option: introduce qemu_find_opts_singleton hutao
` (29 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Igor Mammedov <imammedo@redhat.com>
Adds option to -m
"size" - startup memory amount
For compatibility with legacy CLI if suffix-less number is passed,
it assumes amount in Mb.
Otherwise user is free to use suffixed number using suffixes b,k/K,M,G
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
qemu-options.hx | 9 +++++---
vl.c | 71 +++++++++++++++++++++++++++++++++++++++++++++------------
2 files changed, 63 insertions(+), 17 deletions(-)
diff --git a/qemu-options.hx b/qemu-options.hx
index f66c3cf..30faa0e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -214,10 +214,13 @@ use is discouraged as it may be removed from future versions.
ETEXI
DEF("m", HAS_ARG, QEMU_OPTION_m,
- "-m megs set virtual RAM size to megs MB [default="
- stringify(DEFAULT_RAM_SIZE) "]\n", QEMU_ARCH_ALL)
+ "-m [size=]megs\n"
+ " configure guest RAM\n"
+ " size: initial amount of guest memory (default: "
+ stringify(DEFAULT_RAM_SIZE) "MiB)\n",
+ QEMU_ARCH_ALL)
STEXI
-@item -m @var{megs}
+@item -m [size=]@var{megs}
@findex -m
Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB. Optionally,
a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
diff --git a/vl.c b/vl.c
index d42e208..37d9973 100644
--- a/vl.c
+++ b/vl.c
@@ -509,6 +509,20 @@ static QemuOptsList qemu_name_opts = {
},
};
+static QemuOptsList qemu_mem_opts = {
+ .name = "memory",
+ .implied_opt_name = "size",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
+ .merge_lists = true,
+ .desc = {
+ {
+ .name = "size",
+ .type = QEMU_OPT_SIZE,
+ },
+ { /* end of list */ }
+ },
+};
+
/**
* Get machine options
*
@@ -2858,6 +2872,8 @@ int main(int argc, char **argv, char **envp)
};
const char *trace_events = NULL;
const char *trace_file = NULL;
+ const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
+ 1024 * 1024;
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
@@ -2881,6 +2897,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_trace_opts);
qemu_add_opts(&qemu_option_rom_opts);
qemu_add_opts(&qemu_machine_opts);
+ qemu_add_opts(&qemu_mem_opts);
qemu_add_opts(&qemu_smp_opts);
qemu_add_opts(&qemu_boot_opts);
qemu_add_opts(&qemu_sandbox_opts);
@@ -2906,7 +2923,7 @@ int main(int argc, char **argv, char **envp)
module_call_init(MODULE_INIT_MACHINE);
machine_class = find_default_machine();
cpu_model = NULL;
- ram_size = 0;
+ ram_size = default_ram_size;
snapshot = 0;
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
@@ -3196,20 +3213,48 @@ int main(int argc, char **argv, char **envp)
exit(0);
break;
case QEMU_OPTION_m: {
- int64_t value;
uint64_t sz;
- char *end;
+ const char *mem_str;
- value = strtosz(optarg, &end);
- if (value < 0 || *end) {
- fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
- exit(1);
+ opts = qemu_opts_parse(qemu_find_opts("memory"),
+ optarg, 1);
+ if (!opts) {
+ exit(EXIT_FAILURE);
+ }
+
+ mem_str = qemu_opt_get(opts, "size");
+ if (!mem_str) {
+ error_report("invalid -m option, missing 'size' option");
+ exit(EXIT_FAILURE);
+ }
+ if (!*mem_str) {
+ error_report("missing 'size' option value");
+ exit(EXIT_FAILURE);
+ }
+
+ sz = qemu_opt_get_size(opts, "size", ram_size);
+
+ /* Fix up legacy suffix-less format */
+ if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+ uint64_t overflow_check = sz;
+
+ sz <<= 20;
+ if ((sz >> 20) != overflow_check) {
+ error_report("too large 'size' option value");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* backward compatibility behaviour for case "-m 0" */
+ if (sz == 0) {
+ sz = default_ram_size;
}
- sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+
+ sz = QEMU_ALIGN_UP(sz, 8192);
ram_size = sz;
if (ram_size != sz) {
- fprintf(stderr, "qemu: ram size too large\n");
- exit(1);
+ error_report("ram size too large");
+ exit(EXIT_FAILURE);
}
break;
}
@@ -4051,10 +4096,8 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
- /* init the memory */
- if (ram_size == 0) {
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
- }
+ /* store value for the future use */
+ qemu_opt_set_number(qemu_find_opts_singleton("memory"), "size", ram_size);
if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
!= 0) {
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 06/34] man: improve -numa doc
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (5 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 09/34] vl: redo -object parsing hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 03/34] NUMA: Add numa_info structure to contain numa nodes info hutao
` (26 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Luiz Capitulino, Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Luiz Capitulino <lcapitulino@redhat.com>
The -numa option documentation in qemu's manpage lacks the command-line
options and some information regarding how it relates to options -m and
-smp. This commit fills in the missing text.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-options.hx | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/qemu-options.hx b/qemu-options.hx
index ee5437b..f66c3cf 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -97,10 +97,14 @@ ETEXI
DEF("numa", HAS_ARG, QEMU_OPTION_numa,
"-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL)
STEXI
-@item -numa @var{opts}
+@item -numa node[,mem=@var{size}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}]
@findex -numa
-Simulate a multi node NUMA system. If mem and cpus are omitted, resources
-are split equally.
+Simulate a multi node NUMA system. If @samp{mem}
+and @samp{cpus} are omitted, resources are split equally. Also, note
+that the -@option{numa} option doesn't allocate any of the specified
+resources. That is, it just assigns existing resources to NUMA nodes. This
+means that one still has to use the @option{-m}, @option{-smp} options
+to respectively allocate RAM and vCPUs.
ETEXI
DEF("add-fd", HAS_ARG, QEMU_OPTION_add_fd,
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 04/34] NUMA: convert -numa option to use OptsVisitor
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (7 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 03/34] NUMA: Add numa_info structure to contain numa nodes info hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 10/34] qmp: allow object-add completion handler to get canonical path hutao
` (24 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/sysemu.h | 3 +-
numa.c | 145 +++++++++++++++++++++++-------------------------
qapi-schema.json | 32 +++++++++++
vl.c | 11 +++-
4 files changed, 114 insertions(+), 77 deletions(-)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 3a9308b..4102be3 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -148,9 +148,10 @@ typedef struct node_info {
DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
} NodeInfo;
extern NodeInfo numa_info[MAX_NODES];
-void numa_add(const char *optarg);
void set_numa_nodes(void);
void set_numa_modes(void);
+extern QemuOptsList qemu_numa_opts;
+int numa_init_func(QemuOpts *opts, void *opaque);
#define MAX_OPTION_ROMS 16
typedef struct QEMUOptionRom {
diff --git a/numa.c b/numa.c
index 48d8bcc..439df87 100644
--- a/numa.c
+++ b/numa.c
@@ -29,101 +29,96 @@
#include "qom/cpu.h"
#include "qemu/error-report.h"
#include "include/exec/cpu-common.h" /* for RAM_ADDR_FMT */
-
-static void numa_node_parse_cpus(int nodenr, const char *cpus)
+#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",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_numa_opts.head),
+ .desc = { { 0 } } /* validated with OptsVisitor */
+};
+
+static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp)
{
- char *endptr;
- unsigned long long value, endvalue;
+ uint16_t nodenr;
+ uint16List *cpus = NULL;
- /* Empty CPU range strings will be considered valid, they will simply
- * not set any bit in the CPU bitmap.
- */
- if (!*cpus) {
- return;
- }
-
- if (parse_uint(cpus, &value, &endptr, 10) < 0) {
- goto error;
- }
- if (*endptr == '-') {
- if (parse_uint_full(endptr + 1, &endvalue, 10) < 0) {
- goto error;
- }
- } else if (*endptr == '\0') {
- endvalue = value;
+ if (node->has_nodeid) {
+ nodenr = node->nodeid;
} else {
- goto error;
+ nodenr = nb_numa_nodes;
}
- if (endvalue >= MAX_CPUMASK_BITS) {
- endvalue = MAX_CPUMASK_BITS - 1;
- fprintf(stderr,
- "qemu: NUMA: A max of %d VCPUs are supported\n",
- MAX_CPUMASK_BITS);
+ if (nodenr >= MAX_NODES) {
+ error_setg(errp, "Max number of NUMA nodes reached: %"
+ PRIu16 "\n", nodenr);
+ return;
}
- if (endvalue < value) {
- goto error;
+ for (cpus = node->cpus; cpus; cpus = cpus->next) {
+ if (cpus->value > MAX_CPUMASK_BITS) {
+ error_setg(errp, "CPU number %" PRIu16 " is bigger than %d",
+ cpus->value, MAX_CPUMASK_BITS);
+ return;
+ }
+ bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
}
- bitmap_set(numa_info[nodenr].node_cpu, value, endvalue-value+1);
- return;
-
-error:
- fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus);
- exit(1);
+ if (node->has_mem) {
+ uint64_t mem_size = node->mem;
+ const char *mem_str = qemu_opt_get(opts, "mem");
+ /* Fix up legacy suffix-less format */
+ if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+ mem_size <<= 20;
+ }
+ numa_info[nodenr].node_mem = mem_size;
+ }
}
-void numa_add(const char *optarg)
+int numa_init_func(QemuOpts *opts, void *opaque)
{
- char option[128];
- char *endptr;
- unsigned long long nodenr;
+ NumaOptions *object = NULL;
+ Error *err = NULL;
- optarg = get_opt_name(option, 128, optarg, ',');
- if (*optarg == ',') {
- optarg++;
+ {
+ OptsVisitor *ov = opts_visitor_new(opts);
+ visit_type_NumaOptions(opts_get_visitor(ov), &object, NULL, &err);
+ opts_visitor_cleanup(ov);
}
- if (!strcmp(option, "node")) {
- if (nb_numa_nodes >= MAX_NODES) {
- fprintf(stderr, "qemu: too many NUMA nodes\n");
- exit(1);
- }
+ if (err) {
+ goto error;
+ }
- if (get_param_value(option, 128, "nodeid", optarg) == 0) {
- nodenr = nb_numa_nodes;
- } else {
- if (parse_uint_full(option, &nodenr, 10) < 0) {
- fprintf(stderr, "qemu: Invalid NUMA nodeid: %s\n", option);
- exit(1);
- }
+ switch (object->kind) {
+ case NUMA_OPTIONS_KIND_NODE:
+ numa_node_parse(object->node, opts, &err);
+ if (err) {
+ goto error;
}
+ nb_numa_nodes++;
+ break;
+ default:
+ abort();
+ }
- if (nodenr >= MAX_NODES) {
- fprintf(stderr, "qemu: invalid NUMA nodeid: %llu\n", nodenr);
- exit(1);
- }
+ return 0;
- if (get_param_value(option, 128, "mem", optarg) == 0) {
- numa_info[nodenr].node_mem = 0;
- } else {
- int64_t sval;
- sval = strtosz(option, &endptr);
- if (sval < 0 || *endptr) {
- fprintf(stderr, "qemu: invalid numa mem size: %s\n", optarg);
- exit(1);
- }
- numa_info[nodenr].node_mem = sval;
- }
- if (get_param_value(option, 128, "cpus", optarg) != 0) {
- numa_node_parse_cpus(nodenr, option);
- }
- nb_numa_nodes++;
- } else {
- fprintf(stderr, "Invalid -numa option: %s\n", option);
- exit(1);
+error:
+ qerror_report_err(err);
+ error_free(err);
+
+ if (object) {
+ QapiDeallocVisitor *dv = qapi_dealloc_visitor_new();
+ visit_type_NumaOptions(qapi_dealloc_get_visitor(dv),
+ &object, NULL, NULL);
+ qapi_dealloc_visitor_cleanup(dv);
}
+
+ return -1;
}
void set_numa_nodes(void)
diff --git a/qapi-schema.json b/qapi-schema.json
index b68cd44..8451d15 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4686,3 +4686,35 @@
'btn' : 'InputBtnEvent',
'rel' : 'InputMoveEvent',
'abs' : 'InputMoveEvent' } }
+
+##
+# @NumaOptions
+#
+# A discriminated record of NUMA options. (for OptsVisitor)
+#
+# Since 2.1
+##
+{ 'union': 'NumaOptions',
+ 'data': {
+ 'node': 'NumaNodeOptions' }}
+
+##
+# @NumaNodeOptions
+#
+# Create a guest NUMA node. (for OptsVisitor)
+#
+# @nodeid: #optional NUMA node ID (increase by 1 from 0 if omitted)
+#
+# @cpus: #optional VCPUs belonging to this node (assign VCPUS round-robin
+# if omitted)
+#
+# @mem: #optional memory size of this node (equally divide total memory among
+# nodes if omitted)
+#
+# Since: 2.1
+##
+{ 'type': 'NumaNodeOptions',
+ 'data': {
+ '*nodeid': 'uint16',
+ '*cpus': ['uint16'],
+ '*mem': 'size' }}
diff --git a/vl.c b/vl.c
index 0027164..9ac7028 100644
--- a/vl.c
+++ b/vl.c
@@ -2899,6 +2899,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_realtime_opts);
qemu_add_opts(&qemu_msg_opts);
qemu_add_opts(&qemu_name_opts);
+ qemu_add_opts(&qemu_numa_opts);
runstate_init();
@@ -3096,7 +3097,10 @@ int main(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_numa:
- numa_add(optarg);
+ opts = qemu_opts_parse(qemu_find_opts("numa"), optarg, 1);
+ if (!opts) {
+ exit(1);
+ }
break;
case QEMU_OPTION_display:
display_type = select_display(optarg);
@@ -4189,6 +4193,11 @@ int main(int argc, char **argv, char **envp)
register_savevm_live(NULL, "ram", 0, 4, &savevm_ram_handlers, NULL);
+ if (qemu_opts_foreach(qemu_find_opts("numa"), numa_init_func,
+ NULL, 1) != 0) {
+ exit(1);
+ }
+
set_numa_nodes();
if (qemu_opts_foreach(qemu_find_opts("mon"), mon_init_func, NULL, 1) != 0) {
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 07/34] qemu-option: introduce qemu_find_opts_singleton
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (3 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 08/34] vl: convert -m to QemuOpts hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 09/34] vl: redo -object parsing hutao
` (28 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Andreas Faerber <afaerber@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/config-file.h | 2 ++
util/qemu-config.c | 14 ++++++++++++++
vl.c | 11 +----------
3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index dbd97c4..d4ba20e 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -8,6 +8,8 @@
QemuOptsList *qemu_find_opts(const char *group);
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
+QemuOpts *qemu_find_opts_singleton(const char *group);
+
void qemu_add_opts(QemuOptsList *list);
void qemu_add_drive_opts(QemuOptsList *list);
int qemu_set_option(const char *str);
diff --git a/util/qemu-config.c b/util/qemu-config.c
index f610101..60051df 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -39,6 +39,20 @@ QemuOptsList *qemu_find_opts(const char *group)
return ret;
}
+QemuOpts *qemu_find_opts_singleton(const char *group)
+{
+ QemuOptsList *list;
+ QemuOpts *opts;
+
+ list = qemu_find_opts(group);
+ assert(list);
+ opts = qemu_opts_find(list, NULL);
+ if (!opts) {
+ opts = qemu_opts_create(list, NULL, 0, &error_abort);
+ }
+ return opts;
+}
+
static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
{
CommandLineParameterInfoList *param_list = NULL, *entry;
diff --git a/vl.c b/vl.c
index 9ac7028..d42e208 100644
--- a/vl.c
+++ b/vl.c
@@ -516,16 +516,7 @@ static QemuOptsList qemu_name_opts = {
*/
QemuOpts *qemu_get_machine_opts(void)
{
- QemuOptsList *list;
- QemuOpts *opts;
-
- list = qemu_find_opts("machine");
- assert(list);
- opts = qemu_opts_find(list, NULL);
- if (!opts) {
- opts = qemu_opts_create(list, NULL, 0, &error_abort);
- }
- return opts;
+ return qemu_find_opts_singleton("machine");
}
const char *qemu_get_vm_name(void)
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 03/34] NUMA: Add numa_info structure to contain numa nodes info
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (6 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 06/34] man: improve -numa doc hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 04/34] NUMA: convert -numa option to use OptsVisitor hutao
` (25 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: Andre Przywara, ehabkost@redhat.com, imammedo@redhat.com,
mtosatti@redhat.com, Paolo Bonzini,
a.motakis@virtualopensystems.com, gaowanlong@cn.fujitsu.com
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Add the numa_info structure to contain the numa nodes memory,
VCPUs information and the future added numa nodes host memory
policies.
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
[Fix hw/ppc/spapr.c - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 12 ++++++++----
hw/ppc/spapr.c | 11 ++++++-----
include/sysemu/sysemu.h | 8 ++++++--
monitor.c | 2 +-
numa.c | 23 ++++++++++++-----------
vl.c | 7 +++----
6 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 14f0d91..249e504 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -675,14 +675,14 @@ static FWCfgState *bochs_bios_init(void)
unsigned int apic_id = x86_cpu_apic_id_from_index(i);
assert(apic_id < apic_id_limit);
for (j = 0; j < nb_numa_nodes; j++) {
- if (test_bit(i, node_cpumask[j])) {
+ if (test_bit(i, numa_info[j].node_cpu)) {
numa_fw_cfg[apic_id + 1] = cpu_to_le64(j);
break;
}
}
}
for (i = 0; i < nb_numa_nodes; i++) {
- numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(node_mem[i]);
+ numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(numa_info[i].node_mem);
}
fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
(1 + apic_id_limit + nb_numa_nodes) *
@@ -1093,8 +1093,12 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
guest_info->apic_id_limit = pc_apic_id_limit(max_cpus);
guest_info->apic_xrupt_override = kvm_allows_irq0_override();
guest_info->numa_nodes = nb_numa_nodes;
- guest_info->node_mem = g_memdup(node_mem, guest_info->numa_nodes *
+ guest_info->node_mem = g_malloc0(guest_info->numa_nodes *
sizeof *guest_info->node_mem);
+ for (i = 0; i < nb_numa_nodes; i++) {
+ guest_info->node_mem[i] = numa_info[i].node_mem;
+ }
+
guest_info->node_cpu = g_malloc0(guest_info->apic_id_limit *
sizeof *guest_info->node_cpu);
@@ -1102,7 +1106,7 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
unsigned int apic_id = x86_cpu_apic_id_from_index(i);
assert(apic_id < guest_info->apic_id_limit);
for (j = 0; j < nb_numa_nodes; j++) {
- if (test_bit(i, node_cpumask[j])) {
+ if (test_bit(i, numa_info[j].node_cpu)) {
guest_info->node_cpu[apic_id] = j;
break;
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a11e121..89f71a8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -538,8 +538,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
int i, off;
/* memory node(s) */
- if (nb_numa_nodes > 1 && node_mem[0] < ram_size) {
- node0_size = node_mem[0];
+ if (nb_numa_nodes > 1 && numa_info[0].node_mem < ram_size) {
+ node0_size = numa_info[0].node_mem;
} else {
node0_size = ram_size;
}
@@ -577,7 +577,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
if (mem_start >= ram_size) {
node_size = 0;
} else {
- node_size = node_mem[i];
+ node_size = numa_info[i].node_mem;
if (node_size > ram_size - mem_start) {
node_size = ram_size - mem_start;
}
@@ -722,7 +722,8 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
/* Update the RMA size if necessary */
if (spapr->vrma_adjust) {
- hwaddr node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
+ hwaddr node0_size = (nb_numa_nodes > 1) ?
+ numa_info[0].node_mem : ram_size;
spapr->rma_size = kvmppc_rma_size(node0_size, spapr->htab_shift);
}
}
@@ -1155,7 +1156,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
hwaddr rma_alloc_size;
- hwaddr node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
+ hwaddr node0_size = (nb_numa_nodes > 1) ? numa_info[0].node_mem : ram_size;
uint32_t initrd_base = 0;
long kernel_size = 0, initrd_size = 0;
long load_limit, rtas_limit, fw_size;
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 565c8f6..3a9308b 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -9,6 +9,7 @@
#include "qapi-types.h"
#include "qemu/notify.h"
#include "qemu/main-loop.h"
+#include "qemu/bitmap.h"
/* vl.c */
@@ -142,8 +143,11 @@ extern QEMUClockType rtc_clock;
#define MAX_CPUMASK_BITS 255
extern int nb_numa_nodes;
-extern uint64_t node_mem[MAX_NODES];
-extern unsigned long *node_cpumask[MAX_NODES];
+typedef struct node_info {
+ uint64_t node_mem;
+ DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
+} NodeInfo;
+extern NodeInfo numa_info[MAX_NODES];
void numa_add(const char *optarg);
void set_numa_nodes(void);
void set_numa_modes(void);
diff --git a/monitor.c b/monitor.c
index 342e83b..39f2518 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2031,7 +2031,7 @@ static void do_info_numa(Monitor *mon, const QDict *qdict)
}
monitor_printf(mon, "\n");
monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
- node_mem[i] >> 20);
+ numa_info[i].node_mem >> 20);
}
}
diff --git a/numa.c b/numa.c
index 1d2f761..48d8bcc 100644
--- a/numa.c
+++ b/numa.c
@@ -66,7 +66,7 @@ static void numa_node_parse_cpus(int nodenr, const char *cpus)
goto error;
}
- bitmap_set(node_cpumask[nodenr], value, endvalue-value+1);
+ bitmap_set(numa_info[nodenr].node_cpu, value, endvalue-value+1);
return;
error:
@@ -106,7 +106,7 @@ void numa_add(const char *optarg)
}
if (get_param_value(option, 128, "mem", optarg) == 0) {
- node_mem[nodenr] = 0;
+ numa_info[nodenr].node_mem = 0;
} else {
int64_t sval;
sval = strtosz(option, &endptr);
@@ -114,7 +114,7 @@ void numa_add(const char *optarg)
fprintf(stderr, "qemu: invalid numa mem size: %s\n", optarg);
exit(1);
}
- node_mem[nodenr] = sval;
+ numa_info[nodenr].node_mem = sval;
}
if (get_param_value(option, 128, "cpus", optarg) != 0) {
numa_node_parse_cpus(nodenr, option);
@@ -140,7 +140,7 @@ void set_numa_nodes(void)
* and distribute the available memory equally across all nodes
*/
for (i = 0; i < nb_numa_nodes; i++) {
- if (node_mem[i] != 0) {
+ if (numa_info[i].node_mem != 0) {
break;
}
}
@@ -151,15 +151,16 @@ void set_numa_nodes(void)
* the final node gets the rest.
*/
for (i = 0; i < nb_numa_nodes - 1; i++) {
- node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
- usedmem += node_mem[i];
+ numa_info[i].node_mem = (ram_size / nb_numa_nodes) &
+ ~((1 << 23UL) - 1);
+ usedmem += numa_info[i].node_mem;
}
- node_mem[i] = ram_size - usedmem;
+ numa_info[i].node_mem = ram_size - usedmem;
}
numa_total = 0;
for (i = 0; i < nb_numa_nodes; i++) {
- numa_total += node_mem[i];
+ numa_total += numa_info[i].node_mem;
}
if (numa_total != ram_size) {
error_report("qemu: total memory size for NUMA nodes (%" PRIu64 ")"
@@ -169,7 +170,7 @@ void set_numa_nodes(void)
}
for (i = 0; i < nb_numa_nodes; i++) {
- if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) {
+ if (!bitmap_empty(numa_info[i].node_cpu, MAX_CPUMASK_BITS)) {
break;
}
}
@@ -179,7 +180,7 @@ void set_numa_nodes(void)
*/
if (i == nb_numa_nodes) {
for (i = 0; i < max_cpus; i++) {
- set_bit(i, node_cpumask[i % nb_numa_nodes]);
+ set_bit(i, numa_info[i % nb_numa_nodes].node_cpu);
}
}
}
@@ -192,7 +193,7 @@ void set_numa_modes(void)
CPU_FOREACH(cpu) {
for (i = 0; i < nb_numa_nodes; i++) {
- if (test_bit(cpu->cpu_index, node_cpumask[i])) {
+ if (test_bit(cpu->cpu_index, numa_info[i].node_cpu)) {
cpu->numa_node = i;
}
}
diff --git a/vl.c b/vl.c
index c05b099..0027164 100644
--- a/vl.c
+++ b/vl.c
@@ -195,8 +195,7 @@ static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
QTAILQ_HEAD_INITIALIZER(fw_boot_order);
int nb_numa_nodes;
-uint64_t node_mem[MAX_NODES];
-unsigned long *node_cpumask[MAX_NODES];
+NodeInfo numa_info[MAX_NODES];
uint8_t qemu_uuid[16];
bool qemu_uuid_set;
@@ -2921,8 +2920,8 @@ int main(int argc, char **argv, char **envp)
translation = BIOS_ATA_TRANSLATION_AUTO;
for (i = 0; i < MAX_NODES; i++) {
- node_mem[i] = 0;
- node_cpumask[i] = bitmap_new(MAX_CPUMASK_BITS);
+ numa_info[i].node_mem = 0;
+ bitmap_zero(numa_info[i].node_cpu, MAX_CPUMASK_BITS);
}
nb_numa_nodes = 0;
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 10/34] qmp: allow object-add completion handler to get canonical path
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (8 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 04/34] NUMA: convert -numa option to use OptsVisitor hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 14/34] add memdev backend infrastructure hutao
` (23 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Igor Mammedov <imammedo@redhat.com>
Add object to /objects before calling user_creatable_complete()
handler, so that object might be able to call
object_get_canonical_path() in its completion handler.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qmp.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/qmp.c b/qmp.c
index 87a28f7..54b95ba 100644
--- a/qmp.c
+++ b/qmp.c
@@ -564,13 +564,15 @@ void object_add(const char *type, const char *id, const QDict *qdict,
goto out;
}
+ object_property_add_child(container_get(object_get_root(), "/objects"),
+ id, obj, &local_err);
+
user_creatable_complete(obj, &local_err);
if (local_err) {
+ object_property_del(container_get(object_get_root(), "/objects"),
+ id, &error_abort);
goto out;
}
-
- object_property_add_child(container_get(object_get_root(), "/objects"),
- id, obj, &local_err);
out:
if (local_err) {
error_propagate(errp, local_err);
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 12/34] pc: pass QEMUMachineInitArgs to pc_memory_init
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (11 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 16/34] memory: reorganize file-based allocation hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 11/34] qmp: improve error reporting for -object and object-add hutao
` (20 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 11 +++++------
hw/i386/pc_piix.c | 8 +++-----
hw/i386/pc_q35.c | 4 +---
include/hw/i386/pc.h | 7 +++----
4 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 249e504..d5fb884 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1161,10 +1161,8 @@ void pc_acpi_init(const char *default_dsdt)
}
}
-FWCfgState *pc_memory_init(MemoryRegion *system_memory,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
+FWCfgState *pc_memory_init(QEMUMachineInitArgs *args,
+ MemoryRegion *system_memory,
ram_addr_t below_4g_mem_size,
ram_addr_t above_4g_mem_size,
MemoryRegion *rom_memory,
@@ -1176,7 +1174,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
MemoryRegion *ram_below_4g, *ram_above_4g;
FWCfgState *fw_cfg;
- linux_boot = (kernel_filename != NULL);
+ linux_boot = (args->kernel_filename != NULL);
/* Allocate RAM. We allocate it as a single memory region and use
* aliases to address portions of it, mostly for backwards compatibility
@@ -1217,7 +1215,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
rom_set_fw(fw_cfg);
if (linux_boot) {
- load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
+ load_linux(fw_cfg, args->kernel_filename, args->initrd_filename,
+ args->kernel_cmdline, below_4g_mem_size);
}
for (i = 0; i < nb_option_roms; i++) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7930a26..3bd8821 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -151,11 +151,9 @@ static void pc_init1(QEMUMachineInitArgs *args,
/* allocate ram and load rom/bios */
if (!xen_enabled()) {
- fw_cfg = pc_memory_init(system_memory,
- args->kernel_filename, args->kernel_cmdline,
- args->initrd_filename,
- below_4g_mem_size, above_4g_mem_size,
- rom_memory, &ram_memory, guest_info);
+ fw_cfg = pc_memory_init(args, system_memory,
+ below_4g_mem_size, above_4g_mem_size,
+ rom_memory, &ram_memory, guest_info);
}
gsi_state = g_malloc0(sizeof(*gsi_state));
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c844dc2..01794fc 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -138,9 +138,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
/* allocate ram and load rom/bios */
if (!xen_enabled()) {
- pc_memory_init(get_system_memory(),
- args->kernel_filename, args->kernel_cmdline,
- args->initrd_filename,
+ pc_memory_init(args, get_system_memory(),
below_4g_mem_size, above_4g_mem_size,
rom_memory, &ram_memory, guest_info);
}
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9010246..8fc0527 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -3,6 +3,7 @@
#include "qemu-common.h"
#include "exec/memory.h"
+#include "hw/boards.h"
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
#include "net/net.h"
@@ -134,10 +135,8 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
MemoryRegion *pci_address_space);
-FWCfgState *pc_memory_init(MemoryRegion *system_memory,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
+FWCfgState *pc_memory_init(QEMUMachineInitArgs *args,
+ MemoryRegion *system_memory,
ram_addr_t below_4g_mem_size,
ram_addr_t above_4g_mem_size,
MemoryRegion *rom_memory,
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 16/34] memory: reorganize file-based allocation
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (10 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 14/34] add memdev backend infrastructure hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 12/34] pc: pass QEMUMachineInitArgs to pc_memory_init hutao
` (21 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Split the internal interface in exec.c to a separate function, and
push the check on mem_path up to memory_region_init_ram.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
exec.c | 105 +++++++++++++++++++++++++++++-------------------
include/exec/cpu-all.h | 3 --
include/exec/ram_addr.h | 2 +
include/sysemu/sysemu.h | 2 +
memory.c | 7 +++-
5 files changed, 73 insertions(+), 46 deletions(-)
diff --git a/exec.c b/exec.c
index 91513c6..8ae8b95 100644
--- a/exec.c
+++ b/exec.c
@@ -1247,56 +1247,30 @@ static int memory_try_enable_merging(void *addr, size_t len)
return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
}
-ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
- MemoryRegion *mr)
+static ram_addr_t ram_block_add(RAMBlock *new_block)
{
- RAMBlock *block, *new_block;
+ RAMBlock *block;
ram_addr_t old_ram_size, new_ram_size;
old_ram_size = last_ram_offset() >> TARGET_PAGE_BITS;
- size = TARGET_PAGE_ALIGN(size);
- new_block = g_malloc0(sizeof(*new_block));
- new_block->fd = -1;
-
/* This assumes the iothread lock is taken here too. */
qemu_mutex_lock_ramlist();
- new_block->mr = mr;
- new_block->offset = find_ram_offset(size);
- if (host) {
- new_block->host = host;
- new_block->flags |= RAM_PREALLOC_MASK;
- } else if (xen_enabled()) {
- if (mem_path) {
- fprintf(stderr, "-mem-path not supported with Xen\n");
- exit(1);
- }
- xen_ram_alloc(new_block->offset, size, mr);
- } else {
- if (mem_path) {
- if (phys_mem_alloc != qemu_anon_ram_alloc) {
- /*
- * file_ram_alloc() needs to allocate just like
- * phys_mem_alloc, but we haven't bothered to provide
- * a hook there.
- */
- fprintf(stderr,
- "-mem-path not supported with this accelerator\n");
- exit(1);
- }
- new_block->host = file_ram_alloc(new_block, size, mem_path);
- }
- if (!new_block->host) {
- new_block->host = phys_mem_alloc(size);
+ new_block->offset = find_ram_offset(new_block->length);
+
+ if (!new_block->host) {
+ if (xen_enabled()) {
+ xen_ram_alloc(new_block->offset, new_block->length, new_block->mr);
+ } else {
+ new_block->host = phys_mem_alloc(new_block->length);
if (!new_block->host) {
fprintf(stderr, "Cannot set up guest memory '%s': %s\n",
new_block->mr->name, strerror(errno));
exit(1);
}
- memory_try_enable_merging(new_block->host, size);
+ memory_try_enable_merging(new_block->host, new_block->length);
}
}
- new_block->length = size;
/* Keep the list sorted from biggest to smallest block. */
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
@@ -1324,18 +1298,65 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
old_ram_size, new_ram_size);
}
}
- cpu_physical_memory_set_dirty_range(new_block->offset, size);
+ cpu_physical_memory_set_dirty_range(new_block->offset, new_block->length);
- qemu_ram_setup_dump(new_block->host, size);
- qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE);
- qemu_madvise(new_block->host, size, QEMU_MADV_DONTFORK);
+ qemu_ram_setup_dump(new_block->host, new_block->length);
+ qemu_madvise(new_block->host, new_block->length, QEMU_MADV_HUGEPAGE);
+ qemu_madvise(new_block->host, new_block->length, QEMU_MADV_DONTFORK);
- if (kvm_enabled())
- kvm_setup_guest_memory(new_block->host, size);
+ if (kvm_enabled()) {
+ kvm_setup_guest_memory(new_block->host, new_block->length);
+ }
return new_block->offset;
}
+ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
+ const char *mem_path)
+{
+ RAMBlock *new_block;
+
+ if (xen_enabled()) {
+ fprintf(stderr, "-mem-path not supported with Xen\n");
+ exit(1);
+ }
+
+ if (phys_mem_alloc != qemu_anon_ram_alloc) {
+ /*
+ * file_ram_alloc() needs to allocate just like
+ * phys_mem_alloc, but we haven't bothered to provide
+ * a hook there.
+ */
+ fprintf(stderr,
+ "-mem-path not supported with this accelerator\n");
+ exit(1);
+ }
+
+ size = TARGET_PAGE_ALIGN(size);
+ new_block = g_malloc0(sizeof(*new_block));
+ new_block->mr = mr;
+ new_block->length = size;
+ new_block->host = file_ram_alloc(new_block, size, mem_path);
+ return ram_block_add(new_block);
+}
+
+ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
+ MemoryRegion *mr)
+{
+ RAMBlock *new_block;
+
+ size = TARGET_PAGE_ALIGN(size);
+ new_block = g_malloc0(sizeof(*new_block));
+ new_block->mr = mr;
+ new_block->length = size;
+ new_block->fd = -1;
+ new_block->host = host;
+ if (host) {
+ new_block->flags |= RAM_PREALLOC_MASK;
+ }
+ return ram_block_add(new_block);
+}
+
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr)
{
return qemu_ram_alloc_from_ptr(size, NULL, mr);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 758a928..dfdd071 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -442,9 +442,6 @@ typedef struct RAMList {
} RAMList;
extern RAMList ram_list;
-extern const char *mem_path;
-extern int mem_prealloc;
-
/* Flags stored in the low bits of the TLB virtual address. These are
defined so that fast path ram access is all zeros. */
/* Zero if TLB entry is valid. */
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 2edfa96..dedb258 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -22,6 +22,8 @@
#ifndef CONFIG_USER_ONLY
#include "hw/xen/xen.h"
+ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
+ const char *mem_path);
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 1e141e3..277230d 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -133,6 +133,8 @@ extern uint8_t *boot_splash_filedata;
extern size_t boot_splash_filedata_size;
extern uint8_t qemu_extra_params_fw[2];
extern QEMUClockType rtc_clock;
+extern const char *mem_path;
+extern int mem_prealloc;
#define MAX_NODES 128
diff --git a/memory.c b/memory.c
index 3f1df23..daaeb7e 100644
--- a/memory.c
+++ b/memory.c
@@ -23,6 +23,7 @@
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
+#include "sysemu/sysemu.h"
//#define DEBUG_UNASSIGNED
@@ -1016,7 +1017,11 @@ void memory_region_init_ram(MemoryRegion *mr,
mr->ram = true;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
- mr->ram_addr = qemu_ram_alloc(size, mr);
+ if (mem_path) {
+ mr->ram_addr = qemu_ram_alloc_from_file(size, mr, mem_path);
+ } else {
+ mr->ram_addr = qemu_ram_alloc(size, mr);
+ }
}
void memory_region_init_ram_ptr(MemoryRegion *mr,
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 15/34] numa: add -numa node,memdev= option
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (13 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 11/34] qmp: improve error reporting for -object and object-add hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 13/34] numa: introduce memory_region_allocate_system_memory hutao
` (18 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
This option provides the infrastructure for binding guest NUMA nodes
to host NUMA nodes. For example:
-object memory-ram,size=1024M,policy=bind,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 node,mem=".
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/sysemu.h | 1 +
numa.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++--
qapi-schema.json | 11 ++++++---
qemu-options.hx | 12 ++++++----
4 files changed, 77 insertions(+), 9 deletions(-)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index caf88dd..1e141e3 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -147,6 +147,7 @@ extern int nb_numa_nodes;
typedef struct node_info {
uint64_t node_mem;
DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
+ struct HostMemoryBackend *node_memdev;
} NodeInfo;
extern NodeInfo numa_info[MAX_NODES];
void set_numa_nodes(void);
diff --git a/numa.c b/numa.c
index bcd7b04..b9850d7 100644
--- a/numa.c
+++ b/numa.c
@@ -34,6 +34,7 @@
#include "qapi/dealloc-visitor.h"
#include "qapi/qmp/qerror.h"
#include "hw/boards.h"
+#include "sysemu/hostmem.h"
QemuOptsList qemu_numa_opts = {
.name = "numa",
@@ -42,6 +43,8 @@ QemuOptsList qemu_numa_opts = {
.desc = { { 0 } } /* validated with OptsVisitor */
};
+static int have_memdevs = -1;
+
static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp)
{
uint16_t nodenr;
@@ -68,6 +71,20 @@ static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp)
bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
}
+ if (node->has_mem && node->has_memdev) {
+ error_setg(errp, "qemu: cannot specify both mem= and memdev=\n");
+ return;
+ }
+
+ if (have_memdevs == -1) {
+ have_memdevs = node->has_memdev;
+ }
+ if (node->has_memdev != have_memdevs) {
+ error_setg(errp, "qemu: memdev option must be specified for either "
+ "all or no nodes\n");
+ return;
+ }
+
if (node->has_mem) {
uint64_t mem_size = node->mem;
const char *mem_str = qemu_opt_get(opts, "mem");
@@ -77,6 +94,18 @@ static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp)
}
numa_info[nodenr].node_mem = mem_size;
}
+ if (node->has_memdev) {
+ Object *o;
+ o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL);
+ if (!o) {
+ error_setg(errp, "memdev=%s is ambiguous", node->memdev);
+ return;
+ }
+
+ object_ref(o);
+ numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL);
+ numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
+ }
}
int numa_init_func(QemuOpts *opts, void *opaque)
@@ -196,10 +225,39 @@ void set_numa_modes(void)
}
}
+static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
+ const char *name,
+ uint64_t 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,
uint64_t ram_size)
{
- memory_region_init_ram(mr, owner, name, ram_size);
- vmstate_register_ram_global(mr);
+ uint64_t addr = 0;
+ int i;
+
+ if (nb_numa_nodes == 0 || !have_memdevs) {
+ allocate_system_memory_nonnuma(mr, owner, name, ram_size);
+ 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 8451d15..a8c16bc 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4708,8 +4708,12 @@
# @cpus: #optional VCPUs belonging to this node (assign VCPUS round-robin
# if omitted)
#
-# @mem: #optional memory size of this node (equally divide total memory among
-# nodes if omitted)
+# @mem: #optional memory size of this node; mutually exclusive with @memdev.
+# Equally divide total memory among nodes if both @mem and @memdev are
+# omitted.
+#
+# @memdev: #optional memory backend object. If specified for one node,
+# it must be specified for all nodes.
#
# Since: 2.1
##
@@ -4717,4 +4721,5 @@
'data': {
'*nodeid': 'uint16',
'*cpus': ['uint16'],
- '*mem': 'size' }}
+ '*mem': 'size',
+ '*memdev': 'str' }}
diff --git a/qemu-options.hx b/qemu-options.hx
index 30faa0e..9f54b63 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -95,16 +95,20 @@ specifies the maximum number of hotpluggable CPUs.
ETEXI
DEF("numa", HAS_ARG, QEMU_OPTION_numa,
- "-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL)
+ "-numa node[,mem=size][,memdev=id][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL)
STEXI
-@item -numa node[,mem=@var{size}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}]
+@item -numa node[,mem=@var{size}][,memdev=@var{id}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}]
@findex -numa
-Simulate a multi node NUMA system. If @samp{mem}
+Simulate a multi node NUMA system. If @samp{mem}, @samp{memdev}
and @samp{cpus} are omitted, resources are split equally. Also, note
that the -@option{numa} option doesn't allocate any of the specified
resources. That is, it just assigns existing resources to NUMA nodes. This
means that one still has to use the @option{-m}, @option{-smp} options
-to respectively allocate RAM and vCPUs.
+to respectively allocate RAM and vCPUs, and possibly @option{-object}
+to specify the memory backend for the @samp{memdev} suboption.
+
+@samp{mem} and @samp{memdev} are mutually exclusive. Furthermore, if one
+node uses @samp{memdev}, all of them have to use it.
ETEXI
DEF("add-fd", HAS_ARG, QEMU_OPTION_add_fd,
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 14/34] add memdev backend infrastructure
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (9 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 10/34] qmp: allow object-add completion handler to get canonical path hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 16/34] memory: reorganize file-based allocation hutao
` (22 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Igor Mammedov <imammedo@redhat.com>
Provides framework for splitting host RAM allocation/
policies into a separate backend that could be used
by devices.
Initially only legacy RAM backend is provided, which
uses memory_region_init_ram() allocator and compatible
with every CLI option that affects memory_region_init_ram().
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/Makefile.objs | 2 +
backends/hostmem-ram.c | 52 ++++++++++++++++++++++
backends/hostmem.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/hostmem.h | 59 +++++++++++++++++++++++++
4 files changed, 222 insertions(+)
create mode 100644 backends/hostmem-ram.c
create mode 100644 backends/hostmem.c
create mode 100644 include/sysemu/hostmem.h
diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 42557d5..e6bdc11 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -6,3 +6,5 @@ common-obj-$(CONFIG_BRLAPI) += baum.o
$(obj)/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
common-obj-$(CONFIG_TPM) += tpm.o
+
+common-obj-y += hostmem.o hostmem-ram.o
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
new file mode 100644
index 0000000..ce06fbe
--- /dev/null
+++ b/backends/hostmem-ram.c
@@ -0,0 +1,52 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ * Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "qom/object_interfaces.h"
+
+#define TYPE_MEMORY_BACKEND_RAM "memory-ram"
+
+
+static void
+ram_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+
+ if (!backend->size) {
+ error_setg(errp, "can't create backend with size 0");
+ return;
+ }
+
+ memory_region_init_ram(&backend->mr, OBJECT(backend),
+ object_get_canonical_path(OBJECT(backend)),
+ backend->size);
+}
+
+static void
+ram_backend_class_init(ObjectClass *oc, void *data)
+{
+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+ ucc->complete = ram_backend_memory_init;
+}
+
+static const TypeInfo ram_backend_info = {
+ .name = TYPE_MEMORY_BACKEND_RAM,
+ .parent = TYPE_MEMORY_BACKEND,
+ .class_init = ram_backend_class_init,
+};
+
+static void register_types(void)
+{
+ type_register_static(&ram_backend_info);
+}
+
+type_init(register_types);
diff --git a/backends/hostmem.c b/backends/hostmem.c
new file mode 100644
index 0000000..6f26605
--- /dev/null
+++ b/backends/hostmem.c
@@ -0,0 +1,109 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ * Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
+#include "qapi/qmp/qerror.h"
+#include "qom/object_interfaces.h"
+
+static void
+host_memory_backend_get_size(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ uint64_t value = backend->size;
+
+ visit_type_size(v, &value, name, errp);
+}
+
+static void
+host_memory_backend_set_size(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ uint64_t value;
+
+ if (memory_region_size(&backend->mr)) {
+ error_setg(errp, "cannot change property value\n");
+ return;
+ }
+
+ visit_type_size(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+ if (!value) {
+ error_setg(errp, "Property '%s.%s' doesn't take value '%" PRIu64 "'",
+ object_get_typename(obj), name , value);
+ return;
+ }
+ backend->size = value;
+}
+
+static void host_memory_backend_initfn(Object *obj)
+{
+ object_property_add(obj, "size", "int",
+ host_memory_backend_get_size,
+ host_memory_backend_set_size, NULL, NULL, NULL);
+}
+
+static void host_memory_backend_finalize(Object *obj)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ if (memory_region_size(&backend->mr)) {
+ memory_region_destroy(&backend->mr);
+ }
+}
+
+static void
+host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+ error_setg(errp, "memory_init is not implemented for type [%s]",
+ object_get_typename(OBJECT(uc)));
+}
+
+MemoryRegion *
+host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
+{
+ return memory_region_size(&backend->mr) ? &backend->mr : NULL;
+}
+
+static void
+host_memory_backend_class_init(ObjectClass *oc, void *data)
+{
+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+ ucc->complete = host_memory_backend_memory_init;
+}
+
+static const TypeInfo host_memory_backend_info = {
+ .name = TYPE_MEMORY_BACKEND,
+ .parent = TYPE_OBJECT,
+ .abstract = true,
+ .class_size = sizeof(HostMemoryBackendClass),
+ .class_init = host_memory_backend_class_init,
+ .instance_size = sizeof(HostMemoryBackend),
+ .instance_init = host_memory_backend_initfn,
+ .instance_finalize = host_memory_backend_finalize,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+static void register_types(void)
+{
+ type_register_static(&host_memory_backend_info);
+}
+
+type_init(register_types);
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
new file mode 100644
index 0000000..8b1eb7d
--- /dev/null
+++ b/include/sysemu/hostmem.h
@@ -0,0 +1,59 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ * Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_HOSTMEM_H
+#define QEMU_HOSTMEM_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "exec/memory.h"
+
+#define TYPE_MEMORY_BACKEND "memory"
+#define MEMORY_BACKEND(obj) \
+ OBJECT_CHECK(HostMemoryBackend, (obj), TYPE_MEMORY_BACKEND)
+#define MEMORY_BACKEND_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(HostMemoryBackendClass, (obj), TYPE_MEMORY_BACKEND)
+#define MEMORY_BACKEND_CLASS(klass) \
+ OBJECT_CLASS_CHECK(HostMemoryBackendClass, (klass), TYPE_MEMORY_BACKEND)
+
+typedef struct HostMemoryBackend HostMemoryBackend;
+typedef struct HostMemoryBackendClass HostMemoryBackendClass;
+
+/**
+ * HostMemoryBackendClass:
+ * @parent_class: opaque parent class container
+ */
+struct HostMemoryBackendClass {
+ ObjectClass parent_class;
+};
+
+/**
+ * @HostMemoryBackend
+ *
+ * @parent: opaque parent object container
+ * @size: amount of memory backend provides
+ * @id: unique identification string in memdev namespace
+ * @mr: MemoryRegion representing host memory belonging to backend
+ */
+struct HostMemoryBackend {
+ /* private */
+ Object parent;
+
+ /* protected */
+ uint64_t size;
+
+ MemoryRegion mr;
+};
+
+MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend,
+ Error **errp);
+
+#endif
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 11/34] qmp: improve error reporting for -object and object-add
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (12 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 12/34] pc: pass QEMUMachineInitArgs to pc_memory_init hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 15/34] numa: add -numa node,memdev= option hutao
` (19 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Use QERR_INVALID_PARAMETER_VALUE for consistency.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qmp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/qmp.c b/qmp.c
index 54b95ba..440f3ab 100644
--- a/qmp.c
+++ b/qmp.c
@@ -544,7 +544,8 @@ void object_add(const char *type, const char *id, const QDict *qdict,
Error *local_err = NULL;
if (!object_class_by_name(type)) {
- error_setg(errp, "invalid class name");
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+ "qom-type", "a valid class name");
return;
}
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 13/34] numa: introduce memory_region_allocate_system_memory
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (14 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 15/34] numa: add -numa node,memdev= option hutao
@ 2014-03-26 10:36 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 23/34] hostmem: add merge and dump properties hutao
` (17 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:36 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
hw/i386/pc.c | 4 +---
include/hw/boards.h | 6 +++++-
include/sysemu/sysemu.h | 1 +
numa.c | 9 +++++++++
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d5fb884..571dc72 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1181,9 +1181,7 @@ FWCfgState *pc_memory_init(QEMUMachineInitArgs *args,
* with older qemus that used qemu_ram_alloc().
*/
ram = g_malloc(sizeof(*ram));
- memory_region_init_ram(ram, NULL, "pc.ram",
- below_4g_mem_size + above_4g_mem_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "pc.ram", args->ram_size);
*ram_memory = ram;
ram_below_4g = g_malloc(sizeof(*ram_below_4g));
memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", ram,
diff --git a/include/hw/boards.h b/include/hw/boards.h
index dd2c70d..1ea52c0 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -50,9 +50,13 @@ struct QEMUMachine {
const char *hw_version;
};
-#define TYPE_MACHINE_SUFFIX "-machine"
+void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+ const char *name,
+ uint64_t ram_size);
+
int qemu_register_machine(QEMUMachine *m);
+#define TYPE_MACHINE_SUFFIX "-machine"
#define TYPE_MACHINE "machine"
#undef MACHINE /* BSD defines it and QEMU does not use it */
#define MACHINE(obj) \
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 423d49e..caf88dd 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -10,6 +10,7 @@
#include "qemu/notify.h"
#include "qemu/main-loop.h"
#include "qemu/bitmap.h"
+#include "qom/object.h"
/* vl.c */
diff --git a/numa.c b/numa.c
index 439df87..bcd7b04 100644
--- a/numa.c
+++ b/numa.c
@@ -33,6 +33,7 @@
#include "qapi/opts-visitor.h"
#include "qapi/dealloc-visitor.h"
#include "qapi/qmp/qerror.h"
+#include "hw/boards.h"
QemuOptsList qemu_numa_opts = {
.name = "numa",
@@ -194,3 +195,11 @@ void set_numa_modes(void)
}
}
}
+
+void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+ const char *name,
+ uint64_t ram_size)
+{
+ memory_region_init_ram(mr, owner, name, ram_size);
+ vmstate_register_ram_global(mr);
+}
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 18/34] memory: add error propagation to file-based RAM allocation
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (20 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 17/34] memory: move mem_path handling to memory_region_allocate_system_memory hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 19/34] memory: move preallocation code out of exec.c hutao
` (11 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Right now, -mem-path will fall back to RAM-based allocation in some
cases. This should never happen with "-object memory-file", prepare
the code by adding correct error propagation.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
exec.c | 36 ++++++++++++++++++++++++------------
include/exec/memory.h | 5 ++++-
include/exec/ram_addr.h | 2 +-
memory.c | 5 +++--
numa.c | 13 ++++++++++++-
5 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/exec.c b/exec.c
index 379472d..1e51b2f 100644
--- a/exec.c
+++ b/exec.c
@@ -1021,7 +1021,8 @@ static void sigbus_handler(int signal)
static void *file_ram_alloc(RAMBlock *block,
ram_addr_t memory,
- const char *path)
+ const char *path,
+ Error **errp)
{
char *filename;
char *sanitized_name;
@@ -1040,7 +1041,8 @@ static void *file_ram_alloc(RAMBlock *block,
}
if (kvm_enabled() && !kvm_has_sync_mmu()) {
- fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n");
+ error_setg(errp,
+ "host lacks kvm mmu notifiers, -mem-path unsupported\n");
goto error;
}
@@ -1057,7 +1059,8 @@ static void *file_ram_alloc(RAMBlock *block,
fd = mkstemp(filename);
if (fd < 0) {
- perror("unable to create backing store for hugepages");
+ error_setg_errno(errp, errno,
+ "unable to create backing store for hugepages");
g_free(filename);
goto error;
}
@@ -1072,12 +1075,14 @@ static void *file_ram_alloc(RAMBlock *block,
* If anything goes wrong with it under other filesystems,
* mmap will fail.
*/
- if (ftruncate(fd, memory))
+ if (ftruncate(fd, memory)) {
perror("ftruncate");
+ }
area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (area == MAP_FAILED) {
- perror("file_ram_alloc: can't mmap RAM pages");
+ error_setg_errno(errp, errno,
+ "unable to map backing store for hugepages");
close(fd);
goto error;
}
@@ -1305,13 +1310,14 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
#ifdef __linux__
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
- const char *mem_path)
+ const char *mem_path,
+ Error **errp)
{
RAMBlock *new_block;
if (xen_enabled()) {
- fprintf(stderr, "-mem-path not supported with Xen\n");
- exit(1);
+ error_setg(errp, "-mem-path not supported with Xen\n");
+ return -1;
}
if (phys_mem_alloc != qemu_anon_ram_alloc) {
@@ -1320,16 +1326,22 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
* phys_mem_alloc, but we haven't bothered to provide
* a hook there.
*/
- fprintf(stderr,
- "-mem-path not supported with this accelerator\n");
- exit(1);
+ error_setg(errp,
+ "-mem-path not supported with this accelerator\n");
+ return -1;
}
size = TARGET_PAGE_ALIGN(size);
new_block = g_malloc0(sizeof(*new_block));
new_block->mr = mr;
new_block->length = size;
- new_block->host = file_ram_alloc(new_block, size, mem_path);
+ new_block->host = file_ram_alloc(new_block, size,
+ mem_path, errp);
+ if (!new_block->host) {
+ g_free(new_block);
+ return -1;
+ }
+
return ram_block_add(new_block);
}
#endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 75d4635..4e606dd 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -31,6 +31,7 @@
#include "qemu/queue.h"
#include "qemu/int128.h"
#include "qemu/notify.h"
+#include "qapi/error.h"
#define MAX_PHYS_ADDR_SPACE_BITS 62
#define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
@@ -321,12 +322,14 @@ void memory_region_init_ram(MemoryRegion *mr,
* @name: the name of the region.
* @size: size of the region.
* @path: the path in which to allocate the RAM.
+ * @errp: pointer to Error*, to store an error if it happens.
*/
void memory_region_init_ram_from_file(MemoryRegion *mr,
struct Object *owner,
const char *name,
uint64_t size,
- const char *path);
+ const char *path,
+ Error **errp);
#endif
/**
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index dedb258..f9518a6 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -23,7 +23,7 @@
#include "hw/xen/xen.h"
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
- const char *mem_path);
+ const char *mem_path, Error **errp);
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
diff --git a/memory.c b/memory.c
index 677b8f3..6b0c116 100644
--- a/memory.c
+++ b/memory.c
@@ -1025,13 +1025,14 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
struct Object *owner,
const char *name,
uint64_t size,
- const char *path)
+ const char *path,
+ Error **errp)
{
memory_region_init(mr, owner, name, size);
mr->ram = true;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
- mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path);
+ mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path, errp);
}
#endif
diff --git a/numa.c b/numa.c
index e136612..966cacc 100644
--- a/numa.c
+++ b/numa.c
@@ -231,7 +231,18 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
{
if (mem_path) {
#ifdef __linux__
- memory_region_init_ram_from_file(mr, owner, name, ram_size, mem_path);
+ Error *err = NULL;
+ memory_region_init_ram_from_file(mr, owner, name, ram_size,
+ mem_path, &err);
+
+ /* Legacy behavior: if allocation failed, fall back to
+ * regular RAM allocation.
+ */
+ if (!memory_region_size(mr)) {
+ qerror_report_err(err);
+ error_free(err);
+ memory_region_init_ram(mr, owner, name, ram_size);
+ }
#else
fprintf(stderr, "-mem-path not supported on this host\n");
exit(1);
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 21/34] hostmem: add file-based HostMemoryBackend
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (16 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 23/34] hostmem: add merge and dump properties hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 20/34] memory: move RAM_PREALLOC_MASK to exec.c, rename hutao
` (15 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/Makefile.objs | 1 +
backends/hostmem-file.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 109 insertions(+)
create mode 100644 backends/hostmem-file.c
diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index e6bdc11..509e4a3 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -8,3 +8,4 @@ $(obj)/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
common-obj-$(CONFIG_TPM) += tpm.o
common-obj-y += hostmem.o hostmem-ram.o
+common-obj-$(CONFIG_LINUX) += hostmem-file.o
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
new file mode 100644
index 0000000..e22bcef
--- /dev/null
+++ b/backends/hostmem-file.c
@@ -0,0 +1,108 @@
+/*
+ * QEMU Host Memory Backend for hugetlbfs
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ * Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "qom/object_interfaces.h"
+
+/* hostmem-file.c */
+/**
+ * @TYPE_MEMORY_BACKEND_FILE:
+ * name of backend that uses mmap on a file descriptor
+ */
+#define TYPE_MEMORY_BACKEND_FILE "memory-file"
+
+#define MEMORY_BACKEND_FILE(obj) \
+ OBJECT_CHECK(HostMemoryBackendFile, (obj), TYPE_MEMORY_BACKEND_FILE)
+
+typedef struct HostMemoryBackendFile HostMemoryBackendFile;
+
+struct HostMemoryBackendFile {
+ HostMemoryBackend parent_obj;
+ char *mem_path;
+};
+
+static void
+file_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(uc);
+
+ if (!backend->size) {
+ error_setg(errp, "can't create backend with size 0");
+ return;
+ }
+ if (!fb->mem_path) {
+ error_setg(errp, "mem-path property not set");
+ return;
+ }
+#ifndef CONFIG_LINUX
+ error_setg(errp, "-mem-path not supported on this host");
+#else
+ if (!memory_region_size(&backend->mr)) {
+ memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
+ object_get_canonical_path(OBJECT(backend)),
+ backend->size,
+ fb->mem_path, errp);
+ }
+#endif
+}
+
+static void
+file_backend_class_init(ObjectClass *oc, void *data)
+{
+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+ ucc->complete = file_backend_memory_init;
+}
+
+static char *get_mem_path(Object *o, Error **errp)
+{
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+ return g_strdup(fb->mem_path);
+}
+
+static void set_mem_path(Object *o, const char *str, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(o);
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+ if (memory_region_size(&backend->mr)) {
+ error_setg(errp, "cannot change property value");
+ return;
+ }
+ if (fb->mem_path) {
+ g_free(fb->mem_path);
+ }
+ fb->mem_path = g_strdup(str);
+}
+
+static void
+file_backend_instance_init(Object *o)
+{
+ object_property_add_str(o, "mem-path", get_mem_path,
+ set_mem_path, NULL);
+}
+
+static const TypeInfo file_backend_info = {
+ .name = TYPE_MEMORY_BACKEND_FILE,
+ .parent = TYPE_MEMORY_BACKEND,
+ .class_init = file_backend_class_init,
+ .instance_init = file_backend_instance_init,
+ .instance_size = sizeof(HostMemoryBackendFile),
+};
+
+static void register_types(void)
+{
+ type_register_static(&file_backend_info);
+}
+
+type_init(register_types);
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 22/34] hostmem: separate allocation from UserCreatable complete method
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (18 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 20/34] memory: move RAM_PREALLOC_MASK to exec.c, rename hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 17/34] memory: move mem_path handling to memory_region_allocate_system_memory hutao
` (13 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
This allows the superclass to set various policies on the memory
region that the subclass creates.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem-file.c | 9 ++++-----
backends/hostmem-ram.c | 8 +++-----
backends/hostmem.c | 12 ++++++++++--
include/sysemu/hostmem.h | 2 ++
4 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index e22bcef..75a165a 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -30,10 +30,9 @@ struct HostMemoryBackendFile {
};
static void
-file_backend_memory_init(UserCreatable *uc, Error **errp)
+file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
{
- HostMemoryBackend *backend = MEMORY_BACKEND(uc);
- HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(uc);
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
if (!backend->size) {
error_setg(errp, "can't create backend with size 0");
@@ -58,9 +57,9 @@ file_backend_memory_init(UserCreatable *uc, Error **errp)
static void
file_backend_class_init(ObjectClass *oc, void *data)
{
- UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
- ucc->complete = file_backend_memory_init;
+ bc->alloc = file_backend_memory_alloc;
}
static char *get_mem_path(Object *o, Error **errp)
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index ce06fbe..e4d244a 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -16,10 +16,8 @@
static void
-ram_backend_memory_init(UserCreatable *uc, Error **errp)
+ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
{
- HostMemoryBackend *backend = MEMORY_BACKEND(uc);
-
if (!backend->size) {
error_setg(errp, "can't create backend with size 0");
return;
@@ -33,9 +31,9 @@ ram_backend_memory_init(UserCreatable *uc, Error **errp)
static void
ram_backend_class_init(ObjectClass *oc, void *data)
{
- UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
- ucc->complete = ram_backend_memory_init;
+ bc->alloc = ram_backend_memory_alloc;
}
static const TypeInfo ram_backend_info = {
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 6f26605..5b2117d 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -68,8 +68,16 @@ static void host_memory_backend_finalize(Object *obj)
static void
host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
{
- error_setg(errp, "memory_init is not implemented for type [%s]",
- object_get_typename(OBJECT(uc)));
+ HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
+
+ if (!bc->alloc) {
+ error_setg(errp, "memory_alloc is not implemented for type [%s]",
+ object_get_typename(OBJECT(uc)));
+ return;
+ }
+
+ bc->alloc(backend, errp);
}
MemoryRegion *
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 8b1eb7d..9a9e0cd 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -33,6 +33,8 @@ typedef struct HostMemoryBackendClass HostMemoryBackendClass;
*/
struct HostMemoryBackendClass {
ObjectClass parent_class;
+
+ void (*alloc)(HostMemoryBackend *backend, Error **errp);
};
/**
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 23/34] hostmem: add merge and dump properties
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (15 preceding siblings ...)
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 13/34] numa: introduce memory_region_allocate_system_memory hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 21/34] hostmem: add file-based HostMemoryBackend hutao
` (16 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++-
include/qemu/osdep.h | 10 ++++++
include/sysemu/hostmem.h | 1 +
3 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 5b2117d..3e5ebfc 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -49,8 +49,74 @@ host_memory_backend_set_size(Object *obj, Visitor *v, void *opaque,
backend->size = value;
}
+static bool host_memory_backend_get_merge(Object *obj, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ return backend->merge;
+}
+
+static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ if (!memory_region_size(&backend->mr)) {
+ backend->merge = value;
+ return;
+ }
+
+ if (value != backend->merge) {
+ void *ptr = memory_region_get_ram_ptr(&backend->mr);
+ uint64_t sz = memory_region_size(&backend->mr);
+
+ qemu_madvise(ptr, sz,
+ value ? QEMU_MADV_MERGEABLE : QEMU_MADV_UNMERGEABLE);
+ backend->merge = value;
+ }
+}
+
+static bool host_memory_backend_get_dump(Object *obj, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ return backend->dump;
+}
+
+static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ if (!memory_region_size(&backend->mr)) {
+ backend->dump = value;
+ return;
+ }
+
+ if (value != backend->dump) {
+ void *ptr = memory_region_get_ram_ptr(&backend->mr);
+ uint64_t sz = memory_region_size(&backend->mr);
+
+ qemu_madvise(ptr, sz,
+ value ? QEMU_MADV_DODUMP : QEMU_MADV_DONTDUMP);
+ backend->dump = value;
+ }
+}
+
+
static void host_memory_backend_initfn(Object *obj)
{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ backend->merge = qemu_opt_get_bool(qemu_get_machine_opts(),
+ "mem-merge", true);
+ backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(),
+ "dump-guest-core", true);
+
+ object_property_add_bool(obj, "merge",
+ host_memory_backend_get_merge,
+ host_memory_backend_set_merge, NULL);
+ object_property_add_bool(obj, "dump",
+ host_memory_backend_get_dump,
+ host_memory_backend_set_dump, NULL);
object_property_add(obj, "size", "int",
host_memory_backend_get_size,
host_memory_backend_set_size, NULL, NULL, NULL);
@@ -70,6 +136,9 @@ host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(uc);
HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
+ Error *local_err = NULL;
+ void *ptr;
+ uint64_t sz;
if (!bc->alloc) {
error_setg(errp, "memory_alloc is not implemented for type [%s]",
@@ -77,7 +146,21 @@ host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
return;
}
- bc->alloc(backend, errp);
+ bc->alloc(backend, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ ptr = memory_region_get_ram_ptr(&backend->mr);
+ sz = memory_region_size(&backend->mr);
+
+ if (backend->merge) {
+ qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
+ }
+ if (!backend->dump) {
+ qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
+ }
}
MemoryRegion *
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 9c1a119..820c5d0 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -116,6 +116,16 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#else
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
#endif
+#ifdef MADV_UNMERGEABLE
+#define QEMU_MADV_UNMERGEABLE MADV_UNMERGEABLE
+#else
+#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
+#endif
+#ifdef MADV_DODUMP
+#define QEMU_MADV_DODUMP MADV_DODUMP
+#else
+#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
+#endif
#ifdef MADV_DONTDUMP
#define QEMU_MADV_DONTDUMP MADV_DONTDUMP
#else
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 9a9e0cd..9d5eed4 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -51,6 +51,7 @@ struct HostMemoryBackend {
/* protected */
uint64_t size;
+ bool merge, dump;
MemoryRegion mr;
};
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 20/34] memory: move RAM_PREALLOC_MASK to exec.c, rename
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (17 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 21/34] hostmem: add file-based HostMemoryBackend hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 22/34] hostmem: separate allocation from UserCreatable complete method hutao
` (14 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Prepare for adding more flags. The "_MASK" suffix is unique, kill it.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
exec.c | 9 ++++++---
include/exec/cpu-all.h | 3 ---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/exec.c b/exec.c
index 710e025..691d216 100644
--- a/exec.c
+++ b/exec.c
@@ -70,6 +70,9 @@ AddressSpace address_space_memory;
MemoryRegion io_mem_rom, io_mem_notdirty;
static MemoryRegion io_mem_unassigned;
+/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
+#define RAM_PREALLOC (1 << 0)
+
#endif
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
@@ -1316,7 +1319,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
new_block->fd = -1;
new_block->host = host;
if (host) {
- new_block->flags |= RAM_PREALLOC_MASK;
+ new_block->flags |= RAM_PREALLOC;
}
return ram_block_add(new_block);
}
@@ -1355,7 +1358,7 @@ void qemu_ram_free(ram_addr_t addr)
QTAILQ_REMOVE(&ram_list.blocks, block, next);
ram_list.mru_block = NULL;
ram_list.version++;
- if (block->flags & RAM_PREALLOC_MASK) {
+ if (block->flags & RAM_PREALLOC) {
;
} else if (xen_enabled()) {
xen_invalidate_map_cache_entry(block->host);
@@ -1387,7 +1390,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
offset = addr - block->offset;
if (offset < block->length) {
vaddr = block->host + offset;
- if (block->flags & RAM_PREALLOC_MASK) {
+ if (block->flags & RAM_PREALLOC) {
;
} else if (xen_enabled()) {
abort();
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index dfdd071..6960544 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -414,9 +414,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
/* memory API */
-/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
-#define RAM_PREALLOC_MASK (1 << 0)
-
typedef struct RAMBlock {
struct MemoryRegion *mr;
uint8_t *host;
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 19/34] memory: move preallocation code out of exec.c
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (21 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 18/34] memory: add error propagation to file-based RAM allocation hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 24/34] hostmem: allow preallocation of any memory region hutao
` (10 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
So that backends can use it.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
exec.c | 44 +------------------------------
include/qemu/osdep.h | 2 ++
util/oslib-posix.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 76 insertions(+), 43 deletions(-)
diff --git a/exec.c b/exec.c
index 1e51b2f..710e025 100644
--- a/exec.c
+++ b/exec.c
@@ -1012,13 +1012,6 @@ static long gethugepagesize(const char *path)
return fs.f_bsize;
}
-static sigjmp_buf sigjump;
-
-static void sigbus_handler(int signal)
-{
- siglongjmp(sigjump, 1);
-}
-
static void *file_ram_alloc(RAMBlock *block,
ram_addr_t memory,
const char *path,
@@ -1088,42 +1081,7 @@ static void *file_ram_alloc(RAMBlock *block,
}
if (mem_prealloc) {
- int ret, i;
- struct sigaction act, oldact;
- sigset_t set, oldset;
-
- memset(&act, 0, sizeof(act));
- act.sa_handler = &sigbus_handler;
- act.sa_flags = 0;
-
- ret = sigaction(SIGBUS, &act, &oldact);
- if (ret) {
- perror("file_ram_alloc: failed to install signal handler");
- exit(1);
- }
-
- /* unblock SIGBUS */
- sigemptyset(&set);
- sigaddset(&set, SIGBUS);
- pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
-
- if (sigsetjmp(sigjump, 1)) {
- fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
- exit(1);
- }
-
- /* MAP_POPULATE silently ignores failures */
- for (i = 0; i < (memory/hpagesize); i++) {
- memset(area + (hpagesize*i), 0, 1);
- }
-
- ret = sigaction(SIGBUS, &oldact, NULL);
- if (ret) {
- perror("file_ram_alloc: failed to reinstall signal handler");
- exit(1);
- }
-
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ os_mem_prealloc(fd, area, memory);
}
block->fd = fd;
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ffb2966..9c1a119 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -251,4 +251,6 @@ void qemu_init_auxval(char **envp);
void qemu_set_tty_echo(int fd, bool echo);
+void os_mem_prealloc(int fd, char *area, size_t sz);
+
#endif
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 8e9c770..a22c97d 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -46,6 +46,7 @@ extern int daemon(int, int);
#else
# define QEMU_VMALLOC_ALIGN getpagesize()
#endif
+#define HUGETLBFS_MAGIC 0x958458f6
#include <termios.h>
#include <unistd.h>
@@ -58,9 +59,12 @@ extern int daemon(int, int);
#include "qemu/sockets.h"
#include <sys/mman.h>
#include <libgen.h>
+#include <setjmp.h>
+#include <sys/signal.h>
#ifdef CONFIG_LINUX
#include <sys/syscall.h>
+#include <sys/vfs.h>
#endif
#ifdef __FreeBSD__
@@ -332,3 +336,72 @@ char *qemu_get_exec_dir(void)
{
return g_strdup(exec_dir);
}
+
+static sigjmp_buf sigjump;
+
+static void sigbus_handler(int signal)
+{
+ siglongjmp(sigjump, 1);
+}
+
+static size_t fd_getpagesize(int fd)
+{
+#ifdef CONFIG_LINUX
+ struct statfs fs;
+ int ret;
+
+ if (fd != -1) {
+ do {
+ ret = fstatfs(fd, &fs);
+ } while (ret != 0 && errno == EINTR);
+
+ if (ret == 0 && fs.f_type == HUGETLBFS_MAGIC) {
+ return fs.f_bsize;
+ }
+ }
+#endif
+
+ return getpagesize();
+}
+
+void os_mem_prealloc(int fd, char *area, size_t memory)
+{
+ int ret, i;
+ struct sigaction act, oldact;
+ sigset_t set, oldset;
+ size_t hpagesize = fd_getpagesize(fd);
+
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = &sigbus_handler;
+ act.sa_flags = 0;
+
+ ret = sigaction(SIGBUS, &act, &oldact);
+ if (ret) {
+ perror("file_ram_alloc: failed to install signal handler");
+ exit(1);
+ }
+
+ /* unblock SIGBUS */
+ sigemptyset(&set);
+ sigaddset(&set, SIGBUS);
+ pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
+
+ if (sigsetjmp(sigjump, 1)) {
+ fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
+ exit(1);
+ }
+
+ /* MAP_POPULATE silently ignores failures */
+ memory = (memory + hpagesize - 1) & -hpagesize;
+ for (i = 0; i < (memory/hpagesize); i++) {
+ memset(area + (hpagesize*i), 0, 1);
+ }
+
+ ret = sigaction(SIGBUS, &oldact, NULL);
+ if (ret) {
+ perror("file_ram_alloc: failed to reinstall signal handler");
+ exit(1);
+ }
+
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+}
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 17/34] memory: move mem_path handling to memory_region_allocate_system_memory
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (19 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 22/34] hostmem: separate allocation from UserCreatable complete method hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 18/34] memory: add error propagation to file-based RAM allocation hutao
` (12 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
Like the previous patch did in exec.c, split memory_region_init_ram and
memory_region_init_ram_from_file, and push mem_path one step further up.
Other RAM regions than system memory will now be backed by regular RAM.
Also, boards that do not use memory_region_allocate_system_memory will
not support -mem-path anymore. This can be changed before the patches
are merged by migrating boards to use the function.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
exec.c | 10 ++--------
include/exec/memory.h | 18 ++++++++++++++++++
memory.c | 21 ++++++++++++++++-----
numa.c | 11 ++++++++++-
4 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/exec.c b/exec.c
index 8ae8b95..379472d 100644
--- a/exec.c
+++ b/exec.c
@@ -1130,14 +1130,6 @@ error:
}
return NULL;
}
-#else
-static void *file_ram_alloc(RAMBlock *block,
- ram_addr_t memory,
- const char *path)
-{
- fprintf(stderr, "-mem-path not supported on this host\n");
- exit(1);
-}
#endif
static ram_addr_t find_ram_offset(ram_addr_t size)
@@ -1311,6 +1303,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
return new_block->offset;
}
+#ifdef __linux__
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
const char *mem_path)
{
@@ -1339,6 +1332,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
new_block->host = file_ram_alloc(new_block, size, mem_path);
return ram_block_add(new_block);
}
+#endif
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index c084db2..75d4635 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -311,6 +311,24 @@ void memory_region_init_ram(MemoryRegion *mr,
const char *name,
uint64_t size);
+#ifdef __linux__
+/**
+ * memory_region_init_ram_from_file: Initialize RAM memory region with a
+ * mmap-ed backend.
+ *
+ * @mr: the #MemoryRegion to be initialized.
+ * @owner: the object that tracks the region's reference count
+ * @name: the name of the region.
+ * @size: size of the region.
+ * @path: the path in which to allocate the RAM.
+ */
+void memory_region_init_ram_from_file(MemoryRegion *mr,
+ struct Object *owner,
+ const char *name,
+ uint64_t size,
+ const char *path);
+#endif
+
/**
* memory_region_init_ram_ptr: Initialize RAM memory region from a
* user-provided pointer. Accesses into the
diff --git a/memory.c b/memory.c
index daaeb7e..677b8f3 100644
--- a/memory.c
+++ b/memory.c
@@ -1017,13 +1017,24 @@ void memory_region_init_ram(MemoryRegion *mr,
mr->ram = true;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
- if (mem_path) {
- mr->ram_addr = qemu_ram_alloc_from_file(size, mr, mem_path);
- } else {
- mr->ram_addr = qemu_ram_alloc(size, mr);
- }
+ mr->ram_addr = qemu_ram_alloc(size, mr);
}
+#ifdef __linux__
+void memory_region_init_ram_from_file(MemoryRegion *mr,
+ struct Object *owner,
+ const char *name,
+ uint64_t size,
+ const char *path)
+{
+ memory_region_init(mr, owner, name, size);
+ mr->ram = true;
+ mr->terminates = true;
+ mr->destructor = memory_region_destructor_ram;
+ mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path);
+}
+#endif
+
void memory_region_init_ram_ptr(MemoryRegion *mr,
Object *owner,
const char *name,
diff --git a/numa.c b/numa.c
index b9850d7..e136612 100644
--- a/numa.c
+++ b/numa.c
@@ -229,7 +229,16 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
const char *name,
uint64_t ram_size)
{
- memory_region_init_ram(mr, owner, name, ram_size);
+ if (mem_path) {
+#ifdef __linux__
+ memory_region_init_ram_from_file(mr, owner, name, ram_size, mem_path);
+#else
+ fprintf(stderr, "-mem-path not supported on this host\n");
+ exit(1);
+#endif
+ } else {
+ memory_region_init_ram(mr, owner, name, ram_size);
+ }
vmstate_register_ram_global(mr);
}
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 24/34] hostmem: allow preallocation of any memory region
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (22 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 19/34] memory: move preallocation code out of exec.c hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 26/34] configure: add Linux libnuma detection hutao
` (9 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
And allow preallocation of file-based memory even without -mem-prealloc.
Some care is necessary because -mem-prealloc does not allow disabling
preallocation for hostmem-file.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem-file.c | 3 +++
backends/hostmem.c | 42 ++++++++++++++++++++++++++++++++++++++++++
exec.c | 7 +++++++
include/exec/memory.h | 10 ++++++++++
include/exec/ram_addr.h | 1 +
include/sysemu/hostmem.h | 1 +
memory.c | 11 +++++++++++
7 files changed, 75 insertions(+)
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 75a165a..67328b9 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -9,7 +9,9 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
+#include "qemu-common.h"
#include "sysemu/hostmem.h"
+#include "sysemu/sysemu.h"
#include "qom/object_interfaces.h"
/* hostmem-file.c */
@@ -46,6 +48,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
error_setg(errp, "-mem-path not supported on this host");
#else
if (!memory_region_size(&backend->mr)) {
+ backend->force_prealloc = mem_prealloc;
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
object_get_canonical_path(OBJECT(backend)),
backend->size,
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 3e5ebfc..738bb31 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -101,6 +101,41 @@ static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp)
}
}
+static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ return backend->prealloc || backend->force_prealloc;
+}
+
+static void host_memory_backend_set_prealloc(Object *obj, bool value,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ if (backend->force_prealloc) {
+ if (value) {
+ error_setg(errp,
+ "remove -mem-prealloc to use the prealloc property");
+ return;
+ }
+ }
+
+ if (!memory_region_size(&backend->mr)) {
+ backend->prealloc = value;
+ return;
+ }
+
+ if (value && !backend->prealloc) {
+ int fd = memory_region_get_fd(&backend->mr);
+ void *ptr = memory_region_get_ram_ptr(&backend->mr);
+ uint64_t sz = memory_region_size(&backend->mr);
+
+ os_mem_prealloc(fd, ptr, sz);
+ backend->prealloc = true;
+ }
+}
+
static void host_memory_backend_initfn(Object *obj)
{
@@ -110,6 +145,7 @@ static void host_memory_backend_initfn(Object *obj)
"mem-merge", true);
backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(),
"dump-guest-core", true);
+ backend->prealloc = mem_prealloc;
object_property_add_bool(obj, "merge",
host_memory_backend_get_merge,
@@ -117,6 +153,9 @@ static void host_memory_backend_initfn(Object *obj)
object_property_add_bool(obj, "dump",
host_memory_backend_get_dump,
host_memory_backend_set_dump, NULL);
+ object_property_add_bool(obj, "prealloc",
+ host_memory_backend_get_prealloc,
+ host_memory_backend_set_prealloc, NULL);
object_property_add(obj, "size", "int",
host_memory_backend_get_size,
host_memory_backend_set_size, NULL, NULL, NULL);
@@ -161,6 +200,9 @@ host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
if (!backend->dump) {
qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
}
+ if (backend->prealloc) {
+ os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
+ }
}
MemoryRegion *
diff --git a/exec.c b/exec.c
index 691d216..fab45b5 100644
--- a/exec.c
+++ b/exec.c
@@ -1433,6 +1433,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
}
#endif /* !_WIN32 */
+int qemu_get_ram_fd(ram_addr_t addr)
+{
+ RAMBlock *block = qemu_get_ram_block(addr);
+
+ return block->fd;
+}
+
/* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should
only be used for local memory (e.g. video ram) that the device owns,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 4e606dd..846834e 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -534,6 +534,16 @@ bool memory_region_is_logging(MemoryRegion *mr);
bool memory_region_is_rom(MemoryRegion *mr);
/**
+ * memory_region_get_fd: Get a file descriptor backing a RAM memory region.
+ *
+ * Returns a file descriptor backing a file-based RAM memory region,
+ * or -1 if the region is not a file-based RAM memory region.
+ *
+ * @mr: the RAM or alias memory region being queried.
+ */
+int memory_region_get_fd(MemoryRegion *mr);
+
+/**
* memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
*
* Returns a host pointer to a RAM memory region (created with
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index f9518a6..d352f60 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -27,6 +27,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
+int qemu_get_ram_fd(ram_addr_t addr);
void *qemu_get_ram_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr);
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 9d5eed4..fdbc41c 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -52,6 +52,7 @@ struct HostMemoryBackend {
/* protected */
uint64_t size;
bool merge, dump;
+ bool prealloc, force_prealloc;
MemoryRegion mr;
};
diff --git a/memory.c b/memory.c
index 6b0c116..118704d 100644
--- a/memory.c
+++ b/memory.c
@@ -1258,6 +1258,17 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
cpu_physical_memory_reset_dirty(mr->ram_addr + addr, size, client);
}
+int memory_region_get_fd(MemoryRegion *mr)
+{
+ if (mr->alias) {
+ return memory_region_get_fd(mr->alias);
+ }
+
+ assert(mr->terminates);
+
+ return qemu_get_ram_fd(mr->ram_addr & TARGET_PAGE_MASK);
+}
+
void *memory_region_get_ram_ptr(MemoryRegion *mr)
{
if (mr->alias) {
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 27/34] hostmem: add properties for NUMA memory policy
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (24 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 26/34] configure: add Linux libnuma detection hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 25/34] hostmem: add property to map memory with MAP_SHARED hutao
` (7 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
[Raise errors on setting properties if !CONFIG_NUMA. Add BUILD_BUG_ON
checks. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
include/sysemu/hostmem.h | 4 ++
qapi-schema.json | 20 +++++++++
3 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 738bb31..d3f8476 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -10,11 +10,20 @@
* See the COPYING file in the top-level directory.
*/
#include "sysemu/hostmem.h"
-#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
+#include "qapi-types.h"
+#include "qapi-visit.h"
#include "qapi/qmp/qerror.h"
#include "qom/object_interfaces.h"
+#ifdef CONFIG_NUMA
+#include <numaif.h>
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_DEFAULT != MPOL_DEFAULT);
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_PREFERRED != MPOL_PREFERRED);
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_BIND != MPOL_BIND);
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_INTERLEAVE != MPOL_INTERLEAVE);
+#endif
+
static void
host_memory_backend_get_size(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
@@ -49,6 +58,84 @@ host_memory_backend_set_size(Object *obj, Visitor *v, void *opaque,
backend->size = value;
}
+static void
+get_host_nodes(Object *obj, Visitor *v, void *opaque, const char *name,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ uint16List *host_nodes = NULL;
+ uint16List **node = &host_nodes;
+ unsigned long value;
+
+ value = find_first_bit(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(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)
+{
+#ifdef CONFIG_NUMA
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ uint16List *l = NULL;
+
+ visit_type_uint16List(v, &l, name, errp);
+
+ while (l) {
+ bitmap_set(backend->host_nodes, l->value, 1);
+ l = l->next;
+ }
+#else
+ error_setg(errp, "NUMA node binding are not supported by this QEMU");
+#endif
+}
+
+static void
+get_policy(Object *obj, Visitor *v, void *opaque, const char *name,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ int policy = backend->policy;
+
+ visit_type_enum(v, &policy, HostMemPolicy_lookup, NULL, name, errp);
+}
+
+static void
+set_policy(Object *obj, Visitor *v, void *opaque, const char *name,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ int policy;
+
+ visit_type_enum(v, &policy, HostMemPolicy_lookup, NULL, name, errp);
+ backend->policy = policy;
+
+#ifndef CONFIG_NUMA
+ if (policy != HOST_MEM_POLICY_DEFAULT) {
+ error_setg(errp, "NUMA policies are not supported by this QEMU");
+ }
+#endif
+}
+
static bool host_memory_backend_get_merge(Object *obj, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
@@ -159,6 +246,12 @@ static void host_memory_backend_initfn(Object *obj)
object_property_add(obj, "size", "int",
host_memory_backend_get_size,
host_memory_backend_set_size, NULL, NULL, NULL);
+ object_property_add(obj, "host-nodes", "int",
+ get_host_nodes,
+ set_host_nodes, NULL, NULL, NULL);
+ object_property_add(obj, "policy", "str",
+ get_policy,
+ set_policy, NULL, NULL, NULL);
}
static void host_memory_backend_finalize(Object *obj)
@@ -203,6 +296,20 @@ host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
if (backend->prealloc) {
os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
}
+
+#ifdef CONFIG_NUMA
+ unsigned long maxnode = find_last_bit(backend->host_nodes, MAX_NODES);
+
+ /* This is a workaround for a long standing bug in Linux'
+ * mbind implementation, which cuts off the last specified
+ * node.
+ */
+ if (mbind(ptr, sz, backend->policy, backend->host_nodes, maxnode + 2, 0)) {
+ error_setg_errno(errp, errno,
+ "cannot bind memory to host NUMA nodes");
+ return;
+ }
+#endif
}
MemoryRegion *
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index fdbc41c..9e1a816 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -12,9 +12,11 @@
#ifndef QEMU_HOSTMEM_H
#define QEMU_HOSTMEM_H
+#include "sysemu/sysemu.h" /* for MAX_NODES */
#include "qom/object.h"
#include "qapi/error.h"
#include "exec/memory.h"
+#include "qemu/bitmap.h"
#define TYPE_MEMORY_BACKEND "memory"
#define MEMORY_BACKEND(obj) \
@@ -53,6 +55,8 @@ struct HostMemoryBackend {
uint64_t size;
bool merge, dump;
bool prealloc, force_prealloc;
+ DECLARE_BITMAP(host_nodes, MAX_NODES);
+ HostMemPolicy policy;
MemoryRegion mr;
};
diff --git a/qapi-schema.json b/qapi-schema.json
index a8c16bc..5aea3ed 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4723,3 +4723,23 @@
'*cpus': ['uint16'],
'*mem': 'size',
'*memdev': 'str' }}
+
+##
+# @HostMemPolicy
+#
+# Host memory policy types
+#
+# @default: restore default policy, remove any nondefault policy
+#
+# @preferred: set the preferred host nodes for allocation
+#
+# @bind: a strict policy that restricts memory allocation to the
+# host nodes specified
+#
+# @interleave: memory allocations are interleaved across the set
+# of host nodes specified
+#
+# Since 2.1
+##
+{ 'enum': 'HostMemPolicy',
+ 'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 26/34] configure: add Linux libnuma detection
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (23 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 24/34] hostmem: allow preallocation of any memory region hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 27/34] hostmem: add properties for NUMA memory policy hutao
` (8 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: Andre Przywara, ehabkost@redhat.com, imammedo@redhat.com,
mtosatti@redhat.com, Paolo Bonzini,
a.motakis@virtualopensystems.com, gaowanlong@cn.fujitsu.com
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Add detection of libnuma (mostly contained in the numactl package)
to the configure script. Can be enabled or disabled on the command
line, default is use if available.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
configure | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/configure b/configure
index aae617e..67f5c68 100755
--- a/configure
+++ b/configure
@@ -322,6 +322,7 @@ tpm="no"
libssh2=""
vhdx=""
quorum="no"
+numa=""
# parse CC options first
for opt do
@@ -1077,6 +1078,10 @@ for opt do
;;
--enable-quorum) quorum="yes"
;;
+ --disable-numa) numa="no"
+ ;;
+ --enable-numa) numa="yes"
+ ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@@ -1339,6 +1344,8 @@ Advanced options (experts only):
--enable-vhdx enable support for the Microsoft VHDX image format
--disable-quorum disable quorum block filter support
--enable-quorum enable quorum block filter support
+ --disable-numa disable libnuma support
+ --enable-numa enable libnuma support
NOTE: The object files are built at the place where configure is launched
EOF
@@ -3060,6 +3067,27 @@ if compile_prog "" "" ; then
fi
##########################################
+# libnuma probe
+
+if test "$numa" != "no" ; then
+ numa=no
+ cat > $TMPC << EOF
+#include <numa.h>
+int main(void) { return numa_available(); }
+EOF
+
+ if compile_prog "" "-lnuma" ; then
+ numa=yes
+ libs_softmmu="-lnuma $libs_softmmu"
+ else
+ if test "$numa" = "yes" ; then
+ feature_not_found "linux NUMA (install numactl?)"
+ fi
+ numa=no
+ fi
+fi
+
+##########################################
# signalfd probe
signalfd="no"
cat > $TMPC << EOF
@@ -4133,6 +4161,7 @@ echo "vhdx $vhdx"
echo "Quorum $quorum"
echo "lzo support $lzo"
echo "snappy support $snappy"
+echo "NUMA host support $numa"
if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5085,6 +5114,10 @@ if [ "$dtc_internal" = "yes" ]; then
echo "config-host.h: subdir-dtc" >> $config_host_mak
fi
+if test "$numa" = "yes"; then
+ echo "CONFIG_NUMA=y" >> $config_host_mak
+fi
+
# build tree in object directory in case the source is not in the current directory
DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests"
DIRS="$DIRS fsdev"
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 25/34] hostmem: add property to map memory with MAP_SHARED
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (25 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 27/34] hostmem: add properties for NUMA memory policy hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 29/34] Introduce signed range hutao
` (6 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
From: Paolo Bonzini <pbonzini@redhat.com>
A new "share" property can be used with the "memory-file" backend to
map memory with MAP_SHARED instead of MAP_PRIVATE.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem-file.c | 26 +++++++++++++++++++++++++-
exec.c | 18 ++++++++++--------
include/exec/memory.h | 2 ++
include/exec/ram_addr.h | 3 ++-
memory.c | 3 ++-
numa.c | 2 +-
6 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 67328b9..7f30011 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -28,6 +28,8 @@ typedef struct HostMemoryBackendFile HostMemoryBackendFile;
struct HostMemoryBackendFile {
HostMemoryBackend parent_obj;
+
+ bool share;
char *mem_path;
};
@@ -51,7 +53,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
backend->force_prealloc = mem_prealloc;
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
object_get_canonical_path(OBJECT(backend)),
- backend->size,
+ backend->size, fb->share,
fb->mem_path, errp);
}
#endif
@@ -87,9 +89,31 @@ static void set_mem_path(Object *o, const char *str, Error **errp)
fb->mem_path = g_strdup(str);
}
+static bool file_memory_backend_get_share(Object *o, Error **errp)
+{
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+ return fb->share;
+}
+
+static void file_memory_backend_set_share(Object *o, bool value, Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(o);
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+ if (memory_region_size(&backend->mr)) {
+ error_setg(errp, "cannot change property value");
+ return;
+ }
+ fb->share = value;
+}
+
static void
file_backend_instance_init(Object *o)
{
+ object_property_add_bool(o, "share",
+ file_memory_backend_get_share,
+ file_memory_backend_set_share, NULL);
object_property_add_str(o, "mem-path", get_mem_path,
set_mem_path, NULL);
}
diff --git a/exec.c b/exec.c
index fab45b5..85fb85c 100644
--- a/exec.c
+++ b/exec.c
@@ -73,6 +73,9 @@ static MemoryRegion io_mem_unassigned;
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
#define RAM_PREALLOC (1 << 0)
+/* RAM is mmap-ed with MAP_SHARED */
+#define RAM_SHARED (1 << 1)
+
#endif
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
@@ -1075,7 +1078,9 @@ static void *file_ram_alloc(RAMBlock *block,
perror("ftruncate");
}
- area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ area = mmap(0, memory, PROT_READ | PROT_WRITE,
+ (block->flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE),
+ fd, 0);
if (area == MAP_FAILED) {
error_setg_errno(errp, errno,
"unable to map backing store for hugepages");
@@ -1271,7 +1276,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
#ifdef __linux__
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
- const char *mem_path,
+ bool share, const char *mem_path,
Error **errp)
{
RAMBlock *new_block;
@@ -1296,6 +1301,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
new_block = g_malloc0(sizeof(*new_block));
new_block->mr = mr;
new_block->length = size;
+ new_block->flags = share ? RAM_SHARED : 0;
new_block->host = file_ram_alloc(new_block, size,
mem_path, errp);
if (!new_block->host) {
@@ -1398,12 +1404,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
flags = MAP_FIXED;
munmap(vaddr, length);
if (block->fd >= 0) {
-#ifdef MAP_POPULATE
- flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
- MAP_PRIVATE;
-#else
- flags |= MAP_PRIVATE;
-#endif
+ flags |= (block->flags & RAM_SHARED ?
+ MAP_SHARED : MAP_PRIVATE);
area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
flags, block->fd, offset);
} else {
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 846834e..21443bc 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -321,6 +321,7 @@ void memory_region_init_ram(MemoryRegion *mr,
* @owner: the object that tracks the region's reference count
* @name: the name of the region.
* @size: size of the region.
+ * @share: %true if memory must be mmaped with the MAP_SHARED flag
* @path: the path in which to allocate the RAM.
* @errp: pointer to Error*, to store an error if it happens.
*/
@@ -328,6 +329,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
struct Object *owner,
const char *name,
uint64_t size,
+ bool share,
const char *path,
Error **errp);
#endif
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index d352f60..1d4ac74 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -23,7 +23,8 @@
#include "hw/xen/xen.h"
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
- const char *mem_path, Error **errp);
+ bool share, const char *mem_path,
+ Error **errp);
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
diff --git a/memory.c b/memory.c
index 118704d..202869a 100644
--- a/memory.c
+++ b/memory.c
@@ -1025,6 +1025,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
struct Object *owner,
const char *name,
uint64_t size,
+ bool share,
const char *path,
Error **errp)
{
@@ -1032,7 +1033,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
mr->ram = true;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
- mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path, errp);
+ mr->ram_addr = qemu_ram_alloc_from_file(size, mr, share, path, errp);
}
#endif
diff --git a/numa.c b/numa.c
index 966cacc..fa117f0 100644
--- a/numa.c
+++ b/numa.c
@@ -232,7 +232,7 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
if (mem_path) {
#ifdef __linux__
Error *err = NULL;
- memory_region_init_ram_from_file(mr, owner, name, ram_size,
+ memory_region_init_ram_from_file(mr, owner, name, ram_size, false,
mem_path, &err);
/* Legacy behavior: if allocation failed, fall back to
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 32/34] qom: introduce object_property_get_enum and object_property_get_uint16List
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (30 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 28/34] hw: switch all boards to use memory_region_allocate_system_memory hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 34/34] hmp: add info memdev hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 33/34] qmp: add query-memdev hutao
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
include/qom/object.h | 18 ++++++++++++++++++
qom/object.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/include/qom/object.h b/include/qom/object.h
index a641dcd..2e488f1 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -917,6 +917,24 @@ int64_t object_property_get_int(Object *obj, const char *name,
Error **errp);
/**
+ * object_property_get_enum:
+ * @obj: the object
+ * @name: the name of the property
+ * @strings: strings corresponding to enums
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an integer, or
+ * undefined if an error occurs (including when the property value is not
+ * an enum).
+ */
+int object_property_get_enum(Object *obj, const char *name,
+ const char *strings[], Error **errp);
+
+
+void object_property_get_uint16List(Object *obj, const char *name,
+ uint16List **list, Error **errp);
+
+/**
* object_property_set:
* @obj: the object
* @v: the visitor that will be used to write the property value. This should
diff --git a/qom/object.c b/qom/object.c
index f4de619..f6e3c4f 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -13,6 +13,7 @@
#include "qom/object.h"
#include "qemu-common.h"
#include "qapi/visitor.h"
+#include "qapi-visit.h"
#include "qapi/string-input-visitor.h"
#include "qapi/string-output-visitor.h"
#include "qapi/qmp/qerror.h"
@@ -938,6 +939,40 @@ int64_t object_property_get_int(Object *obj, const char *name,
return retval;
}
+int object_property_get_enum(Object *obj, const char *name,
+ const char *strings[], Error **errp)
+{
+ StringOutputVisitor *sov;
+ StringInputVisitor *siv;
+ int ret;
+
+ sov = string_output_visitor_new(false);
+ object_property_get(obj, string_output_get_visitor(sov), name, errp);
+ siv = string_input_visitor_new(string_output_get_string(sov));
+ string_output_visitor_cleanup(sov);
+ visit_type_enum(string_input_get_visitor(siv),
+ &ret, strings, NULL, name, errp);
+ string_input_visitor_cleanup(siv);
+
+ return ret;
+}
+
+void object_property_get_uint16List(Object *obj, const char *name,
+ uint16List **list, Error **errp)
+{
+ StringOutputVisitor *ov;
+ StringInputVisitor *iv;
+
+ ov = string_output_visitor_new(false);
+ object_property_get(obj, string_output_get_visitor(ov),
+ name, errp);
+ iv = string_input_visitor_new(string_output_get_string(ov));
+ visit_type_uint16List(string_input_get_visitor(iv),
+ list, NULL, errp);
+ string_output_visitor_cleanup(ov);
+ string_input_visitor_cleanup(iv);
+}
+
void object_property_parse(Object *obj, const char *string,
const char *name, Error **errp)
{
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 28/34] hw: switch all boards to use memory_region_allocate_system_memory
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (29 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 30/34] qapi: make string input " hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 32/34] qom: introduce object_property_get_enum and object_property_get_uint16List hutao
` (2 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
hw/alpha/typhoon.c | 4 ++--
hw/arm/cubieboard.c | 5 +++--
hw/arm/digic_boards.c | 3 +--
hw/arm/exynos4210.c | 18 +++++++++------
hw/arm/highbank.c | 3 ++-
hw/arm/integratorcp.c | 4 ++--
hw/arm/kzm.c | 3 +--
hw/arm/musicpal.c | 4 ++--
hw/arm/omap1.c | 5 +++--
hw/arm/omap2.c | 5 +++--
hw/arm/pxa2xx.c | 9 ++++----
hw/arm/realview.c | 11 +++++----
hw/arm/strongarm.c | 5 +++--
hw/arm/versatilepb.c | 4 ++--
hw/arm/vexpress.c | 8 +++----
hw/arm/virt.c | 4 ++--
hw/arm/xilinx_zynq.c | 4 ++--
hw/block/onenand.c | 7 +++---
hw/cris/axis_dev88.c | 4 ++--
hw/lm32/lm32_boards.c | 8 +++----
hw/lm32/milkymist.c | 4 ++--
hw/m68k/an5206.c | 4 ++--
hw/m68k/dummy_m68k.c | 4 ++--
hw/m68k/mcf5208.c | 4 ++--
hw/microblaze/petalogix_ml605_mmu.c | 5 +++--
hw/microblaze/petalogix_s3adsp1800_mmu.c | 5 +++--
hw/mips/mips_fulong2e.c | 4 ++--
hw/mips/mips_jazz.c | 4 ++--
hw/mips/mips_malta.c | 4 ++--
hw/mips/mips_mipssim.c | 4 ++--
hw/mips/mips_r4k.c | 4 ++--
hw/moxie/moxiesim.c | 4 ++--
hw/openrisc/openrisc_sim.c | 3 ++-
hw/ppc/e500.c | 4 ++--
hw/ppc/mac_newworld.c | 4 ++--
hw/ppc/mac_oldworld.c | 4 ++--
hw/ppc/ppc405_boards.c | 22 +++++++++---------
hw/ppc/ppc4xx_devs.c | 38 +++++++++++++++++++++++++-------
hw/ppc/prep.c | 3 +--
hw/ppc/spapr.c | 4 ++--
hw/ppc/virtex_ml507.c | 3 +--
hw/s390x/s390-virtio-ccw.c | 4 ++--
hw/s390x/s390-virtio.c | 4 ++--
hw/sh4/r2d.c | 4 ++--
hw/sh4/shix.c | 12 ++++++----
hw/sparc/leon3.c | 3 +--
hw/sparc/sun4m.c | 4 ++--
hw/sparc64/sun4u.c | 4 ++--
hw/unicore32/puv3.c | 4 ++--
hw/xtensa/xtensa_lx60.c | 4 ++--
hw/xtensa/xtensa_sim.c | 4 ++--
51 files changed, 170 insertions(+), 130 deletions(-)
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 67a1070..c1c75f4 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -843,8 +843,8 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
/* Main memory region, 0x00.0000.0000. Real hardware supports 32GB,
but the address space hole reserved at this point is 8TB. */
- memory_region_init_ram(&s->ram_region, OBJECT(s), "ram", ram_size);
- vmstate_register_ram_global(&s->ram_region);
+ memory_region_allocate_system_memory(&s->ram_region, OBJECT(s),
+ "ram", ram_size);
memory_region_add_subregion(addr_space, 0, &s->ram_region);
/* TIGbus, 0x801.0000.0000, 1GB. */
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index d95a7f3..dba0628 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -50,8 +50,9 @@ static void cubieboard_init(QEMUMachineInitArgs *args)
exit(1);
}
- memory_region_init_ram(&s->sdram, NULL, "cubieboard.ram", args->ram_size);
- vmstate_register_ram_global(&s->sdram);
+ memory_region_allocate_system_memory(&s->sdram, NULL,
+ "cubieboard.ram",
+ args->ram_size);
memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
&s->sdram);
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 32fc30a..7ca0e74 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -51,9 +51,8 @@ typedef struct DigicBoard {
static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
{
- memory_region_init_ram(&s->ram, NULL, "ram", ram_size);
+ memory_region_allocate_system_memory(&s->ram, NULL, "ram", ram_size);
memory_region_add_subregion(get_system_memory(), 0, &s->ram);
- vmstate_register_ram_global(&s->ram);
}
static void digic4_board_init(DigicBoard *board)
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 6426d16..101f96c 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -140,6 +140,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
int i, n;
Exynos4210State *s = g_new(Exynos4210State, 1);
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
+ MemoryRegion *ram = g_malloc0(sizeof(*ram));
unsigned long mem_size;
DeviceState *dev;
SysBusDevice *busdev;
@@ -271,18 +272,21 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
/* DRAM */
mem_size = ram_size;
+ memory_region_allocate_system_memory(ram, NULL, "exynos4210.dram",
+ ram_size);
+
if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
- memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
- mem_size - EXYNOS4210_DRAM_MAX_SIZE);
- vmstate_register_ram_global(&s->dram1_mem);
+ mem_size -= EXYNOS4210_DRAM_MAX_SIZE;
+ memory_region_init_alias(&s->dram1_mem, NULL, "exynos4210.dram1",
+ ram, EXYNOS4210_DRAM_MAX_SIZE, mem_size);
memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
- &s->dram1_mem);
+ &s->dram1_mem);
mem_size = EXYNOS4210_DRAM_MAX_SIZE;
}
- memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size);
- vmstate_register_ram_global(&s->dram0_mem);
+ memory_region_init_alias(&s->dram0_mem, NULL, "exynos4210.dram0",
+ ram, 0, mem_size);
memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
- &s->dram0_mem);
+ &s->dram0_mem);
/* PMU.
* The only reason of existence at the moment is that secondary CPU boot
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index f66d57b..964d40e 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -251,7 +251,8 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
sysmem = get_system_memory();
dram = g_new(MemoryRegion, 1);
- memory_region_init_ram(dram, NULL, "highbank.dram", ram_size);
+ memory_region_allocate_system_memory(dram, NULL, "highbank.dram",
+ args->ram_size);
/* SDRAM at address zero. */
memory_region_add_subregion(sysmem, 0, dram);
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index a759689..5196f7b 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -485,8 +485,8 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
exit(1);
}
- memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "integrator.ram",
+ ram_size);
/* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
/* ??? RAM should repeat to fill physical memory space. */
/* SDRAM at address zero*/
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 99d33cb..cd5a67f 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -97,8 +97,7 @@ static void kzm_init(QEMUMachineInitArgs *args)
/* On a real system, the first 16k is a `secure boot rom' */
- memory_region_init_ram(ram, NULL, "kzm.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "kzm.ram", args->ram_size);
memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index de54201..7f4acef 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1609,8 +1609,8 @@ static void musicpal_init(QEMUMachineInitArgs *args)
}
/* For now we use a fixed - the original - RAM size */
- memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "musicpal.ram",
+ MP_RAM_DEFAULT_SIZE);
memory_region_add_subregion(address_space_mem, 0, ram);
memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE);
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index b433748..9a12f1c 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -24,6 +24,7 @@
#include "sysemu/blockdev.h"
#include "qemu/range.h"
#include "hw/sysbus.h"
+#include "hw/boards.h"
/* Should signal the TCMI/GPMC */
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
@@ -3854,8 +3855,8 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
omap_clk_init(s);
/* Memory-mapped stuff */
- memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size);
- vmstate_register_ram_global(&s->emiff_ram);
+ memory_region_allocate_system_memory(&s->emiff_ram, NULL,
+ "omap1.dram", s->sdram_size);
memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size);
vmstate_register_ram_global(&s->imif_ram);
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index 36efde0..2634267 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -29,6 +29,7 @@
#include "hw/arm/soc_dma.h"
#include "hw/sysbus.h"
#include "audio/audio.h"
+#include "hw/boards.h"
/* Enhanced Audio Controller (CODEC only) */
struct omap_eac_s {
@@ -2266,8 +2267,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
omap_clk_init(s);
/* Memory-mapped stuff */
- memory_region_init_ram(&s->sdram, NULL, "omap2.dram", s->sdram_size);
- vmstate_register_ram_global(&s->sdram);
+ memory_region_allocate_system_memory(&s->sdram, NULL, "omap2.dram",
+ s->sdram_size);
memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram);
memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size);
vmstate_register_ram_global(&s->sram);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 0429148..162cb9e 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -13,6 +13,7 @@
#include "hw/char/serial.h"
#include "hw/i2c/i2c.h"
#include "hw/ssi.h"
+#include "hw/boards.h"
#include "sysemu/char.h"
#include "sysemu/blockdev.h"
@@ -2058,8 +2059,8 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0];
/* SDRAM & Internal Memory Storage */
- memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size);
- vmstate_register_ram_global(&s->sdram);
+ memory_region_allocate_system_memory(&s->sdram, NULL, "pxa270.sdram",
+ sdram_size);
memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000);
vmstate_register_ram_global(&s->internal);
@@ -2189,8 +2190,8 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0];
/* SDRAM & Internal Memory Storage */
- memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size);
- vmstate_register_ram_global(&s->sdram);
+ memory_region_allocate_system_memory(&s->sdram, NULL,
+ "pxa255.sdram", sdram_size);
memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
memory_region_init_ram(&s->internal, NULL, "pxa255.internal",
PXA2XX_INTERNAL_SIZE);
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 7e04e50..0d87d24 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -56,6 +56,7 @@ static void realview_init(QEMUMachineInitArgs *args,
MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
+ MemoryRegion *ram = g_malloc0(sizeof(*ram));
DeviceState *dev, *sysctl, *gpio2, *pl041;
SysBusDevice *busdev;
qemu_irq pic[64];
@@ -133,17 +134,19 @@ static void realview_init(QEMUMachineInitArgs *args,
proc_id = 0x02000000;
}
+ memory_region_allocate_system_memory(ram, NULL, "realview.mem", ram_size);
+
if (is_pb && ram_size > 0x20000000) {
/* Core tile RAM. */
low_ram_size = ram_size - 0x20000000;
ram_size = 0x20000000;
- memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size);
- vmstate_register_ram_global(ram_lo);
+ memory_region_init_alias(ram_lo, NULL, "realview.lowmem", ram,
+ 0x20000000, low_ram_size);
memory_region_add_subregion(sysmem, 0x20000000, ram_lo);
}
- memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size);
- vmstate_register_ram_global(ram_hi);
+ memory_region_init_alias(ram_hi, NULL, "realview.highmem", ram, 0,
+ ram_size);
low_ram_size = ram_size;
if (low_ram_size > 0x10000000)
low_ram_size = 0x10000000;
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 170d0ce..93f6f9f 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -33,6 +33,7 @@
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
#include "hw/ssi.h"
+#include "hw/boards.h"
//#define DEBUG
@@ -1608,8 +1609,8 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
exit(1);
}
- memory_region_init_ram(&s->sdram, NULL, "strongarm.sdram", sdram_size);
- vmstate_register_ram_global(&s->sdram);
+ memory_region_allocate_system_memory(&s->sdram, NULL,
+ "strongarm.sdram", sdram_size);
memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index e5493b4..438b3ea 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -198,8 +198,8 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}
- memory_region_init_ram(ram, NULL, "versatile.ram", args->ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "versatile.ram",
+ args->ram_size);
/* ??? RAM should repeat to fill physical memory space. */
/* SDRAM at address zero. */
memory_region_add_subregion(sysmem, 0, ram);
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 67628af..57f85d6 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -252,8 +252,8 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
exit(1);
}
- memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
+ ram_size);
low_ram_size = ram_size;
if (low_ram_size > 0x4000000) {
low_ram_size = 0x4000000;
@@ -346,8 +346,8 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
}
}
- memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
+ ram_size);
/* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */
memory_region_add_subregion(sysmem, 0x80000000, ram);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 2bbc931..e6f254c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -400,8 +400,8 @@ static void machvirt_init(QEMUMachineInitArgs *args)
}
fdt_add_cpu_nodes(vbi);
- memory_region_init_ram(ram, NULL, "mach-virt.ram", args->ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
+ args->ram_size);
memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
dev = qdev_create(NULL, vbi->qdevname);
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 9ee21e7..fbfadac 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -149,8 +149,8 @@ static void zynq_init(QEMUMachineInitArgs *args)
}
/* DDR remapped to address zero. */
- memory_region_init_ram(ext_ram, NULL, "zynq.ext_ram", ram_size);
- vmstate_register_ram_global(ext_ram);
+ memory_region_allocate_system_memory(ext_ram, NULL, "zynq.ext_ram",
+ ram_size);
memory_region_add_subregion(address_space_mem, 0, ext_ram);
/* 256K of on-chip memory */
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index aae9ee7..0d1b02d 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -20,6 +20,7 @@
#include "qemu-common.h"
#include "hw/hw.h"
+#include "hw/boards.h"
#include "hw/block/flash.h"
#include "hw/irq.h"
#include "sysemu/blockdev.h"
@@ -791,9 +792,9 @@ static int onenand_initfn(SysBusDevice *sbd)
}
s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
0xff, (64 + 2) << PAGE_SHIFT);
- memory_region_init_ram(&s->ram, OBJECT(s), "onenand.ram",
- 0xc000 << s->shift);
- vmstate_register_ram_global(&s->ram);
+ memory_region_allocate_system_memory(&s->ram, OBJECT(s),
+ "onenand.ram",
+ 0xc000 << s->shift);
ram = memory_region_get_ram_ptr(&s->ram);
s->boot[0] = ram + (0x0000 << s->shift);
s->boot[1] = ram + (0x8000 << s->shift);
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 645e45c..726524a 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -245,7 +245,6 @@ static struct cris_load_info li;
static
void axisdev88_init(QEMUMachineInitArgs *args)
{
- ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
@@ -270,7 +269,8 @@ void axisdev88_init(QEMUMachineInitArgs *args)
env = &cpu->env;
/* allocate RAM */
- memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size);
+ memory_region_allocate_system_memory(phys_ram, NULL, "axisdev88.ram",
+ args->ram_size);
vmstate_register_ram_global(phys_ram);
memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 5e22e9b..425cbab 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -111,8 +111,8 @@ static void lm32_evr_init(QEMUMachineInitArgs *args)
reset_info->flash_base = flash_base;
- memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size);
- vmstate_register_ram_global(phys_ram);
+ memory_region_allocate_system_memory(phys_ram, NULL, "lm32_evr.sdram",
+ ram_size);
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
@@ -213,8 +213,8 @@ static void lm32_uclinux_init(QEMUMachineInitArgs *args)
reset_info->flash_base = flash_base;
- memory_region_init_ram(phys_ram, NULL, "lm32_uclinux.sdram", ram_size);
- vmstate_register_ram_global(phys_ram);
+ memory_region_allocate_system_memory(phys_ram, NULL,
+ "lm32_uclinux.sdram", ram_size);
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index baf234c..7d3f95b 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -118,8 +118,8 @@ milkymist_init(QEMUMachineInitArgs *args)
cpu_lm32_set_phys_msb_ignore(env, 1);
- memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size);
- vmstate_register_ram_global(phys_sdram);
+ memory_region_allocate_system_memory(phys_sdram, NULL,
+ "milkymist.sdram", sdram_size);
memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
dinfo = drive_get(IF_PFLASH, 0, 0);
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index 24f2068..ec5a4f8 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -50,8 +50,8 @@ static void an5206_init(QEMUMachineInitArgs *args)
env->rambar0 = AN5206_RAMBAR_ADDR | 1;
/* DRAM at address zero */
- memory_region_init_ram(ram, NULL, "an5206.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "an5206.ram",
+ ram_size);
memory_region_add_subregion(address_space_mem, 0, ram);
/* Internal SRAM. */
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index 86e2e6e..b07ffe5 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -40,8 +40,8 @@ static void dummy_m68k_init(QEMUMachineInitArgs *args)
env->vbr = 0;
/* RAM at address zero */
- memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "dummy_m68k.ram",
+ ram_size);
memory_region_add_subregion(address_space_mem, 0, ram);
/* Load kernel. */
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 6e30c0b..791337f 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -218,8 +218,8 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args)
/* TODO: Configure BARs. */
/* DRAM at 0x40000000 */
- memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "mcf5208.ram",
+ ram_size);
memory_region_add_subregion(address_space_mem, 0x40000000, ram);
/* Internal SRAM. */
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 40a9f5c..ba27bbc 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -104,8 +104,9 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
vmstate_register_ram_global(phys_lmb_bram);
memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);
- memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size);
- vmstate_register_ram_global(phys_ram);
+ memory_region_allocate_system_memory(phys_ram, NULL,
+ "petalogix_ml605.ram",
+ ram_size);
memory_region_add_subregion(address_space_mem, ddr_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 6c45e20..bdd0908 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -85,8 +85,9 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args)
vmstate_register_ram_global(phys_lmb_bram);
memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);
- memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram", ram_size);
- vmstate_register_ram_global(phys_ram);
+ memory_region_allocate_system_memory(phys_ram, NULL,
+ "petalogix_s3adsp1800.ram",
+ ram_size);
memory_region_add_subregion(sysmem, ddr_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index e1551aa..cab3366 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -302,8 +302,8 @@ static void mips_fulong2e_init(QEMUMachineInitArgs *args)
bios_size = 1024 * 1024;
/* allocate RAM */
- memory_region_init_ram(ram, NULL, "fulong2e.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL,
+ "fulong2e.ram", ram_size);
memory_region_init_ram(bios, NULL, "fulong2e.bios", bios_size);
vmstate_register_ram_global(bios);
memory_region_set_readonly(bios, true);
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 5f6dd9f..7504d6c 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -179,8 +179,8 @@ static void mips_jazz_init(MemoryRegion *address_space,
cc->do_unassigned_access = mips_jazz_do_unassigned_access;
/* allocate RAM */
- memory_region_init_ram(ram, NULL, "mips_jazz.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
+ ram_size);
memory_region_add_subregion(address_space, 0, ram);
memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index ac5ec44..2d477f2 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -962,8 +962,8 @@ void mips_malta_init(QEMUMachineInitArgs *args)
}
/* register RAM at high address where it is undisturbed by IO */
- memory_region_init_ram(ram_high, NULL, "mips_malta.ram", ram_size);
- vmstate_register_ram_global(ram_high);
+ memory_region_allocate_system_memory(ram_high, NULL,
+ "mips_malta.ram", ram_size);
memory_region_add_subregion(system_memory, 0x80000000, ram_high);
/* alias for pre IO hole access */
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 239aa6a..e5672c7 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -171,8 +171,8 @@ mips_mipssim_init(QEMUMachineInitArgs *args)
qemu_register_reset(main_cpu_reset, reset_info);
/* Allocate RAM. */
- memory_region_init_ram(ram, NULL, "mips_mipssim.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL,
+ "mips_mipssim.ram", ram_size);
memory_region_init_ram(bios, NULL, "mips_mipssim.bios", BIOS_SIZE);
vmstate_register_ram_global(bios);
memory_region_set_readonly(bios, true);
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index e94b543..429079c 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -204,8 +204,8 @@ void mips_r4k_init(QEMUMachineInitArgs *args)
((unsigned int)ram_size / (1 << 20)));
exit(1);
}
- memory_region_init_ram(ram, NULL, "mips_r4k.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL,
+ "mips_r4k.ram", ram_size);
memory_region_add_subregion(address_space_mem, 0, ram);
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index a87ca6d..e79af2f 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -136,8 +136,8 @@ static void moxiesim_init(QEMUMachineInitArgs *args)
qemu_register_reset(main_cpu_reset, cpu);
/* Allocate RAM. */
- memory_region_init_ram(ram, NULL, "moxiesim.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "moxiesim.ram",
+ ram_size);
memory_region_add_subregion(address_space_mem, ram_base, ram);
memory_region_init_ram(rom, NULL, "moxie.rom", 128*0x1000);
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 8e1af8b..f1f34cd 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -114,7 +114,8 @@ static void openrisc_sim_init(QEMUMachineInitArgs *args)
}
ram = g_malloc(sizeof(*ram));
- memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size);
+ memory_region_allocate_system_memory(ram, NULL, "openrisc.ram",
+ args->ram_size);
vmstate_register_ram_global(ram);
memory_region_add_subregion(get_system_memory(), 0, ram);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index d7ba25f..c02ca11 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -675,8 +675,8 @@ void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params *params)
args->ram_size = ram_size;
/* Register Memory */
- memory_region_init_ram(ram, NULL, "mpc8544ds.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "mpc8544ds.ram",
+ args->ram_size);
memory_region_add_subregion(address_space_mem, 0, ram);
dev = qdev_create(NULL, "e500-ccsr");
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 5e79575..6f631b8 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -198,8 +198,8 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
}
/* allocate RAM */
- memory_region_init_ram(ram, NULL, "ppc_core99.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram",
+ args->ram_size);
memory_region_add_subregion(get_system_memory(), 0, ram);
/* allocate and load BIOS */
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 2f27754..d410f5e 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -128,8 +128,8 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
exit(1);
}
- memory_region_init_ram(ram, NULL, "ppc_heathrow.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "ppc_heathrow.ram",
+ args->ram_size);
memory_region_add_subregion(sysmem, 0, ram);
/* allocate and load BIOS */
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index f1a8f67..44a78b8 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -199,14 +199,14 @@ static void ref405ep_init(QEMUMachineInitArgs *args)
MemoryRegion *sysmem = get_system_memory();
/* XXX: fix this */
- memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000);
- vmstate_register_ram_global(&ram_memories[0]);
+ ram_size = 0x08000000;
+ memory_region_allocate_system_memory(&ram_memories[0], NULL,
+ "ef405ep.ram", ram_size);
ram_bases[0] = 0;
ram_sizes[0] = 0x08000000;
memory_region_init(&ram_memories[1], NULL, "ef405ep.ram1", 0);
ram_bases[1] = 0x00000000;
ram_sizes[1] = 0x00000000;
- ram_size = 128 * 1024 * 1024;
#ifdef DEBUG_BOARD_INIT
printf("%s: register cpu\n", __func__);
#endif
@@ -509,6 +509,7 @@ static void taihu_405ep_init(QEMUMachineInitArgs *args)
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *bios;
MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
+ MemoryRegion *ram = g_malloc0(sizeof(*ram));
hwaddr ram_bases[2], ram_sizes[2];
long bios_size;
target_ulong kernel_base, initrd_base;
@@ -518,17 +519,18 @@ static void taihu_405ep_init(QEMUMachineInitArgs *args)
DriveInfo *dinfo;
/* RAM is soldered to the board so the size cannot be changed */
- memory_region_init_ram(&ram_memories[0], NULL,
- "taihu_405ep.ram-0", 0x04000000);
- vmstate_register_ram_global(&ram_memories[0]);
+ ram_size = 0x08000000;
+ memory_region_allocate_system_memory(ram, NULL, "taihu_405ep.ram",
+ ram_size);
+
+ memory_region_init_alias(&ram_memories[0], NULL,
+ "taihu_405ep.ram-0", ram, 0, 0x04000000);
ram_bases[0] = 0;
ram_sizes[0] = 0x04000000;
- memory_region_init_ram(&ram_memories[1], NULL,
- "taihu_405ep.ram-1", 0x04000000);
- vmstate_register_ram_global(&ram_memories[1]);
+ memory_region_init_alias(&ram_memories[1], NULL,
+ "taihu_405ep.ram-1", ram, 0, 0x04000000);
ram_bases[1] = 0x04000000;
ram_sizes[1] = 0x04000000;
- ram_size = 0x08000000;
#ifdef DEBUG_BOARD_INIT
printf("%s: register cpu\n", __func__);
#endif
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 9160ee7..bf90ce7 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include "hw/hw.h"
+#include "hw/boards.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/ppc4xx.h"
#include "qemu/log.h"
@@ -682,20 +683,46 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
hwaddr ram_sizes[],
const unsigned int sdram_bank_sizes[])
{
+ MemoryRegion *ram = g_malloc0(sizeof(*ram));
ram_addr_t size_left = ram_size;
ram_addr_t base = 0;
+ unsigned int bank_size;
int i;
int j;
for (i = 0; i < nr_banks; i++) {
for (j = 0; sdram_bank_sizes[j] != 0; j++) {
- unsigned int bank_size = sdram_bank_sizes[j];
+ bank_size = sdram_bank_sizes[j];
+ if (bank_size <= size_left) {
+ size_left -= bank_size;
+ }
+ }
+ if (!size_left) {
+ /* No need to use the remaining banks. */
+ break;
+ }
+ }
+
+ ram_size -= size_left;
+ if (size_left) {
+ printf("Truncating memory to %d MiB to fit SDRAM controller limits.\n",
+ (int)(ram_size >> 20));
+ }
+
+ memory_region_allocate_system_memory(ram, NULL, "ppc4xx.sdram", ram_size);
+ vmstate_register_ram_global(ram);
+
+ size_left = ram_size;
+
+ for (i = 0; i < nr_banks; i++) {
+ for (j = 0; sdram_bank_sizes[j] != 0; j++) {
+ bank_size = sdram_bank_sizes[j];
if (bank_size <= size_left) {
char name[32];
snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
- memory_region_init_ram(&ram_memories[i], NULL, name, bank_size);
- vmstate_register_ram_global(&ram_memories[i]);
+ memory_region_init_alias(&ram_memories[i], NULL, name, ram,
+ base, bank_size);
ram_bases[i] = base;
ram_sizes[i] = bank_size;
base += bank_size;
@@ -710,10 +737,5 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
}
}
- ram_size -= size_left;
- if (size_left)
- printf("Truncating memory to %d MiB to fit SDRAM controller limits.\n",
- (int)(ram_size >> 20));
-
return ram_size;
}
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index e243651..097bdd5 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -420,8 +420,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
}
/* allocate RAM */
- memory_region_init_ram(ram, NULL, "ppc_prep.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "ppc_prep.ram", ram_size);
memory_region_add_subregion(sysmem, 0, ram);
if (linux_boot) {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 89f71a8..715a2bb 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1264,8 +1264,8 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
ram_addr_t nonrma_base = rma_alloc_size;
ram_addr_t nonrma_size = spapr->ram_limit - rma_alloc_size;
- memory_region_init_ram(ram, NULL, "ppc_spapr.ram", nonrma_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",
+ nonrma_size);
memory_region_add_subregion(sysmem, nonrma_base, ram);
}
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index ce8ea91..f4a8e6a 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -222,8 +222,7 @@ static void virtex_init(QEMUMachineInitArgs *args)
env = &cpu->env;
qemu_register_reset(main_cpu_reset, cpu);
- memory_region_init_ram(phys_ram, NULL, "ram", ram_size);
- vmstate_register_ram_global(phys_ram);
+ memory_region_allocate_system_memory(phys_ram, NULL, "ram", ram_size);
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 0d4f6ae..e54055f 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -110,8 +110,8 @@ static void ccw_init(QEMUMachineInitArgs *args)
virtio_ccw_register_hcalls();
/* allocate RAM */
- memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size);
- vmstate_register_ram_global(ram);
+ /*XXX*/
+ memory_region_allocate_system_memory(ram, NULL, "s390.ram", args->ram_size);
memory_region_add_subregion(sysmem, 0, ram);
/* allocate storage keys */
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index aef2003..0970f6e 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -256,8 +256,8 @@ static void s390_init(QEMUMachineInitArgs *args)
s390_virtio_register_hcalls();
/* allocate RAM */
- memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size);
- vmstate_register_ram_global(ram);
+ /*XXX*/
+ memory_region_allocate_system_memory(ram, NULL, "s390.ram", args->ram_size);
memory_region_add_subregion(sysmem, 0, ram);
/* clear virtio region */
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index eaeb7ed..d670f3b 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -255,8 +255,8 @@ static void r2d_init(QEMUMachineInitArgs *args)
qemu_register_reset(main_cpu_reset, reset_info);
/* Allocate memory space */
- memory_region_init_ram(sdram, NULL, "r2d.sdram", SDRAM_SIZE);
- vmstate_register_ram_global(sdram);
+ memory_region_allocate_system_memory(sdram, NULL, "r2d.sdram",
+ SDRAM_SIZE);
memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram);
/* Register peripherals */
s = sh7750_init(cpu, address_space_mem);
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index 904a966..bb23b69 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -48,6 +48,7 @@ static void shix_init(QEMUMachineInitArgs *args)
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *rom = g_new(MemoryRegion, 1);
MemoryRegion *sdram = g_new(MemoryRegion, 2);
+ MemoryRegion *ram = g_malloc0(sizeof(*ram));
if (!cpu_model)
cpu_model = "any";
@@ -63,11 +64,14 @@ static void shix_init(QEMUMachineInitArgs *args)
vmstate_register_ram_global(rom);
memory_region_set_readonly(rom, true);
memory_region_add_subregion(sysmem, 0x00000000, rom);
- memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000);
- vmstate_register_ram_global(&sdram[0]);
+
+ memory_region_allocate_system_memory(ram, NULL, "shix.sdram",
+ 0x02000000);
+ memory_region_init_alias(&sdram[0], NULL, "shix.sdram1", ram,
+ 0, 0x01000000);
memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
- memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000);
- vmstate_register_ram_global(&sdram[1]);
+ memory_region_init_alias(&sdram[1], NULL, "shix.sdram2", ram,
+ 0x01000000, 0x01000000);
memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);
/* Load BIOS in 0 (and access it through P2, 0xA0000000) */
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index c16e9e4..8c71cd3 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -151,8 +151,7 @@ static void leon3_generic_hw_init(QEMUMachineInitArgs *args)
exit(1);
}
- memory_region_init_ram(ram, NULL, "leon3.ram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "leon3.ram", ram_size);
memory_region_add_subregion(address_space_mem, 0x40000000, ram);
/* Allocate BIOS */
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 75adb68..3bc5c2f 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -784,8 +784,8 @@ static int ram_init1(SysBusDevice *dev)
{
RamDevice *d = SUN4M_RAM(dev);
- memory_region_init_ram(&d->ram, OBJECT(d), "sun4m.ram", d->size);
- vmstate_register_ram_global(&d->ram);
+ memory_region_allocate_system_memory(&d->ram, OBJECT(d),
+ "sun4m.ram", d->size);
sysbus_init_mmio(dev, &d->ram);
return 0;
}
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 6f271d9..fe4c1c8 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -729,8 +729,8 @@ static int ram_init1(SysBusDevice *dev)
{
RamDevice *d = SUN4U_RAM(dev);
- memory_region_init_ram(&d->ram, OBJECT(d), "sun4u.ram", d->size);
- vmstate_register_ram_global(&d->ram);
+ memory_region_allocate_system_memory(&d->ram, OBJECT(d),
+ "sun4u.ram", d->size);
sysbus_init_mmio(dev, &d->ram);
return 0;
}
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 42913b6..b1f0834 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -74,8 +74,8 @@ static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
MemoryRegion *ram_memory = g_new(MemoryRegion, 1);
/* SDRAM at address zero. */
- memory_region_init_ram(ram_memory, NULL, "puv3.ram", ram_size);
- vmstate_register_ram_global(ram_memory);
+ memory_region_allocate_system_memory(ram_memory, NULL, "puv3.ram",
+ ram_size);
memory_region_add_subregion(get_system_memory(), 0, ram_memory);
}
diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c
index 49c58d1..96b8f85 100644
--- a/hw/xtensa/xtensa_lx60.c
+++ b/hw/xtensa/xtensa_lx60.c
@@ -198,8 +198,8 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
}
ram = g_malloc(sizeof(*ram));
- memory_region_init_ram(ram, NULL, "lx60.dram", args->ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL,
+ "lx60.dram", args->ram_size);
memory_region_add_subregion(system_memory, 0, ram);
system_io = g_malloc(sizeof(*system_io));
diff --git a/hw/xtensa/xtensa_sim.c b/hw/xtensa/xtensa_sim.c
index 1192ce7..e2b3834 100644
--- a/hw/xtensa/xtensa_sim.c
+++ b/hw/xtensa/xtensa_sim.c
@@ -77,8 +77,8 @@ static void xtensa_sim_init(QEMUMachineInitArgs *args)
}
ram = g_malloc(sizeof(*ram));
- memory_region_init_ram(ram, NULL, "xtensa.sram", ram_size);
- vmstate_register_ram_global(ram);
+ memory_region_allocate_system_memory(ram, NULL, "xtensa.sram",
+ ram_size);
memory_region_add_subregion(get_system_memory(), 0, ram);
rom = g_malloc(sizeof(*rom));
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 29/34] Introduce signed range.
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (26 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 25/34] hostmem: add property to map memory with MAP_SHARED hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 31/34] qapi: make string output visitor parse int list hutao
` (5 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
include/qemu/range.h | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/include/qemu/range.h b/include/qemu/range.h
index aae9720..d2dd49d 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -3,6 +3,7 @@
#include <inttypes.h>
#include <qemu/typedefs.h>
+#include "qemu/queue.h"
/*
* Operations on 64 bit address ranges.
@@ -60,4 +61,122 @@ static inline int ranges_overlap(uint64_t first1, uint64_t len1,
return !(last2 < first1 || last1 < first2);
}
+typedef struct SignedRangeList SignedRangeList;
+
+typedef struct SignedRange {
+ int64_t start;
+ int64_t length;
+
+ QTAILQ_ENTRY(SignedRange) entry;
+} SignedRange;
+
+QTAILQ_HEAD(SignedRangeList, SignedRange);
+
+static inline SignedRange *s_range_new(int64_t start, int64_t length)
+{
+ SignedRange *range = NULL;
+
+ if (start + length - 1 < start) {
+ /* negative length or overflow */
+ return NULL;
+ }
+
+ range = g_malloc0(sizeof(*range));
+ range->start = start;
+ range->length = length;
+
+ return range;
+}
+
+static inline void s_range_free(SignedRange *range)
+{
+ g_free(range);
+}
+
+static inline bool s_range_overlap(int64_t start1, int64_t length1,
+ int64_t start2, int64_t length2)
+{
+ return !((start1 + length1) < start2 || (start2 + length2) < start1);
+}
+
+static inline int64_t s_range_end(int64_t start, int64_t length)
+{
+ return start + length - 1;
+}
+
+static inline bool s_range_overflow(int64_t start, int64_t length)
+{
+ return s_range_end(start, length) < start;
+}
+
+static inline int s_range_join(SignedRange *range,
+ int64_t start, int64_t length)
+{
+ if (s_range_overflow(start, length)) {
+ return -1;
+ }
+
+ if (s_range_overlap(range->start, range->length, start, length)) {
+ int64_t end = s_range_end(range->start, range->length);
+ if (end < s_range_end(start, length)) {
+ end = s_range_end(start, length);
+ }
+ if (range->start > start) {
+ range->start = start;
+ }
+ range->length = end - range->start + 1;
+ return 0;
+ }
+
+ return -1;
+}
+
+static inline int s_range_compare(int64_t start1, int64_t length1,
+ int64_t start2, int64_t length2)
+{
+ if (start1 == start2 && length1 == length2) {
+ return 0;
+ } else if (s_range_end(start1, length1) <
+ s_range_end(start2, length2)) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+
+/* Add range to list. Keep them sorted, and merge ranges whenever possible */
+static inline void range_list_add(SignedRangeList *list,
+ int64_t start, int64_t length)
+{
+ SignedRange *r, *next, *new = NULL;
+ SignedRange *cur = NULL;
+
+ QTAILQ_FOREACH_SAFE(r, list, entry, next) {
+ if (s_range_overlap(r->start, r->length, start, length)) {
+ s_range_join(r, start, length);
+ break;
+ } else if (s_range_compare(start, length, r->start, r->length) < 0) {
+ cur = r;
+ break;
+ }
+ }
+
+ new = s_range_new(start, length);
+ if (!r) {
+ QTAILQ_INSERT_TAIL(list, new, entry);
+ } else if (cur) {
+ QTAILQ_INSERT_BEFORE(cur, new, entry);
+ } else {
+ s_range_free(new);
+ SignedRange *next = QTAILQ_NEXT(r, entry);
+ while (next && s_range_overlap(r->start, r->length,
+ next->start, next->length)) {
+ s_range_join(r, next->start, next->length);
+ QTAILQ_REMOVE(list, next, entry);
+ s_range_free(next);
+ next = QTAILQ_NEXT(r, entry);
+ }
+ }
+}
+
#endif
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 30/34] qapi: make string input visitor parse int list
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (28 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 31/34] qapi: make string output visitor parse int list hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 28/34] hw: switch all boards to use memory_region_allocate_system_memory hutao
` (3 subsequent siblings)
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
qapi/string-input-visitor.c | 158 ++++++++++++++++++++++++++++++++++++--
tests/test-string-input-visitor.c | 34 ++++++++
2 files changed, 184 insertions(+), 8 deletions(-)
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 793548a..ab9301e 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -15,31 +15,159 @@
#include "qapi/visitor-impl.h"
#include "qapi/qmp/qerror.h"
#include "qemu/option.h"
+#include "qemu/queue.h"
+#include "qemu/range.h"
+
struct StringInputVisitor
{
Visitor visitor;
+
+ bool head;
+
+ SignedRangeList *ranges;
+ SignedRange *cur_range;
+ int64_t cur;
+
const char *string;
};
+static void parse_str(StringInputVisitor *siv, Error **errp)
+{
+ char *str = (char *) siv->string;
+ long long start, end;
+ char *endptr;
+
+ if (!siv->ranges) {
+ siv->ranges = g_malloc0(sizeof(*siv->ranges));
+ QTAILQ_INIT(siv->ranges);
+ errno = 0;
+ do {
+ start = strtoll(str, &endptr, 0);
+ if (errno == 0 && endptr > str && INT64_MIN <= start &&
+ start <= INT64_MAX) {
+ if (*endptr == '\0') {
+ range_list_add(siv->ranges, start, 1);
+ str = NULL;
+ } else if (*endptr == '-') {
+ str = endptr + 1;
+ end = strtoll(str, &endptr, 0);
+ if (errno == 0 && endptr > str &&
+ INT64_MIN <= end && end <= INT64_MAX && start <= end &&
+ (start > INT64_MAX - 65536 ||
+ end < start + 65536)) {
+ if (*endptr == '\0') {
+ range_list_add(siv->ranges, start, end - start + 1);
+ str = NULL;
+ } else if (*endptr == ',') {
+ str = endptr + 1;
+ range_list_add(siv->ranges, start, end - start + 1);
+ } else {
+ /* error */
+ return;
+ }
+ } else {
+ return;
+ }
+ } else if (*endptr == ',') {
+ str = endptr + 1;
+ range_list_add(siv->ranges, start, 1);
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ } while (str);
+ }
+}
+
+static void
+start_list(Visitor *v, const char *name, Error **errp)
+{
+ StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+
+ parse_str(siv, errp);
+
+ if (siv->ranges) {
+ siv->cur_range = QTAILQ_FIRST(siv->ranges);
+ if (siv->cur_range) {
+ siv->cur = siv->cur_range->start;
+ }
+ }
+}
+
+static GenericList *
+next_list(Visitor *v, GenericList **list, Error **errp)
+{
+ StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+ GenericList **link;
+
+ if (!siv->ranges || !siv->cur_range) {
+ return NULL;
+ }
+
+ if (siv->cur < siv->cur_range->start ||
+ siv->cur >= (siv->cur_range->start + siv->cur_range->length)) {
+ siv->cur_range = QTAILQ_NEXT(siv->cur_range, entry);
+ if (siv->cur_range) {
+ siv->cur = siv->cur_range->start;
+ } else {
+ return NULL;
+ }
+ }
+
+ if (siv->head) {
+ link = list;
+ siv->head = false;
+ } else {
+ link = &(*list)->next;
+ }
+
+ *link = g_malloc0(sizeof **link);
+ return *link;
+}
+
+static void
+end_list(Visitor *v, Error **errp)
+{
+ StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+ siv->head = true;
+}
+
static void parse_type_int(Visitor *v, int64_t *obj, const char *name,
Error **errp)
{
StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
- char *endp = (char *) siv->string;
- long long val;
- errno = 0;
- if (siv->string) {
- val = strtoll(siv->string, &endp, 0);
- }
- if (!siv->string || errno || endp == siv->string || *endp) {
+ if (!siv->string) {
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"integer");
return;
}
- *obj = val;
+ parse_str(siv, errp);
+
+ if (!siv->ranges) {
+ goto error;
+ }
+
+ if (!siv->cur_range) {
+ siv->cur_range = QTAILQ_FIRST(siv->ranges);
+ if (siv->cur_range) {
+ siv->cur = siv->cur_range->start;
+ } else {
+ goto error;
+ }
+ }
+
+ *obj = siv->cur;
+ siv->cur++;
+ return;
+
+error:
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, name,
+ "an int64 value or range");
}
static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
@@ -140,6 +268,16 @@ Visitor *string_input_get_visitor(StringInputVisitor *v)
void string_input_visitor_cleanup(StringInputVisitor *v)
{
+ SignedRange *r, *next;
+
+ if (v->ranges) {
+ QTAILQ_FOREACH_SAFE(r, v->ranges, entry, next) {
+ QTAILQ_REMOVE(v->ranges, r, entry);
+ g_free(r);
+ }
+ g_free(v->ranges);
+ }
+
g_free(v);
}
@@ -155,8 +293,12 @@ StringInputVisitor *string_input_visitor_new(const char *str)
v->visitor.type_bool = parse_type_bool;
v->visitor.type_str = parse_type_str;
v->visitor.type_number = parse_type_number;
+ v->visitor.start_list = start_list;
+ v->visitor.next_list = next_list;
+ v->visitor.end_list = end_list;
v->visitor.start_optional = parse_start_optional;
v->string = str;
+ v->head = true;
return v;
}
diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index d406263..c7c67f7 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -64,6 +64,35 @@ static void test_visitor_in_int(TestInputVisitorData *data,
g_assert_cmpint(res, ==, value);
}
+static void test_visitor_in_intList(TestInputVisitorData *data,
+ const void *unused)
+{
+ int64_t value[] = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20};
+ int16List *res = NULL, *tmp;
+ Error *errp = NULL;
+ Visitor *v;
+ int i = 0;
+
+ v = visitor_input_test_init(data, "1,2,-2-1,2-4,20,5-9,1-8");
+
+ visit_type_int16List(v, &res, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ tmp = res;
+ while (i < sizeof(value) / sizeof(value[0])) {
+ g_assert(tmp);
+ g_assert_cmpint(tmp->value, ==, value[i++]);
+ tmp = tmp->next;
+ }
+ g_assert(!tmp);
+
+ tmp = res;
+ while (tmp) {
+ res = res->next;
+ g_free(tmp);
+ tmp = res;
+ }
+}
+
static void test_visitor_in_bool(TestInputVisitorData *data,
const void *unused)
{
@@ -193,6 +222,7 @@ static void test_visitor_in_fuzz(TestInputVisitorData *data,
v = visitor_input_test_init(data, buf);
visit_type_int(v, &ires, NULL, NULL);
+ visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, buf);
visit_type_bool(v, &bres, NULL, NULL);
@@ -200,11 +230,13 @@ static void test_visitor_in_fuzz(TestInputVisitorData *data,
v = visitor_input_test_init(data, buf);
visit_type_number(v, &nres, NULL, NULL);
+ visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, buf);
sres = NULL;
visit_type_str(v, &sres, NULL, NULL);
g_free(sres);
+ visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, buf);
visit_type_EnumOne(v, &eres, NULL, NULL);
@@ -228,6 +260,8 @@ int main(int argc, char **argv)
input_visitor_test_add("/string-visitor/input/int",
&in_visitor_data, test_visitor_in_int);
+ input_visitor_test_add("/string-visitor/input/intList",
+ &in_visitor_data, test_visitor_in_intList);
input_visitor_test_add("/string-visitor/input/bool",
&in_visitor_data, test_visitor_in_bool);
input_visitor_test_add("/string-visitor/input/number",
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 31/34] qapi: make string output visitor parse int list
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (27 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 29/34] Introduce signed range hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:48 ` Paolo Bonzini
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 30/34] qapi: make string input " hutao
` (4 subsequent siblings)
33 siblings, 1 reply; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
qapi/string-output-visitor.c | 236 +++++++++++++++++++++++++++++++++++--
tests/test-string-output-visitor.c | 35 ++++++
2 files changed, 260 insertions(+), 11 deletions(-)
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index fb1d2e8..edfc0a4 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -16,32 +16,177 @@
#include "qapi/qmp/qerror.h"
#include "qemu/host-utils.h"
#include <math.h>
+#include "qemu/range.h"
+
+enum ListMode {
+ LM_NONE, /* not traversing a list of repeated options */
+ LM_STARTED, /* start_list() succeeded */
+
+ LM_IN_PROGRESS, /* next_list() has been called.
+ *
+ * Generating the next list link will consume the most
+ * recently parsed QemuOpt instance of the repeated
+ * option.
+ *
+ * Parsing a value into the list link will examine the
+ * next QemuOpt instance of the repeated option, and
+ * possibly enter LM_SIGNED_INTERVAL or
+ * LM_UNSIGNED_INTERVAL.
+ */
+
+ LM_SIGNED_INTERVAL, /* next_list() has been called.
+ *
+ * Generating the next list link will consume the most
+ * recently stored element from the signed interval,
+ * parsed from the most recent QemuOpt instance of the
+ * repeated option. This may consume QemuOpt itself
+ * and return to LM_IN_PROGRESS.
+ *
+ * Parsing a value into the list link will store the
+ * next element of the signed interval.
+ */
+
+ LM_UNSIGNED_INTERVAL,/* Same as above, only for an unsigned interval. */
+
+ LM_END
+};
+
+typedef enum ListMode ListMode;
struct StringOutputVisitor
{
Visitor visitor;
bool human;
- char *string;
+ GString *string;
+ bool head;
+ ListMode list_mode;
+ union {
+ int64_t s;
+ uint64_t u;
+ } range_start, range_end;
+ SignedRangeList *ranges;
};
static void string_output_set(StringOutputVisitor *sov, char *string)
{
- g_free(sov->string);
- sov->string = string;
+ if (sov->string) {
+ g_string_free(sov->string, true);
+ }
+ sov->string = g_string_new(string);
+ g_free(string);
+}
+
+static void string_output_append(StringOutputVisitor *sov, int64_t a)
+{
+ range_list_add(sov->ranges, a, 1);
+}
+
+static void string_output_append_range(StringOutputVisitor *sov,
+ int64_t s, int64_t e)
+{
+ range_list_add(sov->ranges, s, e);
}
static void print_type_int(Visitor *v, int64_t *obj, const char *name,
Error **errp)
{
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
- char *out;
+ SignedRange *r;
- if (sov->human) {
- out = g_strdup_printf("%lld (%#llx)", (long long) *obj, (long long) *obj);
- } else {
- out = g_strdup_printf("%lld", (long long) *obj);
+ if (!sov->ranges) {
+ sov->ranges = g_malloc0(sizeof(*sov->ranges));
+ QTAILQ_INIT(sov->ranges);
+ }
+
+ switch (sov->list_mode) {
+ case LM_NONE:
+ string_output_append(sov, *obj);
+ goto format_string;
+ break;
+
+ case LM_STARTED:
+ sov->range_start.s = *obj;
+ sov->range_end.s = *obj;
+ sov->list_mode = LM_IN_PROGRESS;
+ break;
+
+ case LM_IN_PROGRESS:
+ if (sov->range_end.s + 1 == *obj) {
+ sov->range_end.s++;
+ break;
+ } else {
+ if (sov->range_start.s == sov->range_end.s) {
+ string_output_append(sov, sov->range_end.s);
+ } else {
+ assert(sov->range_start.s < sov->range_end.s);
+ string_output_append_range(sov, sov->range_start.s,
+ sov->range_end.s -
+ sov->range_start.s + 1);
+ }
+
+ sov->range_start.s = *obj;
+ sov->range_end.s = *obj;
+ }
+ break;
+
+ case LM_END:
+ if (sov->range_end.s + 1 == *obj) {
+ sov->range_end.s++;
+ assert(sov->range_start.s < sov->range_end.s);
+ string_output_append_range(sov, sov->range_start.s,
+ sov->range_end.s -
+ sov->range_start.s + 1);
+ } else {
+ if (sov->range_start.s == sov->range_end.s) {
+ string_output_append(sov, sov->range_end.s);
+ } else {
+ assert(sov->range_start.s < sov->range_end.s);
+
+ string_output_append_range(sov, sov->range_start.s,
+ sov->range_end.s -
+ sov->range_start.s + 1);
+ }
+ string_output_append(sov, *obj);
+ }
+
+format_string:
+ QTAILQ_FOREACH(r, sov->ranges, entry) {
+ if (r->length > 1) {
+ g_string_append_printf(sov->string, "%" PRId64 "-%" PRId64,
+ r->start,
+ s_range_end(r->start, r->length));
+ } else {
+ g_string_append_printf(sov->string, "%" PRId64,
+ r->start);
+ }
+ if (r->entry.tqe_next) {
+ g_string_append(sov->string, ",");
+ }
+ }
+
+ if (sov->human) {
+ g_string_append(sov->string, " (");
+ QTAILQ_FOREACH(r, sov->ranges, entry) {
+ if (r->length > 1) {
+ g_string_append_printf(sov->string, "%" PRIx64 "-%" PRIx64,
+ r->start,
+ s_range_end(r->start, r->length));
+ } else {
+ g_string_append_printf(sov->string, "%" PRIx64,
+ r->start);
+ }
+ if (r->entry.tqe_next) {
+ g_string_append(sov->string, ",");
+ }
+ }
+ g_string_append(sov->string, ")");
+ }
+
+ break;
+
+ default:
+ abort();
}
- string_output_set(sov, out);
}
static void print_type_size(Visitor *v, uint64_t *obj, const char *name,
@@ -103,9 +248,61 @@ static void print_type_number(Visitor *v, double *obj, const char *name,
string_output_set(sov, g_strdup_printf("%f", *obj));
}
+static void
+start_list(Visitor *v, const char *name, Error **errp)
+{
+ StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
+
+ /* we can't traverse a list in a list */
+ assert(sov->list_mode == LM_NONE);
+ sov->list_mode = LM_STARTED;
+ sov->head = true;
+}
+
+static GenericList *
+next_list(Visitor *v, GenericList **list, Error **errp)
+{
+ StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
+ GenericList *ret = NULL;
+ if (*list) {
+ if (sov->head) {
+ ret = *list;
+ } else {
+ ret = (*list)->next;
+ }
+
+ if (sov->head) {
+ if (ret && ret->next == NULL) {
+ sov->list_mode = LM_NONE;
+ }
+ sov->head = false;
+ } else {
+ if (ret && ret->next == NULL) {
+ sov->list_mode = LM_END;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static void
+end_list(Visitor *v, Error **errp)
+{
+ StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
+
+ assert(sov->list_mode == LM_STARTED ||
+ sov->list_mode == LM_END ||
+ sov->list_mode == LM_NONE ||
+ sov->list_mode == LM_IN_PROGRESS);
+ sov->list_mode = LM_NONE;
+ sov->head = true;
+
+}
+
char *string_output_get_string(StringOutputVisitor *sov)
{
- char *string = sov->string;
+ char *string = g_string_free(sov->string, false);
sov->string = NULL;
return string;
}
@@ -117,7 +314,20 @@ Visitor *string_output_get_visitor(StringOutputVisitor *sov)
void string_output_visitor_cleanup(StringOutputVisitor *sov)
{
- g_free(sov->string);
+ SignedRange *r, *next;
+
+ if (sov->string) {
+ g_string_free(sov->string, true);
+ }
+
+ if (sov->ranges) {
+ QTAILQ_FOREACH_SAFE(r, sov->ranges, entry, next) {
+ QTAILQ_REMOVE(sov->ranges, r, entry);
+ s_range_free(r);
+ }
+ g_free(sov->ranges);
+ }
+
g_free(sov);
}
@@ -127,6 +337,7 @@ StringOutputVisitor *string_output_visitor_new(bool human)
v = g_malloc0(sizeof(*v));
+ v->string = g_string_new(NULL);
v->human = human;
v->visitor.type_enum = output_type_enum;
v->visitor.type_int = print_type_int;
@@ -134,6 +345,9 @@ StringOutputVisitor *string_output_visitor_new(bool human)
v->visitor.type_bool = print_type_bool;
v->visitor.type_str = print_type_str;
v->visitor.type_number = print_type_number;
+ v->visitor.start_list = start_list;
+ v->visitor.next_list = next_list;
+ v->visitor.end_list = end_list;
return v;
}
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 22363d1..a460377 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -57,6 +57,39 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
g_free(str);
}
+static void test_visitor_out_intList(TestOutputVisitorData *data,
+ const void *unused)
+{
+ int64_t value[] = {-10, -7, -2, -1, 0, 1, 9, 10, 16, 15, 14,
+ 3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX};
+ intList *list = NULL, **tmp = &list;
+ int i;
+ Error *errp = NULL;
+ char *str;
+
+ for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) {
+ *tmp = g_malloc0(sizeof(**tmp));
+ (*tmp)->value = value[i];
+ tmp = &(*tmp)->next;
+ }
+
+ visit_type_intList(data->ov, &list, NULL, &errp);
+ g_assert(error_is_set(&errp) == 0);
+
+ str = string_output_get_string(data->sov);
+ g_assert(str != NULL);
+ g_assert_cmpstr(str, ==,
+ "-10,-7,-2-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807");
+ g_free(str);
+#if 0
+ while (list) {
+ tmp2 = list->next;
+ g_free(list);
+ list = tmp2;
+ }
+#endif
+}
+
static void test_visitor_out_bool(TestOutputVisitorData *data,
const void *unused)
{
@@ -182,6 +215,8 @@ int main(int argc, char **argv)
&out_visitor_data, test_visitor_out_enum);
output_visitor_test_add("/string-visitor/output/enum-errors",
&out_visitor_data, test_visitor_out_enum_errors);
+ output_visitor_test_add("/string-visitor/output/intList",
+ &out_visitor_data, test_visitor_out_intList);
g_test_run();
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 34/34] hmp: add info memdev
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (31 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 32/34] qom: introduce object_property_get_enum and object_property_get_uint16List hutao
@ 2014-03-26 10:37 ` hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 33/34] qmp: add query-memdev hutao
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
This is the hmp counterpart of qmp query-memdev.
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
hmp.c | 36 ++++++++++++++++++++++++++++++++++++
hmp.h | 1 +
monitor.c | 7 +++++++
3 files changed, 44 insertions(+)
diff --git a/hmp.c b/hmp.c
index 2f279c4..b500856 100644
--- a/hmp.c
+++ b/hmp.c
@@ -22,6 +22,8 @@
#include "qemu/sockets.h"
#include "monitor/monitor.h"
#include "qapi/opts-visitor.h"
+#include "qapi/string-output-visitor.h"
+#include "qapi-visit.h"
#include "ui/console.h"
#include "block/qapi.h"
#include "qemu-io.h"
@@ -1647,3 +1649,37 @@ void hmp_object_del(Monitor *mon, const QDict *qdict)
qmp_object_del(id, &err);
hmp_handle_error(mon, &err);
}
+
+void hmp_info_memdev(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ MemdevList *memdev_list = qmp_query_memdev(&err);
+ MemdevList *m = memdev_list;
+ StringOutputVisitor *ov;
+ int i = 0;
+
+
+ while (m) {
+ ov = string_output_visitor_new(false);
+ visit_type_uint16List(string_output_get_visitor(ov),
+ &m->value->host_nodes, NULL, NULL);
+ monitor_printf(mon, "memory device %d\n", i);
+ monitor_printf(mon, " size: %ld\n", m->value->size);
+ monitor_printf(mon, " merge: %s\n",
+ m->value->merge ? "true" : "false");
+ monitor_printf(mon, " dump: %s\n",
+ m->value->dump ? "true" : "false");
+ monitor_printf(mon, " prealloc: %s\n",
+ m->value->prealloc ? "true" : "false");
+ monitor_printf(mon, " policy: %s\n",
+ HostMemPolicy_lookup[m->value->policy]);
+ monitor_printf(mon, " host nodes: %s\n",
+ string_output_get_string(ov));
+
+ string_output_visitor_cleanup(ov);
+ m = m->next;
+ i++;
+ }
+
+ monitor_printf(mon, "\n");
+}
diff --git a/hmp.h b/hmp.h
index ed58f0e..b6f5d02 100644
--- a/hmp.h
+++ b/hmp.h
@@ -92,5 +92,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict);
void hmp_cpu_add(Monitor *mon, const QDict *qdict);
void hmp_object_add(Monitor *mon, const QDict *qdict);
void hmp_object_del(Monitor *mon, const QDict *qdict);
+void hmp_info_memdev(Monitor *mon, const QDict *qdict);
#endif
diff --git a/monitor.c b/monitor.c
index 39f2518..408daca 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2966,6 +2966,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.cmd = hmp_info_tpm,
},
{
+ .name = "memdev",
+ .args_type = "",
+ .params = "",
+ .help = "show the memory device",
+ .mhandler.cmd = hmp_info_memdev,
+ },
+ {
.name = NULL,
},
};
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [Qemu-devel] [PATCH v3 33/34] qmp: add query-memdev
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
` (32 preceding siblings ...)
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 34/34] hmp: add info memdev hutao
@ 2014-03-26 10:37 ` hutao
33 siblings, 0 replies; 36+ messages in thread
From: hutao @ 2014-03-26 10:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org
Cc: ehabkost@redhat.com, imammedo@redhat.com, mtosatti@redhat.com,
Paolo Bonzini, a.motakis@virtualopensystems.com,
gaowanlong@cn.fujitsu.com
Add qmp command query-memdev to query for information
of memory devices
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
numa.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
qapi-schema.json | 34 ++++++++++++++++++++++++++
qmp-commands.hx | 32 +++++++++++++++++++++++++
3 files changed, 138 insertions(+)
diff --git a/numa.c b/numa.c
index fa117f0..77b6ca1 100644
--- a/numa.c
+++ b/numa.c
@@ -32,9 +32,14 @@
#include "qapi-visit.h"
#include "qapi/opts-visitor.h"
#include "qapi/dealloc-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/string-output-visitor.h"
+#include "qapi/string-input-visitor.h"
#include "qapi/qmp/qerror.h"
#include "hw/boards.h"
#include "sysemu/hostmem.h"
+#include "qmp-commands.h"
QemuOptsList qemu_numa_opts = {
.name = "numa",
@@ -281,3 +286,70 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
addr += size;
}
}
+
+MemdevList *qmp_query_memdev(Error **errp)
+{
+ MemdevList *list = NULL, *m;
+ HostMemoryBackend *backend;
+ Error *err = NULL;
+ int i;
+
+ for (i = 0; i < nb_numa_nodes; i++) {
+ backend = numa_info[i].node_memdev;
+
+ m = g_malloc0(sizeof(*m));
+ m->value = g_malloc0(sizeof(*m->value));
+ m->value->size = object_property_get_int(OBJECT(backend), "size",
+ &err);
+ if (err) {
+ goto error;
+ }
+
+ m->value->merge = object_property_get_bool(OBJECT(backend), "merge",
+ &err);
+ if (err) {
+ goto error;
+ }
+
+ m->value->dump = object_property_get_bool(OBJECT(backend), "dump",
+ &err);
+ if (err) {
+ goto error;
+ }
+
+ m->value->prealloc = object_property_get_bool(OBJECT(backend),
+ "prealloc", &err);
+ if (err) {
+ goto error;
+ }
+
+ m->value->policy = object_property_get_enum(OBJECT(backend),
+ "policy",
+ HostMemPolicy_lookup,
+ &err);
+ if (err) {
+ goto error;
+ }
+
+ object_property_get_uint16List(OBJECT(backend), "host-nodes",
+ &m->value->host_nodes, &err);
+ if (err) {
+ goto error;
+ }
+
+ m->next = list;
+ list = m;
+ }
+
+ return list;
+
+error:
+ while (list) {
+ m = list;
+ list = list->next;
+ g_free(m->value);
+ g_free(m);
+ }
+ qerror_report_err(err);
+ return NULL;
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index 5aea3ed..ee89d29 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4743,3 +4743,37 @@
##
{ 'enum': 'HostMemPolicy',
'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
+
+##
+# @Memdev:
+#
+# Information of memory device
+#
+# @size: memory device size
+#
+# @host-nodes: host nodes for its memory policy
+#
+# @policy: memory policy of memory device
+#
+# Since: 2.1
+##
+
+{ 'type': 'Memdev',
+ 'data': {
+ 'size': 'size',
+ 'merge': 'bool',
+ 'dump': 'bool',
+ 'prealloc': 'bool',
+ 'host-nodes': ['uint16'],
+ 'policy': 'HostMemPolicy' }}
+
+##
+# @query-memdev:
+#
+# Returns information for all memory devices.
+#
+# Returns: a list of @Memdev.
+#
+# Since: 2.1
+##
+{ 'command': 'query-memdev', 'returns': ['Memdev'] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index a22621f..a513b40 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3560,3 +3560,35 @@ Example:
} } ] }
EQMP
+
+ {
+ .name = "query-memdev",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_memdev,
+ },
+
+SQMP
+query-memdev
+------------
+
+Show memory devices information.
+
+
+Example (1):
+
+-> { "execute": "query-memdev" }
+<- { "return": [
+ {
+ "size": 536870912,
+ "host-nodes": [0, 1],
+ "policy": "bind"
+ },
+ {
+ "size": 536870912,
+ "host-nodes": [2, 3],
+ "policy": "preferred"
+ }
+ ]
+ }
+
+EQMP
--
1.8.5.2.229.g4448466
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [Qemu-devel] [PATCH v3 31/34] qapi: make string output visitor parse int list
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 31/34] qapi: make string output visitor parse int list hutao
@ 2014-03-26 10:48 ` Paolo Bonzini
0 siblings, 0 replies; 36+ messages in thread
From: Paolo Bonzini @ 2014-03-26 10:48 UTC (permalink / raw)
To: hutao@cn.fujitsu.com, qemu-devel@nongnu.org
Cc: imammedo@redhat.com, mtosatti@redhat.com, ehabkost@redhat.com,
gaowanlong@cn.fujitsu.com, a.motakis@virtualopensystems.com
Il 26/03/2014 11:37, hutao@cn.fujitsu.com ha scritto:
> Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Just a small comment below.
> ---
> qapi/string-output-visitor.c | 236 +++++++++++++++++++++++++++++++++++--
> tests/test-string-output-visitor.c | 35 ++++++
> 2 files changed, 260 insertions(+), 11 deletions(-)
>
> diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
> index fb1d2e8..edfc0a4 100644
> --- a/qapi/string-output-visitor.c
> +++ b/qapi/string-output-visitor.c
> @@ -16,32 +16,177 @@
> #include "qapi/qmp/qerror.h"
> #include "qemu/host-utils.h"
> #include <math.h>
> +#include "qemu/range.h"
> +
> +enum ListMode {
> + LM_NONE, /* not traversing a list of repeated options */
> + LM_STARTED, /* start_list() succeeded */
> +
> + LM_IN_PROGRESS, /* next_list() has been called.
> + *
> + * Generating the next list link will consume the most
> + * recently parsed QemuOpt instance of the repeated
> + * option.
> + *
> + * Parsing a value into the list link will examine the
> + * next QemuOpt instance of the repeated option, and
> + * possibly enter LM_SIGNED_INTERVAL or
> + * LM_UNSIGNED_INTERVAL.
> + */
> +
> + LM_SIGNED_INTERVAL, /* next_list() has been called.
> + *
> + * Generating the next list link will consume the most
> + * recently stored element from the signed interval,
> + * parsed from the most recent QemuOpt instance of the
> + * repeated option. This may consume QemuOpt itself
> + * and return to LM_IN_PROGRESS.
> + *
> + * Parsing a value into the list link will store the
> + * next element of the signed interval.
> + */
> +
> + LM_UNSIGNED_INTERVAL,/* Same as above, only for an unsigned interval. */
> +
> + LM_END
> +};
> +
> +typedef enum ListMode ListMode;
>
> struct StringOutputVisitor
> {
> Visitor visitor;
> bool human;
> - char *string;
> + GString *string;
> + bool head;
> + ListMode list_mode;
> + union {
> + int64_t s;
> + uint64_t u;
> + } range_start, range_end;
> + SignedRangeList *ranges;
> };
>
> static void string_output_set(StringOutputVisitor *sov, char *string)
> {
> - g_free(sov->string);
> - sov->string = string;
> + if (sov->string) {
> + g_string_free(sov->string, true);
> + }
> + sov->string = g_string_new(string);
> + g_free(string);
> +}
> +
> +static void string_output_append(StringOutputVisitor *sov, int64_t a)
> +{
> + range_list_add(sov->ranges, a, 1);
> +}
> +
> +static void string_output_append_range(StringOutputVisitor *sov,
> + int64_t s, int64_t e)
> +{
> + range_list_add(sov->ranges, s, e);
> }
>
> static void print_type_int(Visitor *v, int64_t *obj, const char *name,
> Error **errp)
> {
> StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> - char *out;
> + SignedRange *r;
>
> - if (sov->human) {
> - out = g_strdup_printf("%lld (%#llx)", (long long) *obj, (long long) *obj);
> - } else {
> - out = g_strdup_printf("%lld", (long long) *obj);
> + if (!sov->ranges) {
> + sov->ranges = g_malloc0(sizeof(*sov->ranges));
> + QTAILQ_INIT(sov->ranges);
> + }
> +
> + switch (sov->list_mode) {
> + case LM_NONE:
> + string_output_append(sov, *obj);
> + goto format_string;
> + break;
> +
No need for the goto if...
> + case LM_STARTED:
> + sov->range_start.s = *obj;
> + sov->range_end.s = *obj;
> + sov->list_mode = LM_IN_PROGRESS;
> + break;
... you have "return;" here
> + case LM_IN_PROGRESS:
> + if (sov->range_end.s + 1 == *obj) {
> + sov->range_end.s++;
> + break;
(unnecessary break)
> + } else {
> + if (sov->range_start.s == sov->range_end.s) {
> + string_output_append(sov, sov->range_end.s);
> + } else {
> + assert(sov->range_start.s < sov->range_end.s);
> + string_output_append_range(sov, sov->range_start.s,
> + sov->range_end.s -
> + sov->range_start.s + 1);
> + }
> +
> + sov->range_start.s = *obj;
> + sov->range_end.s = *obj;
> + }
> + break;
... and "return;" here...
> + case LM_END:
> + if (sov->range_end.s + 1 == *obj) {
> + sov->range_end.s++;
> + assert(sov->range_start.s < sov->range_end.s);
> + string_output_append_range(sov, sov->range_start.s,
> + sov->range_end.s -
> + sov->range_start.s + 1);
> + } else {
> + if (sov->range_start.s == sov->range_end.s) {
> + string_output_append(sov, sov->range_end.s);
> + } else {
> + assert(sov->range_start.s < sov->range_end.s);
> +
> + string_output_append_range(sov, sov->range_start.s,
> + sov->range_end.s -
> + sov->range_start.s + 1);
> + }
> + string_output_append(sov, *obj);
> + }
... and "break;" here" and move the formatting code outside the "switch".
> +format_string:
> + QTAILQ_FOREACH(r, sov->ranges, entry) {
> + if (r->length > 1) {
> + g_string_append_printf(sov->string, "%" PRId64 "-%" PRId64,
> + r->start,
> + s_range_end(r->start, r->length));
> + } else {
> + g_string_append_printf(sov->string, "%" PRId64,
> + r->start);
> + }
> + if (r->entry.tqe_next) {
> + g_string_append(sov->string, ",");
> + }
> + }
> +
> + if (sov->human) {
> + g_string_append(sov->string, " (");
> + QTAILQ_FOREACH(r, sov->ranges, entry) {
> + if (r->length > 1) {
> + g_string_append_printf(sov->string, "%" PRIx64 "-%" PRIx64,
> + r->start,
> + s_range_end(r->start, r->length));
> + } else {
> + g_string_append_printf(sov->string, "%" PRIx64,
> + r->start);
> + }
> + if (r->entry.tqe_next) {
> + g_string_append(sov->string, ",");
> + }
> + }
> + g_string_append(sov->string, ")");
> + }
> +
> + break;
> +
> + default:
> + abort();
> }
> - string_output_set(sov, out);
> }
>
> static void print_type_size(Visitor *v, uint64_t *obj, const char *name,
> @@ -103,9 +248,61 @@ static void print_type_number(Visitor *v, double *obj, const char *name,
> string_output_set(sov, g_strdup_printf("%f", *obj));
> }
>
> +static void
> +start_list(Visitor *v, const char *name, Error **errp)
> +{
> + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> +
> + /* we can't traverse a list in a list */
> + assert(sov->list_mode == LM_NONE);
> + sov->list_mode = LM_STARTED;
> + sov->head = true;
> +}
> +
> +static GenericList *
> +next_list(Visitor *v, GenericList **list, Error **errp)
> +{
> + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> + GenericList *ret = NULL;
> + if (*list) {
> + if (sov->head) {
> + ret = *list;
> + } else {
> + ret = (*list)->next;
> + }
> +
> + if (sov->head) {
> + if (ret && ret->next == NULL) {
> + sov->list_mode = LM_NONE;
> + }
> + sov->head = false;
> + } else {
> + if (ret && ret->next == NULL) {
> + sov->list_mode = LM_END;
> + }
> + }
> + }
> +
> + return ret;
> +}
> +
> +static void
> +end_list(Visitor *v, Error **errp)
> +{
> + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> +
> + assert(sov->list_mode == LM_STARTED ||
> + sov->list_mode == LM_END ||
> + sov->list_mode == LM_NONE ||
> + sov->list_mode == LM_IN_PROGRESS);
> + sov->list_mode = LM_NONE;
> + sov->head = true;
> +
> +}
> +
> char *string_output_get_string(StringOutputVisitor *sov)
> {
> - char *string = sov->string;
> + char *string = g_string_free(sov->string, false);
> sov->string = NULL;
> return string;
> }
> @@ -117,7 +314,20 @@ Visitor *string_output_get_visitor(StringOutputVisitor *sov)
>
> void string_output_visitor_cleanup(StringOutputVisitor *sov)
> {
> - g_free(sov->string);
> + SignedRange *r, *next;
> +
> + if (sov->string) {
> + g_string_free(sov->string, true);
> + }
> +
> + if (sov->ranges) {
> + QTAILQ_FOREACH_SAFE(r, sov->ranges, entry, next) {
> + QTAILQ_REMOVE(sov->ranges, r, entry);
> + s_range_free(r);
> + }
> + g_free(sov->ranges);
> + }
> +
> g_free(sov);
> }
>
> @@ -127,6 +337,7 @@ StringOutputVisitor *string_output_visitor_new(bool human)
>
> v = g_malloc0(sizeof(*v));
>
> + v->string = g_string_new(NULL);
> v->human = human;
> v->visitor.type_enum = output_type_enum;
> v->visitor.type_int = print_type_int;
> @@ -134,6 +345,9 @@ StringOutputVisitor *string_output_visitor_new(bool human)
> v->visitor.type_bool = print_type_bool;
> v->visitor.type_str = print_type_str;
> v->visitor.type_number = print_type_number;
> + v->visitor.start_list = start_list;
> + v->visitor.next_list = next_list;
> + v->visitor.end_list = end_list;
>
> return v;
> }
> diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
> index 22363d1..a460377 100644
> --- a/tests/test-string-output-visitor.c
> +++ b/tests/test-string-output-visitor.c
> @@ -57,6 +57,39 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
> g_free(str);
> }
>
> +static void test_visitor_out_intList(TestOutputVisitorData *data,
> + const void *unused)
> +{
> + int64_t value[] = {-10, -7, -2, -1, 0, 1, 9, 10, 16, 15, 14,
> + 3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX};
> + intList *list = NULL, **tmp = &list;
> + int i;
> + Error *errp = NULL;
> + char *str;
> +
> + for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) {
> + *tmp = g_malloc0(sizeof(**tmp));
> + (*tmp)->value = value[i];
> + tmp = &(*tmp)->next;
> + }
> +
> + visit_type_intList(data->ov, &list, NULL, &errp);
> + g_assert(error_is_set(&errp) == 0);
> +
> + str = string_output_get_string(data->sov);
> + g_assert(str != NULL);
> + g_assert_cmpstr(str, ==,
> + "-10,-7,-2-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807");
> + g_free(str);
> +#if 0
> + while (list) {
> + tmp2 = list->next;
> + g_free(list);
> + list = tmp2;
> + }
> +#endif
> +}
> +
> static void test_visitor_out_bool(TestOutputVisitorData *data,
> const void *unused)
> {
> @@ -182,6 +215,8 @@ int main(int argc, char **argv)
> &out_visitor_data, test_visitor_out_enum);
> output_visitor_test_add("/string-visitor/output/enum-errors",
> &out_visitor_data, test_visitor_out_enum_errors);
> + output_visitor_test_add("/string-visitor/output/intList",
> + &out_visitor_data, test_visitor_out_intList);
>
> g_test_run();
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2014-03-26 11:12 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-26 10:36 [Qemu-devel] [PATCH v3 00/34] NUMA series v3 hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 01/34] NUMA: move numa related code to new file numa.c hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 02/34] NUMA: check if the total numa memory size is equal to ram_size hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 05/34] NUMA: expand MAX_NODES from 64 to 128 hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 08/34] vl: convert -m to QemuOpts hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 07/34] qemu-option: introduce qemu_find_opts_singleton hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 09/34] vl: redo -object parsing hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 06/34] man: improve -numa doc hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 03/34] NUMA: Add numa_info structure to contain numa nodes info hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 04/34] NUMA: convert -numa option to use OptsVisitor hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 10/34] qmp: allow object-add completion handler to get canonical path hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 14/34] add memdev backend infrastructure hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 16/34] memory: reorganize file-based allocation hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 12/34] pc: pass QEMUMachineInitArgs to pc_memory_init hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 11/34] qmp: improve error reporting for -object and object-add hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 15/34] numa: add -numa node,memdev= option hutao
2014-03-26 10:36 ` [Qemu-devel] [PATCH v3 13/34] numa: introduce memory_region_allocate_system_memory hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 23/34] hostmem: add merge and dump properties hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 21/34] hostmem: add file-based HostMemoryBackend hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 20/34] memory: move RAM_PREALLOC_MASK to exec.c, rename hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 22/34] hostmem: separate allocation from UserCreatable complete method hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 17/34] memory: move mem_path handling to memory_region_allocate_system_memory hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 18/34] memory: add error propagation to file-based RAM allocation hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 19/34] memory: move preallocation code out of exec.c hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 24/34] hostmem: allow preallocation of any memory region hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 26/34] configure: add Linux libnuma detection hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 27/34] hostmem: add properties for NUMA memory policy hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 25/34] hostmem: add property to map memory with MAP_SHARED hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 29/34] Introduce signed range hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 31/34] qapi: make string output visitor parse int list hutao
2014-03-26 10:48 ` Paolo Bonzini
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 30/34] qapi: make string input " hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 28/34] hw: switch all boards to use memory_region_allocate_system_memory hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 32/34] qom: introduce object_property_get_enum and object_property_get_uint16List hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 34/34] hmp: add info memdev hutao
2014-03-26 10:37 ` [Qemu-devel] [PATCH v3 33/34] qmp: add query-memdev hutao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).