Merge tag 'patchew/20200219160953.13771-1-imammedo@redhat.com' of https://github.com/patchew-project/qemu into HEAD

This series removes ad hoc RAM allocation API (memory_region_allocate_system_memory)
and consolidates it around hostmem backend. It allows to

* resolve conflicts between global -mem-prealloc and hostmem's "policy" option,
  fixing premature allocation before binding policy is applied

* simplify complicated memory allocation routines which had to deal with 2 ways
  to allocate RAM.

* reuse hostmem backends of a choice for main RAM without adding extra CLI
  options to duplicate hostmem features.  A recent case was -mem-shared, to
  enable vhost-user on targets that don't support hostmem backends [1] (ex: s390)

* move RAM allocation from individual boards into generic machine code and
  provide them with prepared MemoryRegion.

* clean up deprecated NUMA features which were tied to the old API (see patches)
  - "numa: remove deprecated -mem-path fallback to anonymous RAM"
  - (POSTPONED, waiting on libvirt side) "forbid '-numa node,mem' for 5.0 and newer machine types"
  - (POSTPONED) "numa: remove deprecated implicit RAM distribution between nodes"

Introduce a new machine.memory-backend property and wrapper code that aliases
global -mem-path and -mem-alloc into automatically created hostmem backend
properties (provided memory-backend was not set explicitly given by user).
A bulk of trivial patches then follow to incrementally convert individual
boards to using machine.memory-backend provided MemoryRegion.

Board conversion typically involves:

* providing MachineClass::default_ram_size and MachineClass::default_ram_id
  so generic code could create default backend if user didn't explicitly provide
  memory-backend or -m options

* dropping memory_region_allocate_system_memory() call

* using convenience MachineState::ram MemoryRegion, which points to MemoryRegion
   allocated by ram-memdev

On top of that for some boards:

* missing ram_size checks are added (typically it were boards with fixed ram size)

* ram_size fixups are replaced by checks and hard errors, forcing user to
  provide correct "-m" values instead of ignoring it and continuing running.

After all boards are converted, the old API is removed and memory allocation
routines are cleaned up.
This commit is contained in:
Paolo Bonzini 2020-02-25 09:19:00 +01:00
commit ca6155c0f2
78 changed files with 828 additions and 774 deletions

View file

@ -14,67 +14,60 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
static char *make_cli(const char *generic_cli, const char *test_cli)
static char *make_cli(const GString *generic_cli, const char *test_cli)
{
return g_strdup_printf("%s %s", generic_cli ? generic_cli : "", test_cli);
return g_strdup_printf("%s %s", generic_cli->str, test_cli);
}
static void test_mon_explicit(const void *data)
{
char *s;
char *cli;
QTestState *qts;
g_autofree char *s = NULL;
g_autofree char *cli = NULL;
cli = make_cli(data, "-smp 8 "
"-numa node,nodeid=0,cpus=0-3 "
"-numa node,nodeid=1,cpus=4-7 ");
cli = make_cli(data, "-smp 8 -numa node,nodeid=0,memdev=ram,cpus=0-3 "
"-numa node,nodeid=1,cpus=4-7");
qts = qtest_init(cli);
s = qtest_hmp(qts, "info numa");
g_assert(strstr(s, "node 0 cpus: 0 1 2 3"));
g_assert(strstr(s, "node 1 cpus: 4 5 6 7"));
g_free(s);
qtest_quit(qts);
g_free(cli);
}
static void test_mon_default(const void *data)
static void test_def_cpu_split(const void *data)
{
char *s;
char *cli;
QTestState *qts;
g_autofree char *s = NULL;
g_autofree char *cli = NULL;
cli = make_cli(data, "-smp 8 -numa node -numa node");
cli = make_cli(data, "-smp 8 -numa node,memdev=ram -numa node");
qts = qtest_init(cli);
s = qtest_hmp(qts, "info numa");
g_assert(strstr(s, "node 0 cpus: 0 2 4 6"));
g_assert(strstr(s, "node 1 cpus: 1 3 5 7"));
g_free(s);
qtest_quit(qts);
g_free(cli);
}
static void test_mon_partial(const void *data)
{
char *s;
char *cli;
QTestState *qts;
g_autofree char *s = NULL;
g_autofree char *cli = NULL;
cli = make_cli(data, "-smp 8 "
"-numa node,nodeid=0,cpus=0-1 "
"-numa node,nodeid=0,memdev=ram,cpus=0-1 "
"-numa node,nodeid=1,cpus=4-5 ");
qts = qtest_init(cli);
s = qtest_hmp(qts, "info numa");
g_assert(strstr(s, "node 0 cpus: 0 1 2 3 6 7"));
g_assert(strstr(s, "node 1 cpus: 4 5"));
g_free(s);
qtest_quit(qts);
g_free(cli);
}
static QList *get_cpus(QTestState *qts, QDict **resp)
@ -87,13 +80,14 @@ static QList *get_cpus(QTestState *qts, QDict **resp)
static void test_query_cpus(const void *data)
{
char *cli;
QDict *resp;
QList *cpus;
QObject *e;
QTestState *qts;
g_autofree char *cli = NULL;
cli = make_cli(data, "-smp 8 -numa node,cpus=0-3 -numa node,cpus=4-7");
cli = make_cli(data, "-smp 8 -numa node,memdev=ram,cpus=0-3 "
"-numa node,cpus=4-7");
qts = qtest_init(cli);
cpus = get_cpus(qts, &resp);
g_assert(cpus);
@ -120,19 +114,18 @@ static void test_query_cpus(const void *data)
qobject_unref(resp);
qtest_quit(qts);
g_free(cli);
}
static void pc_numa_cpu(const void *data)
{
char *cli;
QDict *resp;
QList *cpus;
QObject *e;
QTestState *qts;
g_autofree char *cli = NULL;
cli = make_cli(data, "-cpu pentium -smp 8,sockets=2,cores=2,threads=2 "
"-numa node,nodeid=0 -numa node,nodeid=1 "
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
"-numa cpu,node-id=1,socket-id=0 "
"-numa cpu,node-id=0,socket-id=1,core-id=0 "
"-numa cpu,node-id=0,socket-id=1,core-id=1,thread-id=0 "
@ -174,19 +167,18 @@ static void pc_numa_cpu(const void *data)
qobject_unref(resp);
qtest_quit(qts);
g_free(cli);
}
static void spapr_numa_cpu(const void *data)
{
char *cli;
QDict *resp;
QList *cpus;
QObject *e;
QTestState *qts;
g_autofree char *cli = NULL;
cli = make_cli(data, "-smp 4,cores=4 "
"-numa node,nodeid=0 -numa node,nodeid=1 "
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
"-numa cpu,node-id=0,core-id=0 "
"-numa cpu,node-id=0,core-id=1 "
"-numa cpu,node-id=0,core-id=2 "
@ -220,19 +212,18 @@ static void spapr_numa_cpu(const void *data)
qobject_unref(resp);
qtest_quit(qts);
g_free(cli);
}
static void aarch64_numa_cpu(const void *data)
{
char *cli;
QDict *resp;
QList *cpus;
QObject *e;
QTestState *qts;
g_autofree char *cli = NULL;
cli = make_cli(data, "-smp 2 "
"-numa node,nodeid=0 -numa node,nodeid=1 "
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
"-numa cpu,node-id=1,thread-id=0 "
"-numa cpu,node-id=0,thread-id=1");
qts = qtest_init(cli);
@ -264,7 +255,6 @@ static void aarch64_numa_cpu(const void *data)
qobject_unref(resp);
qtest_quit(qts);
g_free(cli);
}
static void pc_dynamic_cpu_cfg(const void *data)
@ -273,13 +263,14 @@ static void pc_dynamic_cpu_cfg(const void *data)
QDict *resp;
QList *cpus;
QTestState *qs;
g_autofree char *cli = NULL;
qs = qtest_initf("%s -nodefaults --preconfig -smp 2",
data ? (char *)data : "");
cli = make_cli(data, "-nodefaults --preconfig -smp 2");
qs = qtest_init(cli);
/* create 2 numa nodes */
g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
" 'arguments': { 'type': 'node', 'nodeid': 0 } }")));
" 'arguments': { 'type': 'node', 'nodeid': 0, 'memdev': 'ram' } }")));
g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
" 'arguments': { 'type': 'node', 'nodeid': 1 } }")));
@ -329,16 +320,19 @@ static void pc_dynamic_cpu_cfg(const void *data)
static void pc_hmat_build_cfg(const void *data)
{
QTestState *qs = qtest_initf("%s -nodefaults --preconfig -machine hmat=on "
"-smp 2,sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
"-numa node,nodeid=0,memdev=m0 "
"-numa node,nodeid=1,memdev=m1,initiator=0 "
"-numa cpu,node-id=0,socket-id=0 "
"-numa cpu,node-id=0,socket-id=1",
data ? (char *)data : "");
QTestState *qs;
g_autofree char *cli = NULL;
cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on "
"-smp 2,sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
"-numa node,nodeid=0,memdev=m0 "
"-numa node,nodeid=1,memdev=m1,initiator=0 "
"-numa cpu,node-id=0,socket-id=0 "
"-numa cpu,node-id=0,socket-id=1");
qs = qtest_init(cli);
/* Fail: Initiator should be less than the number of nodes */
g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
@ -455,13 +449,16 @@ static void pc_hmat_build_cfg(const void *data)
static void pc_hmat_off_cfg(const void *data)
{
QTestState *qs = qtest_initf("%s -nodefaults --preconfig "
"-smp 2,sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
"-numa node,nodeid=0,memdev=m0",
data ? (char *)data : "");
QTestState *qs;
g_autofree char *cli = NULL;
cli = make_cli(data, "-nodefaults --preconfig "
"-smp 2,sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
"-numa node,nodeid=0,memdev=m0");
qs = qtest_init(cli);
/*
* Fail: Enable HMAT with -machine hmat=on
@ -491,16 +488,19 @@ static void pc_hmat_off_cfg(const void *data)
static void pc_hmat_erange_cfg(const void *data)
{
QTestState *qs = qtest_initf("%s -nodefaults --preconfig -machine hmat=on "
"-smp 2,sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
"-numa node,nodeid=0,memdev=m0 "
"-numa node,nodeid=1,memdev=m1,initiator=0 "
"-numa cpu,node-id=0,socket-id=0 "
"-numa cpu,node-id=0,socket-id=1",
data ? (char *)data : "");
QTestState *qs;
g_autofree char *cli = NULL;
cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on "
"-smp 2,sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
"-numa node,nodeid=0,memdev=m0 "
"-numa node,nodeid=1,memdev=m1,initiator=0 "
"-numa cpu,node-id=0,socket-id=0 "
"-numa cpu,node-id=0,socket-id=1");
qs = qtest_init(cli);
/* Can't store the compressed latency */
g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
@ -539,16 +539,22 @@ static void pc_hmat_erange_cfg(const void *data)
int main(int argc, char **argv)
{
const char *args = NULL;
g_autoptr(GString) args = g_string_new(NULL);
const char *arch = qtest_get_arch();
if (strcmp(arch, "aarch64") == 0) {
args = "-machine virt";
if (g_str_equal(arch, "ppc64")) {
g_string_append(args, " -object memory-backend-ram,id=ram,size=512M");
} else {
g_string_append(args, " -object memory-backend-ram,id=ram,size=128M");
}
if (g_str_equal(arch, "aarch64")) {
g_string_append(args, " -machine virt");
}
g_test_init(&argc, &argv, NULL);
qtest_add_data_func("/numa/mon/default", args, test_mon_default);
qtest_add_data_func("/numa/mon/cpus/default", args, test_def_cpu_split);
qtest_add_data_func("/numa/mon/cpus/explicit", args, test_mon_explicit);
qtest_add_data_func("/numa/mon/cpus/partial", args, test_mon_partial);
qtest_add_data_func("/numa/qmp/cpus/query-cpus", args, test_query_cpus);