[Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor

2013-12-11 Thread Paolo Bonzini
From: Wanlong Gao gaowanl...@cn.fujitsu.com

Signed-off-by: Wanlong Gao gaowanl...@cn.fujitsu.com
Signed-off-by: Paolo Bonzini pbonz...@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) {
-

Re: [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor

2013-12-11 Thread Eric Blake
On 12/11/2013 05:19 AM, Paolo Bonzini wrote:
 From: Wanlong Gao gaowanl...@cn.fujitsu.com
 
 Signed-off-by: Wanlong Gao gaowanl...@cn.fujitsu.com
 Signed-off-by: Paolo Bonzini pbonz...@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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [RFC PATCH 04/14] NUMA: convert -numa option to use OptsVisitor

2013-12-11 Thread Paolo Bonzini
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' }}