* [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work
@ 2013-12-11 12:19 Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 01/14] NUMA: move numa related code to new file numa.c Paolo Bonzini
` (13 more replies)
0 siblings, 14 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
Hi,
this is a proposal for a common tree for memory hotplug and NUMA
policy patches.
The common base for these tree is Igor's "memory device" QOM hierarchy,
that subsumes and improves on the "-numa mem" concept that I had proposed.
These patches include a basic conversion of his QOM hierarchy to -object.
Stefan and Igor are looking at improving -object, but this is not required
to build on this series.
Thanks to the memory device object, NUMA nodes' memory allocation
be expressed easily via a new suboption "-numa node,memdev=ID".
For example:
-object memory-ram,size=1024M,id=ram-node0 \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-object memory-ram,size=1024M,id=ram-node1 \
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
-m 2048
memdev=ID is alternative to mem=SIZE: if you use memdev for one node,
you must use it for all of them. When memdev is in use, the single
large RAM memory region is replaced by a container region, with all
memdevs layed out one after another.
The integration between boards and the NUMA subsystem is done by
a new function in numa.c, memory_region_allocate_system_memory.
Thus, boards have to request NUMA-aware allocation explicitly.
This however is not a change compared to Wanlong's patches: both
the early ones that hardcoded the "pc.ram" memory region name,
and the latest version that similarly introduced a function for
boards to call (memory_region_set_mem_policy in his patches).
Wanlong can then proceed to add policy properties (hostnode, policy)
to backends/hostmem-ram.c, and these will be automatically applicable
to hotpluggable memory as well.
I'm quite happy with the design of both series. It took quite a long
time, but it shows the power of the host/guest separation that is
already present in -blockdev/-chardev/-netdev.
You can find this at refs/heads/numa in my github repository, where
I included also the monitor object-add/object-del patches.
Paolo
Igor Mammedov (3):
qapi: add SIZE type parser to string_input_visitor
vl: convert -m to QemuOpts
add memdev backend infrastructure
Paolo Bonzini (6):
QemuOpts: introduce qemu_find_opts_singleton
qom: fix leak for objects created with -object
qom: catch errors in object_property_add_child
pc: pass QEMUMachineInitArgs to pc_memory_init
numa: introduce memory_region_allocate_system_memory
numa: add -numa node,memdev= option
Wanlong Gao (5):
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
Makefile.target | 2 +-
backends/Makefile.objs | 2 +
backends/hostmem-ram.c | 46 ++++++++
backends/hostmem.c | 116 ++++++++++++++++++++
cpus.c | 14 ---
hw/i386/pc.c | 27 ++---
hw/i386/pc_piix.c | 8 +-
hw/i386/pc_q35.c | 4 +-
include/hw/i386/pc.h | 7 +-
include/qemu/config-file.h | 2 +
include/sysemu/cpus.h | 1 -
include/sysemu/hostmem.h | 63 +++++++++++
include/sysemu/sysemu.h | 21 +++-
monitor.c | 2 +-
numa.c | 259 ++++++++++++++++++++++++++++++++++++++++++++
qapi-schema.json | 34 ++++++
qapi/string-input-visitor.c | 18 +++
qemu-options.hx | 7 +-
qom/object.c | 9 +-
util/qemu-config.c | 14 +++
vl.c | 221 ++++++++++---------------------------
21 files changed, 664 insertions(+), 213 deletions(-)
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.4.2
^ permalink raw reply [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 01/14] NUMA: move numa related code to new file numa.c
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 02/14] NUMA: check if the total numa memory size is equal to ram_size Paolo Bonzini
` (12 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
Makefile.target | 2 +-
cpus.c | 14 ----
include/sysemu/cpus.h | 1 -
include/sysemu/sysemu.h | 3 +
numa.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++
vl.c | 139 +-----------------------------------
6 files changed, 187 insertions(+), 154 deletions(-)
create mode 100644 numa.c
diff --git a/Makefile.target b/Makefile.target
index af6ac7e..0197c17 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 01d128d..53360b0 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1297,20 +1297,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/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 495dae8..2509649 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -136,6 +136,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..ce7736a
--- /dev/null
+++ b/numa.c
@@ -0,0 +1,182 @@
+/*
+ * 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"
+
+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 b0399de..a5c6f17 100644
--- a/vl.c
+++ b/vl.c
@@ -1262,102 +1262,6 @@ char *get_boot_devices_list(size_t *size)
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",
@@ -4157,48 +4061,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.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 02/14] NUMA: check if the total numa memory size is equal to ram_size
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 01/14] NUMA: move numa related code to new file numa.c Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 18:48 ` Eric Blake
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 03/14] NUMA: Add numa_info structure to contain numa nodes info Paolo Bonzini
` (11 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
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 talb, 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>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
numa.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/numa.c b/numa.c
index ce7736a..beda80e 100644
--- a/numa.c
+++ b/numa.c
@@ -150,6 +150,16 @@ void set_numa_nodes(void)
node_mem[i] = ram_size - usedmem;
}
+ uint64_t numa_total = 0;
+ for (i = 0; i < nb_numa_nodes; i++) {
+ numa_total += node_mem[i];
+ }
+ if (numa_total != ram_size) {
+ fprintf(stderr, "qemu: numa nodes total memory size "
+ "should equal to ram_size\n");
+ exit(1);
+ }
+
for (i = 0; i < nb_numa_nodes; i++) {
if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) {
break;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 03/14] NUMA: Add numa_info structure to contain numa nodes info
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 01/14] NUMA: move numa related code to new file numa.c Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 02/14] NUMA: check if the total numa memory size is equal to ram_size Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor Paolo Bonzini
` (10 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha, Andre Przywara
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>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 12 ++++++++----
include/sysemu/sysemu.h | 8 ++++++--
monitor.c | 2 +-
numa.c | 23 ++++++++++++-----------
vl.c | 7 +++----
5 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 12c436e..74c1f16 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -670,14 +670,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) *
@@ -1072,8 +1072,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);
@@ -1081,7 +1085,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/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 2509649..d873b42 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 */
@@ -134,8 +135,11 @@ extern QEMUClockType rtc_clock;
#define MAX_NODES 64
#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 845f608..b97b7d3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2004,7 +2004,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 beda80e..1bc0fad 100644
--- a/numa.c
+++ b/numa.c
@@ -61,7 +61,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:
@@ -101,7 +101,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);
@@ -109,7 +109,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);
@@ -134,7 +134,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;
}
if (i == nb_numa_nodes) {
@@ -144,15 +144,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;
}
uint64_t 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) {
fprintf(stderr, "qemu: numa nodes total memory size "
@@ -161,7 +162,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;
}
}
@@ -171,7 +172,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);
}
}
}
@@ -184,7 +185,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 a5c6f17..53a412f 100644
--- a/vl.c
+++ b/vl.c
@@ -248,8 +248,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;
@@ -2815,8 +2814,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.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (2 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 03/14] NUMA: Add numa_info structure to contain numa nodes info Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 18:51 ` Eric Blake
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 05/14] NUMA: expand MAX_NODES from 64 to 128 Paolo Bonzini
` (9 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/sysemu.h | 3 +-
numa.c | 148 +++++++++++++++++++++++-------------------------
qapi-schema.json | 30 ++++++++++
vl.c | 11 +++-
4 files changed, 114 insertions(+), 78 deletions(-)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d873b42..20b05a3 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -140,9 +140,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 1bc0fad..c4fa665 100644
--- a/numa.c
+++ b/numa.c
@@ -24,101 +24,97 @@
*/
#include "sysemu/sysemu.h"
-
-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"
+QemuOptsList qemu_numa_opts = {
+ .name = "numa",
+ .implied_opt_name = "type",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_numa_opts.head),
+ .desc = { { 0 } } /* validated with OptsVisitor */
+};
+
+static int numa_node_parse(NumaNodeOptions *opts)
{
- 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;
- }
+ uint16_t nodenr;
+ uint16List *cpus = NULL;
- 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 (opts->has_nodeid) {
+ nodenr = opts->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) {
+ fprintf(stderr, "qemu: Max number of NUMA nodes reached: %"
+ PRIu16 "\n", nodenr);
+ return -1;
}
- if (endvalue < value) {
- goto error;
+ for (cpus = opts->cpus; cpus; cpus = cpus->next) {
+ if (cpus->value > MAX_CPUMASK_BITS) {
+ fprintf(stderr, "qemu: cpu number %" PRIu16 " is bigger than %d",
+ cpus->value, MAX_CPUMASK_BITS);
+ continue;
+ }
+ bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
}
- bitmap_set(numa_info[nodenr].node_cpu, value, endvalue-value+1);
- return;
+ if (opts->has_mem) {
+ int64_t mem_size;
+ char *endptr;
+ mem_size = strtosz(opts->mem, &endptr);
+ if (mem_size < 0 || *endptr) {
+ fprintf(stderr, "qemu: invalid numa mem size: %s\n", opts->mem);
+ return -1;
+ }
+ numa_info[nodenr].node_mem = mem_size;
+ }
-error:
- fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus);
- exit(1);
+ return 0;
}
-void numa_add(const char *optarg)
+int numa_init_func(QemuOpts *opts, void *opaque)
{
- char option[128];
- char *endptr;
- unsigned long long nodenr;
-
- optarg = get_opt_name(option, 128, optarg, ',');
- if (*optarg == ',') {
- optarg++;
+ NumaOptions *object = NULL;
+ Error *err = NULL;
+ int ret = 0;
+
+ {
+ 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 (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 (error_is_set(&err)) {
+ fprintf(stderr, "qemu: %s\n", error_get_pretty(err));
+ error_free(err);
+ ret = -1;
+ goto error;
+ }
- 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);
+ switch (object->kind) {
+ case NUMA_OPTIONS_KIND_NODE:
+ ret = numa_node_parse(object->node);
+ if (ret) {
+ goto error;
}
nb_numa_nodes++;
- } else {
- fprintf(stderr, "Invalid -numa option: %s\n", option);
- exit(1);
+ break;
+ default:
+ fprintf(stderr, "qemu: Invalid NUMA options type.\n");
+ ret = -1;
}
+
+error:
+ 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 ret;
}
void set_numa_nodes(void)
diff --git a/qapi-schema.json b/qapi-schema.json
index d6f8615..d99e39d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4235,3 +4235,33 @@
# Since: 1.7
##
{ 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
+
+##
+# @NumaOptions
+#
+# A discriminated record of NUMA options. (for OptsVisitor)
+#
+# Since 2.0
+##
+{ 'union': 'NumaOptions',
+ 'data': {
+ 'node': 'NumaNodeOptions' }}
+
+##
+# @NumaNodeOptions
+#
+# Create a guest NUMA node. (for OptsVisitor)
+#
+# @nodeid: #optional NUMA node ID
+#
+# @cpus: #optional VCPUs belong to this node
+#
+# @mem: #optional memory size of this node
+#
+# Since: 2.0
+##
+{ 'type': 'NumaNodeOptions',
+ 'data': {
+ '*nodeid': 'uint16',
+ '*cpus': ['uint16'],
+ '*mem': 'str' }}
diff --git a/vl.c b/vl.c
index 53a412f..95181e0 100644
--- a/vl.c
+++ b/vl.c
@@ -2793,6 +2793,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_tpmdev_opts);
qemu_add_opts(&qemu_realtime_opts);
qemu_add_opts(&qemu_msg_opts);
+ qemu_add_opts(&qemu_numa_opts);
runstate_init();
@@ -2980,7 +2981,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);
@@ -4060,6 +4064,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.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 05/14] NUMA: expand MAX_NODES from 64 to 128
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (3 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 06/14] qapi: add SIZE type parser to string_input_visitor Paolo Bonzini
` (8 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
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>
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 20b05a3..4c94cf5 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -132,7 +132,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
#define MAX_CPUMASK_BITS 255
extern int nb_numa_nodes;
typedef struct node_info {
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 06/14] qapi: add SIZE type parser to string_input_visitor
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (4 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 05/14] NUMA: expand MAX_NODES from 64 to 128 Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 07/14] QemuOpts: introduce qemu_find_opts_singleton Paolo Bonzini
` (7 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
From: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qapi/string-input-visitor.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 8f1bc41..a152f5d 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -97,6 +97,23 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
*obj = val;
}
+static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
+ Error **errp)
+{
+ StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+ int64_t val;
+ char *endp;
+
+ val = strtosz_suffix(siv->string ? siv->string : "", &endp,
+ STRTOSZ_DEFSUFFIX_B);
+ if (val < 0 || *endp != '\0') {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, name,
+ "a size value representible as a non-negative int64");
+ return;
+ }
+ *obj = val;
+}
+
static void parse_start_optional(Visitor *v, bool *present,
const char *name, Error **errp)
{
@@ -131,6 +148,7 @@ 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.type_size = parse_type_size;
v->visitor.start_optional = parse_start_optional;
v->string = str;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 07/14] QemuOpts: introduce qemu_find_opts_singleton
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (5 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 06/14] qapi: add SIZE type parser to string_input_visitor Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 08/14] vl: convert -m to QemuOpts Paolo Bonzini
` (6 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
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 508428f..699c3a1 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -7,6 +7,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 04da942..c6ac589 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_nofail(list);
+ }
+ return opts;
+}
+
static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
{
CommandLineParameterInfoList *param_list = NULL, *entry;
diff --git a/vl.c b/vl.c
index 95181e0..ecda5ad 100644
--- a/vl.c
+++ b/vl.c
@@ -537,16 +537,7 @@ static QemuOptsList qemu_msg_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_nofail(list);
- }
- return opts;
+ return qemu_find_opts_singleton("machine");
}
const char *qemu_get_vm_name(void)
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 08/14] vl: convert -m to QemuOpts
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (6 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 07/14] QemuOpts: introduce qemu_find_opts_singleton Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 09/14] qom: fix leak for objects created with -object Paolo Bonzini
` (5 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
From: Igor Mammedov <imammedo@redhat.com>
Adds option to -m
"mem" - 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>
---
qemu-options.hx | 7 +++++--
vl.c | 52 +++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/qemu-options.hx b/qemu-options.hx
index af34483..416f8e4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -210,8 +210,11 @@ 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 [mem=]megs\n"
+ " configure guest RAM\n"
+ " mem: initial amount of guest memory (default: "
+ stringify(DEFAULT_RAM_SIZE) "Mb)\n",
+ QEMU_ARCH_ALL)
STEXI
@item -m @var{megs}
@findex -m
diff --git a/vl.c b/vl.c
index ecda5ad..68ba565 100644
--- a/vl.c
+++ b/vl.c
@@ -530,6 +530,20 @@ static QemuOptsList qemu_msg_opts = {
},
};
+static QemuOptsList qemu_mem_opts = {
+ .name = "memory-opts",
+ .implied_opt_name = "mem",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
+ .merge_lists = true,
+ .desc = {
+ {
+ .name = "mem",
+ .type = QEMU_OPT_SIZE,
+ },
+ { /* end of list */ }
+ },
+};
+
/**
* Get machine options
*
@@ -2746,6 +2760,7 @@ 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 = DEFAULT_RAM_SIZE * 1024 * 1024;
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
@@ -2785,6 +2800,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_numa_opts);
+ qemu_add_opts(&qemu_mem_opts);
runstate_init();
@@ -2800,7 +2816,7 @@ int main(int argc, char **argv, char **envp)
module_call_init(MODULE_INIT_MACHINE);
machine = 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;
@@ -3080,16 +3096,32 @@ 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);
+ opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
+ optarg, 1);
+
+ mem_str = qemu_opt_get(opts, "mem");
+ if (!mem_str) {
+ fprintf(stderr, "qemu: invalid -m option, missing "
+ " 'mem' option\n");
exit(1);
}
- sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+
+ sz = qemu_opt_get_size(opts, "mem", ram_size);
+
+ /* Fix up legacy suffix-less format */
+ if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+ sz <<= 20;
+ }
+
+ /* backward compatibility behaviour for case "-m 0" */
+ if (sz == 0) {
+ sz = default_ram_size;
+ }
+
+ sz = QEMU_ALIGN_UP(sz, 8192);
ram_size = sz;
if (ram_size != sz) {
fprintf(stderr, "qemu: ram size too large\n");
@@ -3929,10 +3961,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-opts"), "mem", ram_size);
if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
!= 0) {
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 09/14] qom: fix leak for objects created with -object
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (7 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 08/14] vl: convert -m to QemuOpts Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-12 8:18 ` Stefan Hajnoczi
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child Paolo Bonzini
` (4 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
The object must be unref-ed when its variable goes out of scope.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
vl.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/vl.c b/vl.c
index 68ba565..086a062 100644
--- a/vl.c
+++ b/vl.c
@@ -2717,12 +2717,13 @@ static int object_create(QemuOpts *opts, void *opaque)
obj = object_new(type);
if (qemu_opt_foreach(opts, object_set_property, obj, 1) < 0) {
+ object_unref(obj);
return -1;
}
object_property_add_child(container_get(object_get_root(), "/objects"),
id, obj, NULL);
-
+ object_unref(obj);
return 0;
}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (8 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 09/14] qom: fix leak for objects created with -object Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:44 ` Igor Mammedov
2013-12-12 8:18 ` Stefan Hajnoczi
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 11/14] pc: pass QEMUMachineInitArgs to pc_memory_init Paolo Bonzini
` (3 subsequent siblings)
13 siblings, 2 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qom/object.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index fc19cf6..68fe07a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -988,17 +988,22 @@ static void object_finalize_child_property(Object *obj, const char *name,
void object_property_add_child(Object *obj, const char *name,
Object *child, Error **errp)
{
+ Error *local_err = NULL;
gchar *type;
type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
object_property_add(obj, name, type, object_get_child_property,
- NULL, object_finalize_child_property, child, errp);
-
+ NULL, object_finalize_child_property, child, &local_err);
+ if (error_is_set(&local_err)) {
+ error_propagate(errp, local_err);
+ goto out;
+ }
object_ref(child);
g_assert(child->parent == NULL);
child->parent = obj;
+out:
g_free(type);
}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 11/14] pc: pass QEMUMachineInitArgs to pc_memory_init
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (9 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 12/14] numa: introduce memory_region_allocate_system_memory Paolo Bonzini
` (2 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
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 74c1f16..76c47a9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1148,10 +1148,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,
@@ -1163,7 +1161,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
@@ -1204,7 +1202,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 ab56285..cd3eda1 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -130,11 +130,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 97aa842..c2dcbae 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -115,9 +115,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 09652fb..7dda9a6 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"
@@ -140,10 +141,8 @@ static inline uint64_t pci_host_get_hole64_size(uint64_t pci_hole64_size)
void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,
uint64_t pci_hole64_size);
-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.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 12/14] numa: introduce memory_region_allocate_system_memory
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (10 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 11/14] pc: pass QEMUMachineInitArgs to pc_memory_init Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 13/14] add memdev backend infrastructure Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 14/14] numa: add -numa node, memdev= option Paolo Bonzini
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 4 +---
include/sysemu/sysemu.h | 5 +++++
numa.c | 10 ++++++++++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 76c47a9..61df5d4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1168,9 +1168,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_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/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 4c94cf5..e9da760 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -10,6 +10,8 @@
#include "qemu/notify.h"
#include "qemu/main-loop.h"
#include "qemu/bitmap.h"
+#include "qom/object.h"
+#include "hw/boards.h"
/* vl.c */
@@ -144,6 +146,9 @@ void set_numa_nodes(void);
void set_numa_modes(void);
extern QemuOptsList qemu_numa_opts;
int numa_init_func(QemuOpts *opts, void *opaque);
+void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+ const char *name,
+ QEMUMachineInitArgs *args);
#define MAX_OPTION_ROMS 16
typedef struct QEMUOptionRom {
diff --git a/numa.c b/numa.c
index c4fa665..f903b9e 100644
--- a/numa.c
+++ b/numa.c
@@ -187,3 +187,13 @@ void set_numa_modes(void)
}
}
}
+
+void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+ const char *name,
+ QEMUMachineInitArgs *args)
+{
+ uint64_t ram_size = args->ram_size;
+
+ memory_region_init_ram(mr, owner, name, ram_size);
+ vmstate_register_ram_global(mr);
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 13/14] add memdev backend infrastructure
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (11 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 12/14] numa: introduce memory_region_allocate_system_memory Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 14/14] numa: add -numa node, memdev= option Paolo Bonzini
13 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
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 | 46 +++++++++++++++++++
backends/hostmem.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/hostmem.h | 63 +++++++++++++++++++++++++
4 files changed, 227 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..3860cee
--- /dev/null
+++ b/backends/hostmem-ram.c
@@ -0,0 +1,46 @@
+/*
+ * 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"
+
+#define TYPE_MEMORY_BACKEND_RAM "memory-ram"
+
+
+static void
+ram_backend_memory_init(HostMemoryBackend *backend, Error **errp)
+{
+ if (!memory_region_size(&backend->mr)) {
+ 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)
+{
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
+
+ bc->memory_init = 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..91066e1
--- /dev/null
+++ b/backends/hostmem.c
@@ -0,0 +1,116 @@
+/*
+ * 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 "qemu/config-file.h"
+
+static void
+hostmemory_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
+hostmemory_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 hostmemory_backend_initfn(Object *obj)
+{
+ object_property_add(obj, "size", "int",
+ hostmemory_backend_get_size,
+ hostmemory_backend_set_size, NULL, NULL, NULL);
+}
+
+static void hostmemory_backend_finalize(Object *obj)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+ if (memory_region_size(&backend->mr)) {
+ memory_region_destroy(&backend->mr);
+ }
+}
+
+static void
+hostmemory_backend_memory_init(HostMemoryBackend *backend, Error **errp)
+{
+ error_setg(errp, "memory_init is not implemented for type [%s]",
+ object_get_typename(OBJECT(backend)));
+}
+
+MemoryRegion *
+host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
+{
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(backend);
+ Object *obj = OBJECT(backend);
+
+ if (!backend->size) {
+ error_setg(errp, "Invalid property [%s.size] value: %" PRIu64,
+ object_get_typename(obj), backend->size);
+ return NULL;
+ }
+
+ bc->memory_init(backend, errp);
+
+ return memory_region_size(&backend->mr) ? &backend->mr : NULL;
+}
+
+static void
+hostmemory_backend_class_init(ObjectClass *oc, void *data)
+{
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
+
+ bc->memory_init = hostmemory_backend_memory_init;
+}
+
+static const TypeInfo hostmemory_backend_info = {
+ .name = TYPE_MEMORY_BACKEND,
+ .parent = TYPE_OBJECT,
+ .abstract = true,
+ .class_size = sizeof(HostMemoryBackendClass),
+ .class_init = hostmemory_backend_class_init,
+ .instance_size = sizeof(HostMemoryBackend),
+ .instance_init = hostmemory_backend_initfn,
+ .instance_finalize = hostmemory_backend_finalize,
+};
+
+static void register_types(void)
+{
+ type_register_static(&hostmemory_backend_info);
+}
+
+type_init(register_types);
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
new file mode 100644
index 0000000..e047e45
--- /dev/null
+++ b/include/sysemu/hostmem.h
@@ -0,0 +1,63 @@
+/*
+ * 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_RAM_H
+#define QEMU_RAM_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "exec/memory.h"
+#include "qemu/option.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
+ * @memory_init: hook for derived classes to perform memory allocation
+ */
+struct HostMemoryBackendClass {
+ ObjectClass parent_class;
+
+ void (*memory_init)(HostMemoryBackend *backend, Error **errp);
+};
+
+/**
+ * @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.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [RFC PATCH 14/14] numa: add -numa node, memdev= option
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
` (12 preceding siblings ...)
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 13/14] add memdev backend infrastructure Paolo Bonzini
@ 2013-12-11 12:19 ` Paolo Bonzini
2013-12-11 15:36 ` Igor Mammedov
13 siblings, 1 reply; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 12:19 UTC (permalink / raw)
To: qemu-devel; +Cc: imammedo, gaowanlong, stefanha
This option provides the infrastructure for binding guest NUMA nodes
to host NUMA nodes. For example:
-object memory-ram,size=1024M,policy=membind,host-nodes=0,id=ram-node0 \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-object memory-ram,size=1024M,policy=interleave,host-nodes=1-3,id=ram-node1 \
-numa node,nodeid=1,cpus=1,memdev=ram-node1
The option replaces "-numa mem".
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/sysemu.h | 2 ++
numa.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--
qapi-schema.json | 6 ++++-
3 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index e9da760..acfc0c7 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -12,6 +12,7 @@
#include "qemu/bitmap.h"
#include "qom/object.h"
#include "hw/boards.h"
+#include "sysemu/hostmem.h"
/* vl.c */
@@ -140,6 +141,7 @@ extern int nb_numa_nodes;
typedef struct node_info {
uint64_t node_mem;
DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
+ HostMemoryBackend *node_memdev;
} NodeInfo;
extern NodeInfo numa_info[MAX_NODES];
void set_numa_nodes(void);
diff --git a/numa.c b/numa.c
index f903b9e..686dbfa 100644
--- a/numa.c
+++ b/numa.c
@@ -27,6 +27,8 @@
#include "qapi-visit.h"
#include "qapi/opts-visitor.h"
#include "qapi/dealloc-visitor.h"
+#include "qapi/qmp/qerror.h"
+
QemuOptsList qemu_numa_opts = {
.name = "numa",
.implied_opt_name = "type",
@@ -34,10 +36,13 @@ QemuOptsList qemu_numa_opts = {
.desc = { { 0 } } /* validated with OptsVisitor */
};
+static int have_memdevs = -1;
+
static int numa_node_parse(NumaNodeOptions *opts)
{
uint16_t nodenr;
uint16List *cpus = NULL;
+ Error *local_err = NULL;
if (opts->has_nodeid) {
nodenr = opts->nodeid;
@@ -60,6 +65,19 @@ static int numa_node_parse(NumaNodeOptions *opts)
bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
}
+ if (opts->has_mem && opts->has_memdev) {
+ fprintf(stderr, "qemu: cannot specify both mem= and memdev=\n");
+ return -1;
+ }
+
+ if (have_memdevs == -1) {
+ have_memdevs = opts->has_memdev;
+ }
+ if (opts->has_memdev != have_memdevs) {
+ fprintf(stderr, "qemu: memdev option must be specified for either "
+ "all or no nodes\n");
+ }
+
if (opts->has_mem) {
int64_t mem_size;
char *endptr;
@@ -70,7 +88,19 @@ static int numa_node_parse(NumaNodeOptions *opts)
}
numa_info[nodenr].node_mem = mem_size;
}
+ if (opts->has_memdev) {
+ Object *o;
+ o = object_resolve_path_type(opts->memdev, TYPE_MEMORY_BACKEND, NULL);
+ if (!o) {
+ error_setg(&local_err, "memdev=%s is ambiguous", opts->memdev);
+ qerror_report_err(local_err);
+ return -1;
+ }
+ object_ref(o);
+ numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL);
+ numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
+ }
return 0;
}
@@ -188,12 +218,42 @@ void set_numa_modes(void)
}
}
+static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
+ const char *name,
+ QEMUMachineInitArgs *args)
+{
+ uint64_t ram_size = args->ram_size;
+
+ memory_region_init_ram(mr, owner, name, ram_size);
+ vmstate_register_ram_global(mr);
+}
+
void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
const char *name,
QEMUMachineInitArgs *args)
{
uint64_t ram_size = args->ram_size;
+ uint64_t addr = 0;
+ int i;
- memory_region_init_ram(mr, owner, name, ram_size);
- vmstate_register_ram_global(mr);
+ if (nb_numa_nodes == 0 || !have_memdevs) {
+ allocate_system_memory_nonnuma(mr, owner, name, args);
+ return;
+ }
+
+ memory_region_init(mr, owner, name, ram_size);
+ for (i = 0; i < nb_numa_nodes; i++) {
+ Error *local_err = NULL;
+ uint64_t size = numa_info[i].node_mem;
+ HostMemoryBackend *backend = numa_info[i].node_memdev;
+ MemoryRegion *seg = host_memory_backend_get_memory(backend, &local_err);
+ if (local_err) {
+ qerror_report_err(local_err);
+ exit(1);
+ }
+
+ memory_region_add_subregion(mr, addr, seg);
+ vmstate_register_ram_global(seg);
+ addr += size;
+ }
}
diff --git a/qapi-schema.json b/qapi-schema.json
index d99e39d..e449316 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4256,7 +4256,10 @@
#
# @cpus: #optional VCPUs belong to this node
#
-# @mem: #optional memory size of this node
+# @memdev: #optional memory backend object. If specified for one node,
+# it must be specified for all nodes.
+#
+# @mem: #optional memory size of this node; mutually exclusive with @memdev.
#
# Since: 2.0
##
@@ -4264,4 +4267,5 @@
'data': {
'*nodeid': 'uint16',
'*cpus': ['uint16'],
+ '*memdev': 'str',
'*mem': 'str' }}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child Paolo Bonzini
@ 2013-12-11 12:44 ` Igor Mammedov
2013-12-12 8:18 ` Stefan Hajnoczi
1 sibling, 0 replies; 23+ messages in thread
From: Igor Mammedov @ 2013-12-11 12:44 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: stefanha, qemu-devel, gaowanlong
On Wed, 11 Dec 2013 13:19:17 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> qom/object.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index fc19cf6..68fe07a 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -988,17 +988,22 @@ static void object_finalize_child_property(Object *obj, const char *name,
> void object_property_add_child(Object *obj, const char *name,
> Object *child, Error **errp)
> {
> + Error *local_err = NULL;
> gchar *type;
>
> type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
>
> object_property_add(obj, name, type, object_get_child_property,
> - NULL, object_finalize_child_property, child, errp);
> -
> + NULL, object_finalize_child_property, child, &local_err);
> + if (error_is_set(&local_err)) {
> + error_propagate(errp, local_err);
> + goto out;
> + }
> object_ref(child);
> g_assert(child->parent == NULL);
> child->parent = obj;
>
> +out:
> g_free(type);
> }
>
> --
> 1.8.4.2
>
>
>
Reviewed-By: Igor Mammedov <imammedo@redhat.com>
--
Regards,
Igor
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 14/14] numa: add -numa node, memdev= option
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 14/14] numa: add -numa node, memdev= option Paolo Bonzini
@ 2013-12-11 15:36 ` Igor Mammedov
2013-12-11 15:50 ` Paolo Bonzini
0 siblings, 1 reply; 23+ messages in thread
From: Igor Mammedov @ 2013-12-11 15:36 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: gaowanlong, qemu-devel, stefanha
On Wed, 11 Dec 2013 13:19:21 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:
> This option provides the infrastructure for binding guest NUMA nodes
> to host NUMA nodes. For example:
>
> -object memory-ram,size=1024M,policy=membind,host-nodes=0,id=ram-node0 \
> -numa node,nodeid=0,cpus=0,memdev=ram-node0 \
> -object memory-ram,size=1024M,policy=interleave,host-nodes=1-3,id=ram-node1 \
> -numa node,nodeid=1,cpus=1,memdev=ram-node1
I was thinking about a bit more radical change:
-object memory-ram,size=1024M,policy=membind,host-nodes=0,id=ram-node0
-device dimm,memdev=ram-node0,node=0
-object memory-ram,size=1024M,policy=membind,host-nodes=1,id=ram-node1
-device dimm,memdev=ram-node1,node=1
that would allow to avoid synthetic -numa option but would require conversion
of initial RAM to dimms. That would be more flexible for example allowing
bind several backends to one node (like: 1Gb_hugepage + 2Mb_hugepage ones)
>
> The option replaces "-numa mem".
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> include/sysemu/sysemu.h | 2 ++
> numa.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--
> qapi-schema.json | 6 ++++-
> 3 files changed, 69 insertions(+), 3 deletions(-)
>
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index e9da760..acfc0c7 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -12,6 +12,7 @@
> #include "qemu/bitmap.h"
> #include "qom/object.h"
> #include "hw/boards.h"
> +#include "sysemu/hostmem.h"
>
> /* vl.c */
>
> @@ -140,6 +141,7 @@ extern int nb_numa_nodes;
> typedef struct node_info {
> uint64_t node_mem;
> DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
> + HostMemoryBackend *node_memdev;
> } NodeInfo;
> extern NodeInfo numa_info[MAX_NODES];
> void set_numa_nodes(void);
> diff --git a/numa.c b/numa.c
> index f903b9e..686dbfa 100644
> --- a/numa.c
> +++ b/numa.c
> @@ -27,6 +27,8 @@
> #include "qapi-visit.h"
> #include "qapi/opts-visitor.h"
> #include "qapi/dealloc-visitor.h"
> +#include "qapi/qmp/qerror.h"
> +
> QemuOptsList qemu_numa_opts = {
> .name = "numa",
> .implied_opt_name = "type",
> @@ -34,10 +36,13 @@ QemuOptsList qemu_numa_opts = {
> .desc = { { 0 } } /* validated with OptsVisitor */
> };
>
> +static int have_memdevs = -1;
> +
> static int numa_node_parse(NumaNodeOptions *opts)
> {
> uint16_t nodenr;
> uint16List *cpus = NULL;
> + Error *local_err = NULL;
>
> if (opts->has_nodeid) {
> nodenr = opts->nodeid;
> @@ -60,6 +65,19 @@ static int numa_node_parse(NumaNodeOptions *opts)
> bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
> }
>
> + if (opts->has_mem && opts->has_memdev) {
> + fprintf(stderr, "qemu: cannot specify both mem= and memdev=\n");
> + return -1;
> + }
> +
> + if (have_memdevs == -1) {
> + have_memdevs = opts->has_memdev;
> + }
> + if (opts->has_memdev != have_memdevs) {
> + fprintf(stderr, "qemu: memdev option must be specified for either "
> + "all or no nodes\n");
> + }
> +
> if (opts->has_mem) {
> int64_t mem_size;
> char *endptr;
> @@ -70,7 +88,19 @@ static int numa_node_parse(NumaNodeOptions *opts)
> }
> numa_info[nodenr].node_mem = mem_size;
> }
> + if (opts->has_memdev) {
> + Object *o;
> + o = object_resolve_path_type(opts->memdev, TYPE_MEMORY_BACKEND, NULL);
> + if (!o) {
> + error_setg(&local_err, "memdev=%s is ambiguous", opts->memdev);
> + qerror_report_err(local_err);
> + return -1;
> + }
>
> + object_ref(o);
> + numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL);
> + numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
> + }
there wouldn't be any need for keeping numa mappings in separate structure,
if we use node property of dimm device.
acpi_build then could build SRAT directly enumerating present dimm devices.
> return 0;
> }
>
> @@ -188,12 +218,42 @@ void set_numa_modes(void)
> }
> }
>
> +static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
> + const char *name,
> + QEMUMachineInitArgs *args)
> +{
> + uint64_t ram_size = args->ram_size;
> +
> + memory_region_init_ram(mr, owner, name, ram_size);
> + vmstate_register_ram_global(mr);
> +}
> +
> void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
> const char *name,
> QEMUMachineInitArgs *args)
> {
> uint64_t ram_size = args->ram_size;
> + uint64_t addr = 0;
> + int i;
>
> - memory_region_init_ram(mr, owner, name, ram_size);
> - vmstate_register_ram_global(mr);
> + if (nb_numa_nodes == 0 || !have_memdevs) {
> + allocate_system_memory_nonnuma(mr, owner, name, args);
> + return;
> + }
> +
> + memory_region_init(mr, owner, name, ram_size);
container might clip subregions due to presence of hole,
it's size should be ram_size + hole_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 d99e39d..e449316 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -4256,7 +4256,10 @@
> #
> # @cpus: #optional VCPUs belong to this node
> #
> -# @mem: #optional memory size of this node
> +# @memdev: #optional memory backend object. If specified for one node,
> +# it must be specified for all nodes.
> +#
> +# @mem: #optional memory size of this node; mutually exclusive with @memdev.
> #
> # Since: 2.0
> ##
> @@ -4264,4 +4267,5 @@
> 'data': {
> '*nodeid': 'uint16',
> '*cpus': ['uint16'],
> + '*memdev': 'str',
> '*mem': 'str' }}
> --
> 1.8.4.2
>
--
Regards,
Igor
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 14/14] numa: add -numa node, memdev= option
2013-12-11 15:36 ` Igor Mammedov
@ 2013-12-11 15:50 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 15:50 UTC (permalink / raw)
To: Igor Mammedov; +Cc: stefanha, qemu-devel, gaowanlong
Il 11/12/2013 16:36, Igor Mammedov ha scritto:
>> > -object memory-ram,size=1024M,policy=membind,host-nodes=0,id=ram-node0 \
>> > -numa node,nodeid=0,cpus=0,memdev=ram-node0 \
>> > -object memory-ram,size=1024M,policy=interleave,host-nodes=1-3,id=ram-node1 \
>> > -numa node,nodeid=1,cpus=1,memdev=ram-node1
>
> I was thinking about a bit more radical change:
> -object memory-ram,size=1024M,policy=membind,host-nodes=0,id=ram-node0
> -device dimm,memdev=ram-node0,node=0
> -object memory-ram,size=1024M,policy=membind,host-nodes=1,id=ram-node1
> -device dimm,memdev=ram-node1,node=1
>
> that would allow to avoid synthetic -numa option
You still need -numa for cpus, at least in the short/medium-term.
> but would require conversion
> of initial RAM to dimms. That would be more flexible for example allowing
> bind several backends to one node (like: 1Gb_hugepage + 2Mb_hugepage ones)
Yes, that's another possibility, perhaps even cleaner.
With "-numa node,memdev=", your board only needs to use
memory_region_allocate_system_memory in order to apply a NUMA policy to
guest RAM; it also works with guests or boards that are not themselves
NUMA-aware.
Doing the same with "-device dimm" requires changing the board to
support RAM-as-dimms; do you have any idea how easy/hard that would be?
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 02/14] NUMA: check if the total numa memory size is equal to ram_size
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 02/14] NUMA: check if the total numa memory size is equal to ram_size Paolo Bonzini
@ 2013-12-11 18:48 ` Eric Blake
0 siblings, 0 replies; 23+ messages in thread
From: Eric Blake @ 2013-12-11 18:48 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel; +Cc: imammedo, stefanha, gaowanlong
[-- Attachment #1: Type: text/plain, Size: 940 bytes --]
On 12/11/2013 05:19 AM, Paolo Bonzini wrote:
> 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 talb, then the guest will ignore the wrong ACPI table
s/talb/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>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> numa.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
> + }
> + if (numa_total != ram_size) {
> + fprintf(stderr, "qemu: numa nodes total memory size "
> + "should equal to ram_size\n");
s/to //
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor Paolo Bonzini
@ 2013-12-11 18:51 ` Eric Blake
2013-12-11 21:35 ` Paolo Bonzini
0 siblings, 1 reply; 23+ messages in thread
From: Eric Blake @ 2013-12-11 18:51 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel; +Cc: imammedo, stefanha, gaowanlong
[-- Attachment #1: Type: text/plain, Size: 1340 bytes --]
On 12/11/2013 05:19 AM, Paolo Bonzini wrote:
> From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
>
> Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> +++ b/qapi-schema.json
> @@ -4235,3 +4235,33 @@
> # Since: 1.7
> ##
> { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
> +
> +##
> +# @NumaOptions
> +#
> +# A discriminated record of NUMA options. (for OptsVisitor)
> +#
> +# Since 2.0
> +##
> +{ 'union': 'NumaOptions',
> + 'data': {
> + 'node': 'NumaNodeOptions' }}
Why do we need a union, if there's no alternative, and since nothing
else in the series adds an alternative?
> +
> +##
> +# @NumaNodeOptions
> +#
> +# Create a guest NUMA node. (for OptsVisitor)
> +#
> +# @nodeid: #optional NUMA node ID
> +#
> +# @cpus: #optional VCPUs belong to this node
What are the defaults if these fields are omitted?
> +#
> +# @mem: #optional memory size of this node
In bytes? Why is this field a string instead of an integer?
> +#
> +# Since: 2.0
> +##
> +{ 'type': 'NumaNodeOptions',
> + 'data': {
> + '*nodeid': 'uint16',
> + '*cpus': ['uint16'],
> + '*mem': 'str' }}
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor
2013-12-11 18:51 ` Eric Blake
@ 2013-12-11 21:35 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2013-12-11 21:35 UTC (permalink / raw)
To: Eric Blake; +Cc: imammedo, gaowanlong, qemu-devel, stefanha
Il 11/12/2013 19:51, Eric Blake ha scritto:
>> > +{ 'union': 'NumaOptions',
>> > + 'data': {
>> > + 'node': 'NumaNodeOptions' }}
> Why do we need a union, if there's no alternative, and since nothing
> else in the series adds an alternative?
Because these structures are used to parse command-line options and
follow somewhat special rules. The "node" in "-numa node,..." is
present for forwards-extensibility. Another alternative, "mem", was
added in previous versions of the NUMA policy patches but is made
obsolete by Igor's memory object.
>> > +
>> > +##
>> > +# @NumaNodeOptions
>> > +#
>> > +# Create a guest NUMA node. (for OptsVisitor)
>> > +#
>> > +# @nodeid: #optional NUMA node ID
>> > +#
>> > +# @cpus: #optional VCPUs belong to this node
> What are the defaults if these fields are omitted?
Wanlong, can you fill this out when you resubmit?
>> > +#
>> > +# @mem: #optional memory size of this node
> In bytes? Why is this field a string instead of an integer?
It was like this because it is a command-line option and thus is never
used via QMP. However, it can and should indeed be a 'size', handled
like Igor did for '-m mem=' in patch 8 of the series.
Paolo
>> > +#
>> > +# Since: 2.0
>> > +##
>> > +{ 'type': 'NumaNodeOptions',
>> > + 'data': {
>> > + '*nodeid': 'uint16',
>> > + '*cpus': ['uint16'],
>> > + '*mem': 'str' }}
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 09/14] qom: fix leak for objects created with -object
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 09/14] qom: fix leak for objects created with -object Paolo Bonzini
@ 2013-12-12 8:18 ` Stefan Hajnoczi
0 siblings, 0 replies; 23+ messages in thread
From: Stefan Hajnoczi @ 2013-12-12 8:18 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: imammedo, qemu-devel, gaowanlong
On Wed, Dec 11, 2013 at 01:19:16PM +0100, Paolo Bonzini wrote:
> The object must be unref-ed when its variable goes out of scope.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> vl.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child Paolo Bonzini
2013-12-11 12:44 ` Igor Mammedov
@ 2013-12-12 8:18 ` Stefan Hajnoczi
1 sibling, 0 replies; 23+ messages in thread
From: Stefan Hajnoczi @ 2013-12-12 8:18 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: imammedo, qemu-devel, gaowanlong
On Wed, Dec 11, 2013 at 01:19:17PM +0100, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> qom/object.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2013-12-12 8:18 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-11 12:19 [Qemu-devel] [RFC PATCH 00/14] Common base for memory hotplug and NUMA policy work Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 01/14] NUMA: move numa related code to new file numa.c Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 02/14] NUMA: check if the total numa memory size is equal to ram_size Paolo Bonzini
2013-12-11 18:48 ` Eric Blake
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 03/14] NUMA: Add numa_info structure to contain numa nodes info Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor Paolo Bonzini
2013-12-11 18:51 ` Eric Blake
2013-12-11 21:35 ` Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 05/14] NUMA: expand MAX_NODES from 64 to 128 Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 06/14] qapi: add SIZE type parser to string_input_visitor Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 07/14] QemuOpts: introduce qemu_find_opts_singleton Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 08/14] vl: convert -m to QemuOpts Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 09/14] qom: fix leak for objects created with -object Paolo Bonzini
2013-12-12 8:18 ` Stefan Hajnoczi
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 10/14] qom: catch errors in object_property_add_child Paolo Bonzini
2013-12-11 12:44 ` Igor Mammedov
2013-12-12 8:18 ` Stefan Hajnoczi
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 11/14] pc: pass QEMUMachineInitArgs to pc_memory_init Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 12/14] numa: introduce memory_region_allocate_system_memory Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 13/14] add memdev backend infrastructure Paolo Bonzini
2013-12-11 12:19 ` [Qemu-devel] [RFC PATCH 14/14] numa: add -numa node, memdev= option Paolo Bonzini
2013-12-11 15:36 ` Igor Mammedov
2013-12-11 15:50 ` Paolo Bonzini
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).