OptsVisitor: introduce basic list modes

We're going to need more state while processing a list of repeated
options. This change eliminates "repeated_opts_first" and adds a new state
variable:

  list_mode       repeated_opts  repeated_opts_first
  --------------  -------------  -------------------
  LM_NONE         NULL           false
  LM_STARTED      non-NULL       true
  LM_IN_PROGRESS  non-NULL       false

Additionally, it is documented that lookup_scalar() and processed(), both
called by opts_type_XXX(), are invalid in LM_STARTED -- generated qapi
code calls opts_next_list() to allocate the very first link before trying
to parse a scalar into it. List mode restrictions are expressed in
positive / inclusive form.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
OptsVisitor: introduce list modes for interval flattening

The new modes are equal-rank, exclusive sub-modes of LM_IN_PROGRESS. Teach
opts_next_list(), opts_type_int() and opts_type_uint64() to handle them.

Also enumerate explicitly what functions are valid to call in what modes:
- opts_next_list() is valid to call while flattening a range,
- opts_end_list(): ditto,
- lookup_scalar() is invalid to call during flattening; generated qapi
  traversal code must continue asking for the same kind of signed/unsigned
  list element until the interval is fully flattened,
- processed(): ditto.

List mode restrictions are always formulated in positive / inclusive
sense. The restrictions for lookup_scalar() and processed() are
automatically satisfied by current qapi traversals if the schema to build
is compatible with OptsVisitor.

The new list modes are not entered yet.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
OptsVisitor: opts_type_int(): recognize intervals when LM_IN_PROGRESS

When a well-formed range value, bounded by signed integers, is encountered
while processing a repeated option, enter LM_SIGNED_INTERVAL and return
the low bound.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
OptsVisitor: rebase opts_type_uint64() to parse_uint_full()

Simplify the code in preparation for the next patch.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
OptsVisitor: opts_type_uint64(): recognize intervals when LM_IN_PROGRESS

When a well-formed range value, bounded by unsigned integers, is
encountered while processing a repeated option, enter LM_UNSIGNED_INTERVAL
and return the low bound.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
OptsVisitor: don't try to flatten overlong integer ranges

Prevent mistyped command line options from incurring high memory and CPU
usage at startup. 64K elements in a range should be enough for everyone
(TM).

The OPTS_VISITOR_RANGE_MAX macro is public so that unit tests can
construct corner cases with it.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
NUMA: add NumaOptions, NumaNodeOptions and NumaMemOptions

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: split -numa option

Change -numa option like following as Paolo suggested:
    -numa node,nodeid=0,cpus=0-1 \
    -numa mem,nodeid=0,size=1G

This new option will make later coming memory hotplug better.
And this new option is implemented using OptsVisitor.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: move numa related code to numa.c

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: Add numa_info structure to contain numa nodes info

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>
NUMA: Add Linux libnuma detection

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>
NUMA: parse guest numa nodes memory policy

The memory policy setting format is like:
    policy={membind|interleave|preferred},host-node=[+|!]{all|N-N}
And we are adding this setting as a suboption of "-numa mem,",
the memory policy then can be set like following:
    -numa node,nodeid=0,cpus=0 \
    -numa node,nodeid=1,cpus=1 \
    -numa mem,nodeid=0,size=1G,policy=membind,host-nodes=0-1 \
    -numa mem,nodeid=1,size=1G,policy=interleave,host-nodes=!1

Reviewed-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: split out the common range parser

Since cpus parser and hostnode parser have the common range parser
part, split it out to the common range parser to avoid the duplicate
code.

Reviewed-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: set guest numa nodes memory policy

Set the guest numa nodes memory policies using the mbind(2)
system call node by node.
After this patch, we are able to set guest nodes memory policies
through the QEMU options, this arms to solve the guest cross
nodes memory access performance issue.
And as you all know, if PCI-passthrough is used,
direct-attached-device uses DMA transfer between device and qemu process.
All pages of the guest will be pinned by get_user_pages().

KVM_ASSIGN_PCI_DEVICE ioctl
  kvm_vm_ioctl_assign_device()
    =>kvm_assign_device()
      => kvm_iommu_map_memslots()
        => kvm_iommu_map_pages()
           => kvm_pin_pages()

So, with direct-attached-device, all guest page's page count will be +1 and
any page migration will not work. AutoNUMA won't too.

So, we should set the guest nodes memory allocation policies before
the pages are really mapped.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: add qmp command set-mem-policy to set memory policy for NUMA node

This QMP command allows user set guest node's memory policy
through the QMP protocol. The qmp-shell command is like:
    set-mem-policy nodeid=0 policy=membind host-nodes=0-1

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: add hmp command set-mem-policy

Add hmp command set-mem-policy to set host memory policy for a guest
NUMA node. Then we can also set node's memory policy using
the monitor command like:
    (qemu) set-mem-policy 0 policy=membind,host-nodes=0-1

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: add qmp command query-numa

Add qmp command query-numa to show guest NUMA information.

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
NUMA: convert hmp command info_numa to use qmp command query_numa

Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>