From 694804ed7b26e66e114a2330887187d697a0d92b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 18 Dec 2021 13:49:24 +0100 Subject: hw/qdev: Cosmetic around documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add empty lines to have a clearer distinction between different functions declarations. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Yanan Wang Message-Id: <20211218130437.1516929-2-f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé --- include/hw/qdev-core.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 20d3066595..59a822ffce 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -321,6 +321,7 @@ compat_props_add(GPtrArray *arr, * The returned object has a reference count of 1. */ DeviceState *qdev_new(const char *name); + /** * qdev_try_new: Try to create a device on the heap * @name: device type to create @@ -329,6 +330,7 @@ DeviceState *qdev_new(const char *name); * does not exist, rather than asserting. */ DeviceState *qdev_try_new(const char *name); + /** * qdev_realize: Realize @dev. * @dev: device to realize @@ -347,6 +349,7 @@ DeviceState *qdev_try_new(const char *name); * qdev_realize_and_unref() instead. */ bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp); + /** * qdev_realize_and_unref: Realize @dev and drop a reference * @dev: device to realize @@ -372,6 +375,7 @@ bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp); * would be incorrect. For that use case you want qdev_realize(). */ bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp); + /** * qdev_unrealize: Unrealize a device * @dev: device to unrealize @@ -450,6 +454,7 @@ typedef enum { * For named input GPIO lines, use qdev_get_gpio_in_named(). */ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); + /** * qdev_get_gpio_in_named: Get one of a device's named input GPIO lines * @dev: Device whose GPIO we want @@ -497,6 +502,7 @@ qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n); * For named output GPIO lines, use qdev_connect_gpio_out_named(). */ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); + /** * qdev_connect_gpio_out: Connect one of a device's anonymous output GPIO lines * @dev: Device whose GPIO to connect @@ -524,6 +530,7 @@ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); */ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq pin); + /** * qdev_get_gpio_out_connector: Get the qemu_irq connected to an output GPIO * @dev: Device whose output GPIO we are interested in @@ -541,6 +548,7 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, * by the platform-bus subsystem. */ qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n); + /** * qdev_intercept_gpio_out: Intercept an existing GPIO connection * @dev: Device to intercept the outbound GPIO line from @@ -582,6 +590,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name); * hold of an input GPIO line to manipulate it. */ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); + /** * qdev_init_gpio_out: create an array of anonymous output GPIO lines * @dev: Device to create output GPIOs for @@ -610,6 +619,7 @@ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); * handler. */ void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); + /** * qdev_init_gpio_out: create an array of named output GPIO lines * @dev: Device to create output GPIOs for @@ -623,6 +633,7 @@ void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); */ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, const char *name, int n); + /** * qdev_init_gpio_in_named_with_opaque: create an array of input GPIO lines * for the specified device -- cgit v1.2.3 From 14b0375b39f4acbd2b313a37f5fdf886b0fe74cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 18 Dec 2021 13:52:51 +0100 Subject: hw/qdev: Correct qdev_init_gpio_out_named() documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qdev_init_gpio_out_named() is described as qdev_init_gpio_out(), and referring to itself in an endless loop, which is confusing. Fix. Reported-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Yanan Wang Message-Id: <20211218130437.1516929-3-f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé --- include/hw/qdev-core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 59a822ffce..dcf20c69b8 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -621,7 +621,7 @@ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); /** - * qdev_init_gpio_out: create an array of named output GPIO lines + * qdev_init_gpio_out_named: create an array of named output GPIO lines * @dev: Device to create output GPIOs for * @pins: Pointer to qemu_irq or qemu_irq array for the GPIO lines * @name: Name to give this array of GPIO lines -- cgit v1.2.3 From 1fbd004b00198fb3f27e52ce7b138b9c13288f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 5 Nov 2021 17:50:28 +0100 Subject: hw/qdev: Correct qdev_connect_gpio_out_named() documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qdev_connect_gpio_out_named() is described as qdev_connect_gpio_out(), and referring to itself in an endless loop, which is confusing. Fix. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Yanan Wang Message-Id: <20211218130437.1516929-4-f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé --- include/hw/qdev-core.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index dcf20c69b8..424c48daf6 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -504,7 +504,8 @@ qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n); void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); /** - * qdev_connect_gpio_out: Connect one of a device's anonymous output GPIO lines + * qdev_connect_gpio_out_named: Connect one of a device's named output + * GPIO lines * @dev: Device whose GPIO to connect * @name: Name of the output GPIO array * @n: Number of the anonymous output GPIO line (which must be in range) @@ -526,7 +527,7 @@ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); * qemu_irqs at once, or to connect multiple outbound GPIOs to the * same qemu_irq; see qdev_connect_gpio_out() for details. * - * For named output GPIO lines, use qdev_connect_gpio_out_named(). + * For anonymous output GPIO lines, use qdev_connect_gpio_out(). */ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq pin); -- cgit v1.2.3 From 2ebd9ce19a324aa627c3f9b8f40285a1cf9bb0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 5 Nov 2021 17:53:21 +0100 Subject: hw/qdev: Rename qdev_connect_gpio_out*() 'input_pin' parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @pin is an input where we connect a device output. Rename it @input_pin to simplify the documentation. Reviewed-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211218130437.1516929-5-f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/gpio.c | 13 +++++++------ include/hw/qdev-core.h | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/core/gpio.c b/hw/core/gpio.c index 8e6b4f5edf..80d07a6ec9 100644 --- a/hw/core/gpio.c +++ b/hw/core/gpio.c @@ -115,17 +115,18 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) } void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, - qemu_irq pin) + qemu_irq input_pin) { char *propname = g_strdup_printf("%s[%d]", name ? name : "unnamed-gpio-out", n); - if (pin && !OBJECT(pin)->parent) { + if (input_pin && !OBJECT(input_pin)->parent) { /* We need a name for object_property_set_link to work */ object_property_add_child(container_get(qdev_get_machine(), "/unattached"), - "non-qdev-gpio[*]", OBJECT(pin)); + "non-qdev-gpio[*]", OBJECT(input_pin)); } - object_property_set_link(OBJECT(dev), propname, OBJECT(pin), &error_abort); + object_property_set_link(OBJECT(dev), propname, + OBJECT(input_pin), &error_abort); g_free(propname); } @@ -165,9 +166,9 @@ qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt, return disconnected; } -void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin) +void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq input_pin) { - qdev_connect_gpio_out_named(dev, NULL, n, pin); + qdev_connect_gpio_out_named(dev, NULL, n, input_pin); } void qdev_pass_gpios(DeviceState *dev, DeviceState *container, diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 424c48daf6..d19c941752 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -476,7 +476,7 @@ qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n); * qdev_connect_gpio_out: Connect one of a device's anonymous output GPIO lines * @dev: Device whose GPIO to connect * @n: Number of the anonymous output GPIO line (which must be in range) - * @pin: qemu_irq to connect the output line to + * @input_pin: qemu_irq to connect the output line to * * This function connects an anonymous output GPIO line on a device * up to an arbitrary qemu_irq, so that when the device asserts that @@ -509,7 +509,7 @@ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); * @dev: Device whose GPIO to connect * @name: Name of the output GPIO array * @n: Number of the anonymous output GPIO line (which must be in range) - * @pin: qemu_irq to connect the output line to + * @input_pin: qemu_irq to connect the output line to * * This function connects an anonymous output GPIO line on a device * up to an arbitrary qemu_irq, so that when the device asserts that @@ -530,7 +530,7 @@ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); * For anonymous output GPIO lines, use qdev_connect_gpio_out(). */ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, - qemu_irq pin); + qemu_irq input_pin); /** * qdev_get_gpio_out_connector: Get the qemu_irq connected to an output GPIO -- cgit v1.2.3 From 1ab192f30caeb7dd409fa82164ffa0df5e984a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 15 Nov 2021 12:32:09 +0100 Subject: tests/unit/test-smp-parse: Pass machine type as argument to tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use g_test_add_data_func() instead of g_test_add_func() so we can pass the machine type to the tests (we will soon have different machine types). Reviewed-by: Richard Henderson Reviewed-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211216132015.815493-2-philmd@redhat.com> --- tests/unit/test-smp-parse.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index b02450e25a..37c6b4981d 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -487,9 +487,10 @@ static void machine_base_class_init(ObjectClass *oc, void *data) mc->name = g_strdup(SMP_MACHINE_NAME); } -static void test_generic(void) +static void test_generic(const void *opaque) { - Object *obj = object_new(TYPE_MACHINE); + const char *machine_type = opaque; + Object *obj = object_new(machine_type); MachineState *ms = MACHINE(obj); MachineClass *mc = MACHINE_GET_CLASS(obj); SMPTestData *data = &(SMPTestData){{ }}; @@ -525,9 +526,10 @@ static void test_generic(void) object_unref(obj); } -static void test_with_dies(void) +static void test_with_dies(const void *opaque) { - Object *obj = object_new(TYPE_MACHINE); + const char *machine_type = opaque; + Object *obj = object_new(machine_type); MachineState *ms = MACHINE(obj); MachineClass *mc = MACHINE_GET_CLASS(obj); SMPTestData *data = &(SMPTestData){{ }}; @@ -599,8 +601,12 @@ int main(int argc, char *argv[]) g_test_init(&argc, &argv, NULL); - g_test_add_func("/test-smp-parse/generic", test_generic); - g_test_add_func("/test-smp-parse/with_dies", test_with_dies); + g_test_add_data_func("/test-smp-parse/generic", + TYPE_MACHINE, + test_generic); + g_test_add_data_func("/test-smp-parse/with_dies", + TYPE_MACHINE, + test_with_dies); g_test_run(); -- cgit v1.2.3 From c30bdb025ce04f26ad63cbaebba911cff6573a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 15 Nov 2021 12:35:43 +0100 Subject: tests/unit/test-smp-parse: Split the 'generic' test in valid / invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the 'generic' test in two tests: 'valid' and 'invalid'. This will allow us to remove the hack which modifies the MachineClass internal state. Reviewed-by: Richard Henderson Reviewed-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211216132015.815493-3-philmd@redhat.com> --- tests/unit/test-smp-parse.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 37c6b4981d..425ed6b6b9 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -487,7 +487,7 @@ static void machine_base_class_init(ObjectClass *oc, void *data) mc->name = g_strdup(SMP_MACHINE_NAME); } -static void test_generic(const void *opaque) +static void test_generic_valid(const void *opaque) { const char *machine_type = opaque; Object *obj = object_new(machine_type); @@ -508,6 +508,18 @@ static void test_generic(const void *opaque) smp_parse_test(ms, data, true); } + object_unref(obj); +} + +static void test_generic_invalid(const void *opaque) +{ + const char *machine_type = opaque; + Object *obj = object_new(machine_type); + MachineState *ms = MACHINE(obj); + MachineClass *mc = MACHINE_GET_CLASS(obj); + SMPTestData *data = &(SMPTestData){}; + int i; + /* Force invalid min CPUs and max CPUs */ mc->min_cpus = 2; mc->max_cpus = 511; @@ -601,9 +613,12 @@ int main(int argc, char *argv[]) g_test_init(&argc, &argv, NULL); - g_test_add_data_func("/test-smp-parse/generic", + g_test_add_data_func("/test-smp-parse/generic/valid", + TYPE_MACHINE, + test_generic_valid); + g_test_add_data_func("/test-smp-parse/generic/invalid", TYPE_MACHINE, - test_generic); + test_generic_invalid); g_test_add_data_func("/test-smp-parse/with_dies", TYPE_MACHINE, test_with_dies); -- cgit v1.2.3 From 76b6d4cce364ef841a3e2e3574322ca6d8a27414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 15 Nov 2021 12:39:12 +0100 Subject: tests/unit/test-smp-parse: Add 'smp-with-dies' machine type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid modifying the MachineClass internals by adding the 'smp-with-dies' machine, which inherits from TYPE_MACHINE. Reviewed-by: Richard Henderson Reviewed-by: Yanan Wang Tested-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211216132015.815493-4-philmd@redhat.com> --- tests/unit/test-smp-parse.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 425ed6b6b9..f66cf7bb59 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -487,6 +487,16 @@ static void machine_base_class_init(ObjectClass *oc, void *data) mc->name = g_strdup(SMP_MACHINE_NAME); } +static void machine_with_dies_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->min_cpus = MIN_CPUS; + mc->max_cpus = MAX_CPUS; + + mc->smp_props.dies_supported = true; +} + static void test_generic_valid(const void *opaque) { const char *machine_type = opaque; @@ -548,9 +558,6 @@ static void test_with_dies(const void *opaque) unsigned int num_dies = 2; int i; - /* Force the SMP compat properties */ - mc->smp_props.dies_supported = true; - for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { *data = data_generic_valid[i]; unsupported_params_init(mc, data); @@ -588,9 +595,6 @@ static void test_with_dies(const void *opaque) smp_parse_test(ms, data, false); } - /* Restore the SMP compat properties */ - mc->smp_props.dies_supported = false; - object_unref(obj); } @@ -602,6 +606,10 @@ static const TypeInfo smp_machine_types[] = { .class_init = machine_base_class_init, .class_size = sizeof(MachineClass), .instance_size = sizeof(MachineState), + }, { + .name = MACHINE_TYPE_NAME("smp-with-dies"), + .parent = TYPE_MACHINE, + .class_init = machine_with_dies_class_init, } }; @@ -620,7 +628,7 @@ int main(int argc, char *argv[]) TYPE_MACHINE, test_generic_invalid); g_test_add_data_func("/test-smp-parse/with_dies", - TYPE_MACHINE, + MACHINE_TYPE_NAME("smp-with-dies"), test_with_dies); g_test_run(); -- cgit v1.2.3 From 7ca0705eba00c0d38f7b37670ee6cff9b607bb74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 15 Nov 2021 15:44:07 +0100 Subject: tests/unit/test-smp-parse: Add 'smp-generic-invalid' machine type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid modifying the MachineClass internals by adding the 'smp-generic-invalid' machine, which inherits from TYPE_MACHINE. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Yanan Wang Message-Id: <20211216132015.815493-5-philmd@redhat.com> --- tests/unit/test-smp-parse.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index f66cf7bb59..47e11089e2 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -487,6 +487,17 @@ static void machine_base_class_init(ObjectClass *oc, void *data) mc->name = g_strdup(SMP_MACHINE_NAME); } +static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + /* Force invalid min CPUs and max CPUs */ + mc->min_cpus = 2; + mc->max_cpus = 511; + + mc->smp_props.dies_supported = false; +} + static void machine_with_dies_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -530,10 +541,6 @@ static void test_generic_invalid(const void *opaque) SMPTestData *data = &(SMPTestData){}; int i; - /* Force invalid min CPUs and max CPUs */ - mc->min_cpus = 2; - mc->max_cpus = 511; - for (i = 0; i < ARRAY_SIZE(data_generic_invalid); i++) { *data = data_generic_invalid[i]; unsupported_params_init(mc, data); @@ -541,10 +548,6 @@ static void test_generic_invalid(const void *opaque) smp_parse_test(ms, data, false); } - /* Reset the supported min CPUs and max CPUs */ - mc->min_cpus = MIN_CPUS; - mc->max_cpus = MAX_CPUS; - object_unref(obj); } @@ -606,6 +609,10 @@ static const TypeInfo smp_machine_types[] = { .class_init = machine_base_class_init, .class_size = sizeof(MachineClass), .instance_size = sizeof(MachineState), + }, { + .name = MACHINE_TYPE_NAME("smp-generic-invalid"), + .parent = TYPE_MACHINE, + .class_init = machine_generic_invalid_class_init, }, { .name = MACHINE_TYPE_NAME("smp-with-dies"), .parent = TYPE_MACHINE, @@ -625,7 +632,7 @@ int main(int argc, char *argv[]) TYPE_MACHINE, test_generic_valid); g_test_add_data_func("/test-smp-parse/generic/invalid", - TYPE_MACHINE, + MACHINE_TYPE_NAME("smp-generic-invalid"), test_generic_invalid); g_test_add_data_func("/test-smp-parse/with_dies", MACHINE_TYPE_NAME("smp-with-dies"), -- cgit v1.2.3 From 2dc426c468833619afc1221666e0e6246b8f21d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 15 Nov 2021 15:49:59 +0100 Subject: tests/unit/test-smp-parse: Add 'smp-generic-valid' machine type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the common TYPE_MACHINE class initialization in machine_base_class_init(), make it abstract, and move the non-common code to a new class: "smp-generic-valid". Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Yanan Wang Message-Id: <20211216132015.815493-6-philmd@redhat.com> --- tests/unit/test-smp-parse.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 47e11089e2..b20bf2c235 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -478,13 +478,19 @@ static void machine_base_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + mc->smp_props.prefer_sockets = true; + + mc->name = g_strdup(SMP_MACHINE_NAME); +} + +static void machine_generic_valid_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + mc->min_cpus = MIN_CPUS; mc->max_cpus = MAX_CPUS; - mc->smp_props.prefer_sockets = true; mc->smp_props.dies_supported = false; - - mc->name = g_strdup(SMP_MACHINE_NAME); } static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) @@ -606,9 +612,14 @@ static const TypeInfo smp_machine_types[] = { { .name = TYPE_MACHINE, .parent = TYPE_OBJECT, + .abstract = true, .class_init = machine_base_class_init, .class_size = sizeof(MachineClass), .instance_size = sizeof(MachineState), + }, { + .name = MACHINE_TYPE_NAME("smp-generic-valid"), + .parent = TYPE_MACHINE, + .class_init = machine_generic_valid_class_init, }, { .name = MACHINE_TYPE_NAME("smp-generic-invalid"), .parent = TYPE_MACHINE, @@ -629,7 +640,7 @@ int main(int argc, char *argv[]) g_test_init(&argc, &argv, NULL); g_test_add_data_func("/test-smp-parse/generic/valid", - TYPE_MACHINE, + MACHINE_TYPE_NAME("smp-generic-valid"), test_generic_valid); g_test_add_data_func("/test-smp-parse/generic/invalid", MACHINE_TYPE_NAME("smp-generic-invalid"), -- cgit v1.2.3 From 47ab8a491ac62a884a42fb50ef3c7c7e0dac59d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 11 Nov 2021 08:58:40 +0100 Subject: tests/unit/test-smp-parse: Simplify pointer to compound literal use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can simply use a local variable (and pass its pointer) instead of a pointer to a compound literal. Reviewed-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Yanan Wang Tested-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211216132015.815493-7-philmd@redhat.com> --- tests/unit/test-smp-parse.c | 66 ++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index b20bf2c235..395929b66c 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -520,19 +520,19 @@ static void test_generic_valid(const void *opaque) Object *obj = object_new(machine_type); MachineState *ms = MACHINE(obj); MachineClass *mc = MACHINE_GET_CLASS(obj); - SMPTestData *data = &(SMPTestData){{ }}; + SMPTestData data = {}; int i; for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { - *data = data_generic_valid[i]; - unsupported_params_init(mc, data); + data = data_generic_valid[i]; + unsupported_params_init(mc, &data); - smp_parse_test(ms, data, true); + smp_parse_test(ms, &data, true); /* Unsupported parameters can be provided with their values as 1 */ - data->config.has_dies = true; - data->config.dies = 1; - smp_parse_test(ms, data, true); + data.config.has_dies = true; + data.config.dies = 1; + smp_parse_test(ms, &data, true); } object_unref(obj); @@ -544,14 +544,14 @@ static void test_generic_invalid(const void *opaque) Object *obj = object_new(machine_type); MachineState *ms = MACHINE(obj); MachineClass *mc = MACHINE_GET_CLASS(obj); - SMPTestData *data = &(SMPTestData){}; + SMPTestData data = {}; int i; for (i = 0; i < ARRAY_SIZE(data_generic_invalid); i++) { - *data = data_generic_invalid[i]; - unsupported_params_init(mc, data); + data = data_generic_invalid[i]; + unsupported_params_init(mc, &data); - smp_parse_test(ms, data, false); + smp_parse_test(ms, &data, false); } object_unref(obj); @@ -563,45 +563,45 @@ static void test_with_dies(const void *opaque) Object *obj = object_new(machine_type); MachineState *ms = MACHINE(obj); MachineClass *mc = MACHINE_GET_CLASS(obj); - SMPTestData *data = &(SMPTestData){{ }}; + SMPTestData data = {}; unsigned int num_dies = 2; int i; for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { - *data = data_generic_valid[i]; - unsupported_params_init(mc, data); + data = data_generic_valid[i]; + unsupported_params_init(mc, &data); /* when dies parameter is omitted, it will be set as 1 */ - data->expect_prefer_sockets.dies = 1; - data->expect_prefer_cores.dies = 1; + data.expect_prefer_sockets.dies = 1; + data.expect_prefer_cores.dies = 1; - smp_parse_test(ms, data, true); + smp_parse_test(ms, &data, true); /* when dies parameter is specified */ - data->config.has_dies = true; - data->config.dies = num_dies; - if (data->config.has_cpus) { - data->config.cpus *= num_dies; + data.config.has_dies = true; + data.config.dies = num_dies; + if (data.config.has_cpus) { + data.config.cpus *= num_dies; } - if (data->config.has_maxcpus) { - data->config.maxcpus *= num_dies; + if (data.config.has_maxcpus) { + data.config.maxcpus *= num_dies; } - data->expect_prefer_sockets.dies = num_dies; - data->expect_prefer_sockets.cpus *= num_dies; - data->expect_prefer_sockets.max_cpus *= num_dies; - data->expect_prefer_cores.dies = num_dies; - data->expect_prefer_cores.cpus *= num_dies; - data->expect_prefer_cores.max_cpus *= num_dies; + data.expect_prefer_sockets.dies = num_dies; + data.expect_prefer_sockets.cpus *= num_dies; + data.expect_prefer_sockets.max_cpus *= num_dies; + data.expect_prefer_cores.dies = num_dies; + data.expect_prefer_cores.cpus *= num_dies; + data.expect_prefer_cores.max_cpus *= num_dies; - smp_parse_test(ms, data, true); + smp_parse_test(ms, &data, true); } for (i = 0; i < ARRAY_SIZE(data_with_dies_invalid); i++) { - *data = data_with_dies_invalid[i]; - unsupported_params_init(mc, data); + data = data_with_dies_invalid[i]; + unsupported_params_init(mc, &data); - smp_parse_test(ms, data, false); + smp_parse_test(ms, &data, false); } object_unref(obj); -- cgit v1.2.3 From cf65000ae9884bc4bb36f2941568353ba405d966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 11 Nov 2021 10:23:06 +0100 Subject: tests/unit/test-smp-parse: Constify some pointer/struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare structures const when we don't need to modify them at runtime. Reviewed-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Yanan Wang Tested-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211216132015.815493-8-philmd@redhat.com> --- tests/unit/test-smp-parse.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 395929b66c..0f98c9509e 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -83,7 +83,7 @@ typedef struct SMPTestData { * then test the automatic calculation algorithm of the missing * values in the parser. */ -static struct SMPTestData data_generic_valid[] = { +static const struct SMPTestData data_generic_valid[] = { { /* config: no configuration provided * expect: cpus=1,sockets=1,cores=1,threads=1,maxcpus=1 */ @@ -285,7 +285,7 @@ static struct SMPTestData data_generic_valid[] = { }, }; -static struct SMPTestData data_generic_invalid[] = { +static const struct SMPTestData data_generic_invalid[] = { { /* config: -smp 2,dies=2 */ .config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), @@ -319,7 +319,7 @@ static struct SMPTestData data_generic_invalid[] = { }, }; -static struct SMPTestData data_with_dies_invalid[] = { +static const struct SMPTestData data_with_dies_invalid[] = { { /* config: -smp 16,sockets=2,dies=2,cores=4,threads=2,maxcpus=16 */ .config = SMP_CONFIG_WITH_DIES(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16), @@ -356,7 +356,7 @@ static char *smp_config_to_string(SMPConfiguration *config) config->has_maxcpus ? "true" : "false", config->maxcpus); } -static char *cpu_topology_to_string(CpuTopology *topo) +static char *cpu_topology_to_string(const CpuTopology *topo) { return g_strdup_printf( "(CpuTopology) {\n" @@ -372,7 +372,7 @@ static char *cpu_topology_to_string(CpuTopology *topo) } static void check_parse(MachineState *ms, SMPConfiguration *config, - CpuTopology *expect_topo, const char *expect_err, + const CpuTopology *expect_topo, const char *expect_err, bool is_valid) { g_autofree char *config_str = smp_config_to_string(config); @@ -466,7 +466,7 @@ static void smp_parse_test(MachineState *ms, SMPTestData *data, bool is_valid) } /* The parsed results of the unsupported parameters should be 1 */ -static void unsupported_params_init(MachineClass *mc, SMPTestData *data) +static void unsupported_params_init(const MachineClass *mc, SMPTestData *data) { if (!mc->smp_props.dies_supported) { data->expect_prefer_sockets.dies = 1; -- cgit v1.2.3 From 3e2f14981c73f0cc009963512d63f2919efed5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 11 Nov 2021 10:21:23 +0100 Subject: hw/core: Rename smp_parse() -> machine_parse_smp_config() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All methods related to MachineState are prefixed with "machine_". smp_parse() does not need to be an exception. Rename it and const'ify the SMPConfiguration argument, since it doesn't need to be modified. Reviewed-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Yanan Wang Tested-by: Yanan Wang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211216132015.815493-9-philmd@redhat.com> --- hw/core/machine-smp.c | 6 ++++-- hw/core/machine.c | 2 +- include/hw/boards.h | 3 ++- tests/unit/test-smp-parse.c | 8 ++++---- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c index 116a0cbbfa..2cbfd57429 100644 --- a/hw/core/machine-smp.c +++ b/hw/core/machine-smp.c @@ -44,7 +44,8 @@ static char *cpu_hierarchy_to_string(MachineState *ms) } /* - * smp_parse - Generic function used to parse the given SMP configuration + * machine_parse_smp_config: Generic function used to parse the given + * SMP configuration * * Any missing parameter in "cpus/maxcpus/sockets/cores/threads" will be * automatically computed based on the provided ones. @@ -63,7 +64,8 @@ static char *cpu_hierarchy_to_string(MachineState *ms) * introduced topology members which are likely to be target specific should * be directly set as 1 if they are omitted (e.g. dies for PC since 4.1). */ -void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp) +void machine_parse_smp_config(MachineState *ms, + const SMPConfiguration *config, Error **errp) { MachineClass *mc = MACHINE_GET_CLASS(ms); unsigned cpus = config->has_cpus ? config->cpus : 0; diff --git a/hw/core/machine.c b/hw/core/machine.c index 53a99abc56..3993c534b9 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -761,7 +761,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name, return; } - smp_parse(ms, config, errp); + machine_parse_smp_config(ms, config, errp); } static void machine_class_init(ObjectClass *oc, void *data) diff --git a/include/hw/boards.h b/include/hw/boards.h index 9c1c190104..7597cec440 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -34,7 +34,8 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine); void machine_set_cpu_numa_node(MachineState *machine, const CpuInstanceProperties *props, Error **errp); -void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp); +void machine_parse_smp_config(MachineState *ms, + const SMPConfiguration *config, Error **errp); /** * machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 0f98c9509e..b6df8137fc 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -337,7 +337,7 @@ static const struct SMPTestData data_with_dies_invalid[] = { }, }; -static char *smp_config_to_string(SMPConfiguration *config) +static char *smp_config_to_string(const SMPConfiguration *config) { return g_strdup_printf( "(SMPConfiguration) {\n" @@ -371,7 +371,7 @@ static char *cpu_topology_to_string(const CpuTopology *topo) topo->cores, topo->threads, topo->max_cpus); } -static void check_parse(MachineState *ms, SMPConfiguration *config, +static void check_parse(MachineState *ms, const SMPConfiguration *config, const CpuTopology *expect_topo, const char *expect_err, bool is_valid) { @@ -380,8 +380,8 @@ static void check_parse(MachineState *ms, SMPConfiguration *config, g_autofree char *output_topo_str = NULL; Error *err = NULL; - /* call the generic parser smp_parse() */ - smp_parse(ms, config, &err); + /* call the generic parser */ + machine_parse_smp_config(ms, config, &err); output_topo_str = cpu_topology_to_string(&ms->smp); -- cgit v1.2.3 From 0d8717852326db6deb4f10ab47d3458fb2b73529 Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Tue, 28 Dec 2021 17:22:08 +0800 Subject: qemu-options: Improve readability of SMP related Docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have a description in qemu-options.hx for each CPU topology parameter to explain what it exactly means, and also an extra declaration for the target-specific one, e.g. "for PC only" when describing "dies", and "for PC, it's on one die" when describing "cores". Now we are going to introduce one more non-generic parameter "clusters", it will make the Doc less readable and if we still continue to use the legacy way to describe it. So let's at first make two tweaks of the Docs to improve the readability and also scalability: 1) In the -help text: Delete the extra specific declaration and describe each topology parameter level by level. Then add a note to declare that different machines may support different subsets and the actual meaning of the supported parameters will vary accordingly. 2) In the rST text: List all the sub-hierarchies currently supported in QEMU, and correspondingly give an example of -smp configuration for each of them. Signed-off-by: Yanan Wang Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211228092221.21068-2-wangyanan55@huawei.com> Signed-off-by: Philippe Mathieu-Daudé --- qemu-options.hx | 76 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 7d47510947..b39377de3f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -207,14 +207,26 @@ ERST DEF("smp", HAS_ARG, QEMU_OPTION_smp, "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n" - " set the number of CPUs to 'n' [default=1]\n" + " set the number of initial CPUs to 'n' [default=1]\n" " maxcpus= maximum number of total CPUs, including\n" " offline CPUs for hotplug, etc\n" - " sockets= number of discrete sockets in the system\n" - " dies= number of CPU dies on one socket (for PC only)\n" - " cores= number of CPU cores on one socket (for PC, it's on one die)\n" - " threads= number of threads on one CPU core\n", - QEMU_ARCH_ALL) + " sockets= number of sockets on the machine board\n" + " dies= number of dies in one socket\n" + " cores= number of cores in one die\n" + " threads= number of threads in one core\n" + "Note: Different machines may have different subsets of the CPU topology\n" + " parameters supported, so the actual meaning of the supported parameters\n" + " will vary accordingly. For example, for a machine type that supports a\n" + " three-level CPU hierarchy of sockets/cores/threads, the parameters will\n" + " sequentially mean as below:\n" + " sockets means the number of sockets on the machine board\n" + " cores means the number of cores in one socket\n" + " threads means the number of threads in one core\n" + " For a particular machine type board, an expected CPU topology hierarchy\n" + " can be defined through the supported sub-option. Unsupported parameters\n" + " can also be provided in addition to the sub-option, but their values\n" + " must be set as 1 in the purpose of correct parsing.\n", + QEMU_ARCH_ALL) SRST ``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]`` Simulate a SMP system with '\ ``n``\ ' CPUs initially present on @@ -225,27 +237,57 @@ SRST initial CPU count will match the maximum number. When only one of them is given then the omitted one will be set to its counterpart's value. Both parameters may be specified, but the maximum number of CPUs must - be equal to or greater than the initial CPU count. Both parameters are - subject to an upper limit that is determined by the specific machine - type chosen. - - To control reporting of CPU topology information, the number of sockets, - dies per socket, cores per die, and threads per core can be specified. - The sum `` sockets * cores * dies * threads `` must be equal to the - maximum CPU count. CPU targets may only support a subset of the topology - parameters. Where a CPU target does not support use of a particular - topology parameter, its value should be assumed to be 1 for the purpose - of computing the CPU maximum count. + be equal to or greater than the initial CPU count. Product of the + CPU topology hierarchy must be equal to the maximum number of CPUs. + Both parameters are subject to an upper limit that is determined by + the specific machine type chosen. + + To control reporting of CPU topology information, values of the topology + parameters can be specified. Machines may only support a subset of the + parameters and different machines may have different subsets supported + which vary depending on capacity of the corresponding CPU targets. So + for a particular machine type board, an expected topology hierarchy can + be defined through the supported sub-option. Unsupported parameters can + also be provided in addition to the sub-option, but their values must be + set as 1 in the purpose of correct parsing. Either the initial CPU count, or at least one of the topology parameters must be specified. The specified parameters must be greater than zero, explicit configuration like "cpus=0" is not allowed. Values for any omitted parameters will be computed from those which are given. + + For example, the following sub-option defines a CPU topology hierarchy + (2 sockets totally on the machine, 2 cores per socket, 2 threads per + core) for a machine that only supports sockets/cores/threads. + Some members of the option can be omitted but their values will be + automatically computed: + + :: + + -smp 8,sockets=2,cores=2,threads=2,maxcpus=8 + + The following sub-option defines a CPU topology hierarchy (2 sockets + totally on the machine, 2 dies per socket, 2 cores per die, 2 threads + per core) for PC machines which support sockets/dies/cores/threads. + Some members of the option can be omitted but their values will be + automatically computed: + + :: + + -smp 16,sockets=2,dies=2,cores=2,threads=2,maxcpus=16 + Historically preference was given to the coarsest topology parameters when computing missing values (ie sockets preferred over cores, which were preferred over threads), however, this behaviour is considered liable to change. Prior to 6.2 the preference was sockets over cores over threads. Since 6.2 the preference is cores over sockets over threads. + + For example, the following option defines a machine board with 2 sockets + of 1 core before 6.2 and 1 socket of 2 cores after 6.2: + + :: + + -smp 2 ERST DEF("numa", HAS_ARG, QEMU_OPTION_numa, -- cgit v1.2.3 From 864c3b5c32f02d3507e6a63bdb8a652803c4bd1b Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Tue, 28 Dec 2021 17:22:09 +0800 Subject: hw/core/machine: Introduce CPU cluster topology support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new Cluster-Aware Scheduling support has landed in Linux 5.16, which has been proved to benefit the scheduling performance (e.g. load balance and wake_affine strategy) on both x86_64 and AArch64. So now in Linux 5.16 we have four-level arch-neutral CPU topology definition like below and a new scheduler level for clusters. struct cpu_topology { int thread_id; int core_id; int cluster_id; int package_id; int llc_id; cpumask_t thread_sibling; cpumask_t core_sibling; cpumask_t cluster_sibling; cpumask_t llc_sibling; } A cluster generally means a group of CPU cores which share L2 cache or other mid-level resources, and it is the shared resources that is used to improve scheduler's behavior. From the point of view of the size range, it's between CPU die and CPU core. For example, on some ARM64 Kunpeng servers, we have 6 clusters in each NUMA node, and 4 CPU cores in each cluster. The 4 CPU cores share a separate L2 cache and a L3 cache tag, which brings cache affinity advantage. In virtualization, on the Hosts which have pClusters (physical clusters), if we can design a vCPU topology with cluster level for guest kernel and have a dedicated vCPU pinning. A Cluster-Aware Guest kernel can also make use of the cache affinity of CPU clusters to gain similar scheduling performance. This patch adds infrastructure for CPU cluster level topology configuration and parsing, so that the user can specify cluster parameter if their machines support it. Signed-off-by: Yanan Wang Message-Id: <20211228092221.21068-3-wangyanan55@huawei.com> Reviewed-by: Philippe Mathieu-Daudé [PMD: Added '(since 7.0)' to @clusters in qapi/machine.json] Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine-smp.c | 26 +++++++++++++++++++------- hw/core/machine.c | 3 +++ include/hw/boards.h | 6 +++++- qapi/machine.json | 5 ++++- qemu-options.hx | 7 ++++--- softmmu/vl.c | 3 +++ 6 files changed, 38 insertions(+), 12 deletions(-) diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c index 2cbfd57429..b39ed21e65 100644 --- a/hw/core/machine-smp.c +++ b/hw/core/machine-smp.c @@ -37,6 +37,10 @@ static char *cpu_hierarchy_to_string(MachineState *ms) g_string_append_printf(s, " * dies (%u)", ms->smp.dies); } + if (mc->smp_props.clusters_supported) { + g_string_append_printf(s, " * clusters (%u)", ms->smp.clusters); + } + g_string_append_printf(s, " * cores (%u)", ms->smp.cores); g_string_append_printf(s, " * threads (%u)", ms->smp.threads); @@ -71,6 +75,7 @@ void machine_parse_smp_config(MachineState *ms, unsigned cpus = config->has_cpus ? config->cpus : 0; unsigned sockets = config->has_sockets ? config->sockets : 0; unsigned dies = config->has_dies ? config->dies : 0; + unsigned clusters = config->has_clusters ? config->clusters : 0; unsigned cores = config->has_cores ? config->cores : 0; unsigned threads = config->has_threads ? config->threads : 0; unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0; @@ -82,6 +87,7 @@ void machine_parse_smp_config(MachineState *ms, if ((config->has_cpus && config->cpus == 0) || (config->has_sockets && config->sockets == 0) || (config->has_dies && config->dies == 0) || + (config->has_clusters && config->clusters == 0) || (config->has_cores && config->cores == 0) || (config->has_threads && config->threads == 0) || (config->has_maxcpus && config->maxcpus == 0)) { @@ -97,8 +103,13 @@ void machine_parse_smp_config(MachineState *ms, error_setg(errp, "dies not supported by this machine's CPU topology"); return; } + if (!mc->smp_props.clusters_supported && clusters > 1) { + error_setg(errp, "clusters not supported by this machine's CPU topology"); + return; + } dies = dies > 0 ? dies : 1; + clusters = clusters > 0 ? clusters : 1; /* compute missing values based on the provided ones */ if (cpus == 0 && maxcpus == 0) { @@ -113,41 +124,42 @@ void machine_parse_smp_config(MachineState *ms, if (sockets == 0) { cores = cores > 0 ? cores : 1; threads = threads > 0 ? threads : 1; - sockets = maxcpus / (dies * cores * threads); + sockets = maxcpus / (dies * clusters * cores * threads); } else if (cores == 0) { threads = threads > 0 ? threads : 1; - cores = maxcpus / (sockets * dies * threads); + cores = maxcpus / (sockets * dies * clusters * threads); } } else { /* prefer cores over sockets since 6.2 */ if (cores == 0) { sockets = sockets > 0 ? sockets : 1; threads = threads > 0 ? threads : 1; - cores = maxcpus / (sockets * dies * threads); + cores = maxcpus / (sockets * dies * clusters * threads); } else if (sockets == 0) { threads = threads > 0 ? threads : 1; - sockets = maxcpus / (dies * cores * threads); + sockets = maxcpus / (dies * clusters * cores * threads); } } /* try to calculate omitted threads at last */ if (threads == 0) { - threads = maxcpus / (sockets * dies * cores); + threads = maxcpus / (sockets * dies * clusters * cores); } } - maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads; + maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * clusters * cores * threads; cpus = cpus > 0 ? cpus : maxcpus; ms->smp.cpus = cpus; ms->smp.sockets = sockets; ms->smp.dies = dies; + ms->smp.clusters = clusters; ms->smp.cores = cores; ms->smp.threads = threads; ms->smp.max_cpus = maxcpus; /* sanity-check of the computed topology */ - if (sockets * dies * cores * threads != maxcpus) { + if (sockets * dies * clusters * cores * threads != maxcpus) { g_autofree char *topo_msg = cpu_hierarchy_to_string(ms); error_setg(errp, "Invalid CPU topology: " "product of the hierarchy must match maxcpus: " diff --git a/hw/core/machine.c b/hw/core/machine.c index 3993c534b9..a4a2df405f 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -742,10 +742,12 @@ static void machine_get_smp(Object *obj, Visitor *v, const char *name, .has_cpus = true, .cpus = ms->smp.cpus, .has_sockets = true, .sockets = ms->smp.sockets, .has_dies = true, .dies = ms->smp.dies, + .has_clusters = true, .clusters = ms->smp.clusters, .has_cores = true, .cores = ms->smp.cores, .has_threads = true, .threads = ms->smp.threads, .has_maxcpus = true, .maxcpus = ms->smp.max_cpus, }; + if (!visit_type_SMPConfiguration(v, name, &config, &error_abort)) { return; } @@ -932,6 +934,7 @@ static void machine_initfn(Object *obj) ms->smp.max_cpus = mc->default_cpus; ms->smp.sockets = 1; ms->smp.dies = 1; + ms->smp.clusters = 1; ms->smp.cores = 1; ms->smp.threads = 1; } diff --git a/include/hw/boards.h b/include/hw/boards.h index 7597cec440..f49a2578ea 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -129,10 +129,12 @@ typedef struct { * SMPCompatProps: * @prefer_sockets - whether sockets are preferred over cores in smp parsing * @dies_supported - whether dies are supported by the machine + * @clusters_supported - whether clusters are supported by the machine */ typedef struct { bool prefer_sockets; bool dies_supported; + bool clusters_supported; } SMPCompatProps; /** @@ -299,7 +301,8 @@ typedef struct DeviceMemoryState { * @cpus: the number of present logical processors on the machine * @sockets: the number of sockets on the machine * @dies: the number of dies in one socket - * @cores: the number of cores in one die + * @clusters: the number of clusters in one die + * @cores: the number of cores in one cluster * @threads: the number of threads in one core * @max_cpus: the maximum number of logical processors on the machine */ @@ -307,6 +310,7 @@ typedef struct CpuTopology { unsigned int cpus; unsigned int sockets; unsigned int dies; + unsigned int clusters; unsigned int cores; unsigned int threads; unsigned int max_cpus; diff --git a/qapi/machine.json b/qapi/machine.json index edeab6084b..372535b348 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1404,7 +1404,9 @@ # # @dies: number of dies per socket in the CPU topology # -# @cores: number of cores per die in the CPU topology +# @clusters: number of clusters per die in the CPU topology (since 7.0) +# +# @cores: number of cores per cluster in the CPU topology # # @threads: number of threads per core in the CPU topology # @@ -1416,6 +1418,7 @@ '*cpus': 'int', '*sockets': 'int', '*dies': 'int', + '*clusters': 'int', '*cores': 'int', '*threads': 'int', '*maxcpus': 'int' } } diff --git a/qemu-options.hx b/qemu-options.hx index b39377de3f..fd1f8135fb 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -206,13 +206,14 @@ SRST ERST DEF("smp", HAS_ARG, QEMU_OPTION_smp, - "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n" + "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]\n" " set the number of initial CPUs to 'n' [default=1]\n" " maxcpus= maximum number of total CPUs, including\n" " offline CPUs for hotplug, etc\n" " sockets= number of sockets on the machine board\n" " dies= number of dies in one socket\n" - " cores= number of cores in one die\n" + " clusters= number of clusters in one die\n" + " cores= number of cores in one cluster\n" " threads= number of threads in one core\n" "Note: Different machines may have different subsets of the CPU topology\n" " parameters supported, so the actual meaning of the supported parameters\n" @@ -228,7 +229,7 @@ DEF("smp", HAS_ARG, QEMU_OPTION_smp, " must be set as 1 in the purpose of correct parsing.\n", QEMU_ARCH_ALL) SRST -``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]`` +``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]`` Simulate a SMP system with '\ ``n``\ ' CPUs initially present on the machine type board. On boards supporting CPU hotplug, the optional '\ ``maxcpus``\ ' parameter can be set to enable further CPUs to be diff --git a/softmmu/vl.c b/softmmu/vl.c index 620a1f1367..d9e4c619d3 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -726,6 +726,9 @@ static QemuOptsList qemu_smp_opts = { }, { .name = "dies", .type = QEMU_OPT_NUMBER, + }, { + .name = "clusters", + .type = QEMU_OPT_NUMBER, }, { .name = "cores", .type = QEMU_OPT_NUMBER, -- cgit v1.2.3 From e5ef89ae44f6720e32dc4f516b2e997d2377f08a Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Tue, 28 Dec 2021 17:22:11 +0800 Subject: tests/unit/test-smp-parse: Add testcases for CPU clusters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add testcases for parsing of the four-level CPU topology hierarchy, ie sockets/clusters/cores/threads, which will be supported on ARM virt machines. Signed-off-by: Yanan Wang Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211228092221.21068-5-wangyanan55@huawei.com> Signed-off-by: Philippe Mathieu-Daudé --- tests/unit/test-smp-parse.c | 130 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 123 insertions(+), 7 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index b6df8137fc..331719bbc4 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -61,6 +61,20 @@ .has_maxcpus = hf, .maxcpus = f, \ } +/* + * Currently a 4-level topology hierarchy is supported on ARM virt machines + * -sockets/clusters/cores/threads + */ +#define SMP_CONFIG_WITH_CLUSTERS(ha, a, hb, b, hc, c, hd, d, he, e, hf, f) \ + { \ + .has_cpus = ha, .cpus = a, \ + .has_sockets = hb, .sockets = b, \ + .has_clusters = hc, .clusters = c, \ + .has_cores = hd, .cores = d, \ + .has_threads = he, .threads = e, \ + .has_maxcpus = hf, .maxcpus = f, \ + } + /** * @config - the given SMP configuration * @expect_prefer_sockets - the expected parsing result for the @@ -290,6 +304,10 @@ static const struct SMPTestData data_generic_invalid[] = { /* config: -smp 2,dies=2 */ .config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), .expect_error = "dies not supported by this machine's CPU topology", + }, { + /* config: -smp 2,clusters=2 */ + .config = SMP_CONFIG_WITH_CLUSTERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), + .expect_error = "clusters not supported by this machine's CPU topology", }, { /* config: -smp 8,sockets=2,cores=4,threads=2,maxcpus=8 */ .config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8), @@ -337,20 +355,40 @@ static const struct SMPTestData data_with_dies_invalid[] = { }, }; +static const struct SMPTestData data_with_clusters_invalid[] = { + { + /* config: -smp 16,sockets=2,clusters=2,cores=4,threads=2,maxcpus=16 */ + .config = SMP_CONFIG_WITH_CLUSTERS(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16), + .expect_error = "Invalid CPU topology: " + "product of the hierarchy must match maxcpus: " + "sockets (2) * clusters (2) * cores (4) * threads (2) " + "!= maxcpus (16)", + }, { + /* config: -smp 34,sockets=2,clusters=2,cores=4,threads=2,maxcpus=32 */ + .config = SMP_CONFIG_WITH_CLUSTERS(T, 34, T, 2, T, 2, T, 4, T, 2, T, 32), + .expect_error = "Invalid CPU topology: " + "maxcpus must be equal to or greater than smp: " + "sockets (2) * clusters (2) * cores (4) * threads (2) " + "== maxcpus (32) < smp_cpus (34)", + }, +}; + static char *smp_config_to_string(const SMPConfiguration *config) { return g_strdup_printf( "(SMPConfiguration) {\n" - " .has_cpus = %5s, cpus = %" PRId64 ",\n" - " .has_sockets = %5s, sockets = %" PRId64 ",\n" - " .has_dies = %5s, dies = %" PRId64 ",\n" - " .has_cores = %5s, cores = %" PRId64 ",\n" - " .has_threads = %5s, threads = %" PRId64 ",\n" - " .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n" + " .has_cpus = %5s, cpus = %" PRId64 ",\n" + " .has_sockets = %5s, sockets = %" PRId64 ",\n" + " .has_dies = %5s, dies = %" PRId64 ",\n" + " .has_clusters = %5s, clusters = %" PRId64 ",\n" + " .has_cores = %5s, cores = %" PRId64 ",\n" + " .has_threads = %5s, threads = %" PRId64 ",\n" + " .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n" "}", config->has_cpus ? "true" : "false", config->cpus, config->has_sockets ? "true" : "false", config->sockets, config->has_dies ? "true" : "false", config->dies, + config->has_clusters ? "true" : "false", config->clusters, config->has_cores ? "true" : "false", config->cores, config->has_threads ? "true" : "false", config->threads, config->has_maxcpus ? "true" : "false", config->maxcpus); @@ -363,11 +401,12 @@ static char *cpu_topology_to_string(const CpuTopology *topo) " .cpus = %u,\n" " .sockets = %u,\n" " .dies = %u,\n" + " .clusters = %u,\n" " .cores = %u,\n" " .threads = %u,\n" " .max_cpus = %u,\n" "}", - topo->cpus, topo->sockets, topo->dies, + topo->cpus, topo->sockets, topo->dies, topo->clusters, topo->cores, topo->threads, topo->max_cpus); } @@ -391,6 +430,7 @@ static void check_parse(MachineState *ms, const SMPConfiguration *config, (ms->smp.cpus == expect_topo->cpus) && (ms->smp.sockets == expect_topo->sockets) && (ms->smp.dies == expect_topo->dies) && + (ms->smp.clusters == expect_topo->clusters) && (ms->smp.cores == expect_topo->cores) && (ms->smp.threads == expect_topo->threads) && (ms->smp.max_cpus == expect_topo->max_cpus)) { @@ -472,6 +512,11 @@ static void unsupported_params_init(const MachineClass *mc, SMPTestData *data) data->expect_prefer_sockets.dies = 1; data->expect_prefer_cores.dies = 1; } + + if (!mc->smp_props.clusters_supported) { + data->expect_prefer_sockets.clusters = 1; + data->expect_prefer_cores.clusters = 1; + } } static void machine_base_class_init(ObjectClass *oc, void *data) @@ -491,6 +536,7 @@ static void machine_generic_valid_class_init(ObjectClass *oc, void *data) mc->max_cpus = MAX_CPUS; mc->smp_props.dies_supported = false; + mc->smp_props.clusters_supported = false; } static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) @@ -502,6 +548,7 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) mc->max_cpus = 511; mc->smp_props.dies_supported = false; + mc->smp_props.clusters_supported = false; } static void machine_with_dies_class_init(ObjectClass *oc, void *data) @@ -512,6 +559,18 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data) mc->max_cpus = MAX_CPUS; mc->smp_props.dies_supported = true; + mc->smp_props.clusters_supported = false; +} + +static void machine_with_clusters_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->min_cpus = MIN_CPUS; + mc->max_cpus = MAX_CPUS; + + mc->smp_props.clusters_supported = true; + mc->smp_props.dies_supported = false; } static void test_generic_valid(const void *opaque) @@ -607,6 +666,56 @@ static void test_with_dies(const void *opaque) object_unref(obj); } +static void test_with_clusters(const void *opaque) +{ + const char *machine_type = opaque; + Object *obj = object_new(machine_type); + MachineState *ms = MACHINE(obj); + MachineClass *mc = MACHINE_GET_CLASS(obj); + SMPTestData data = {}; + unsigned int num_clusters = 2; + int i; + + for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { + data = data_generic_valid[i]; + unsupported_params_init(mc, &data); + + /* when clusters parameter is omitted, it will be set as 1 */ + data.expect_prefer_sockets.clusters = 1; + data.expect_prefer_cores.clusters = 1; + + smp_parse_test(ms, &data, true); + + /* when clusters parameter is specified */ + data.config.has_clusters = true; + data.config.clusters = num_clusters; + if (data.config.has_cpus) { + data.config.cpus *= num_clusters; + } + if (data.config.has_maxcpus) { + data.config.maxcpus *= num_clusters; + } + + data.expect_prefer_sockets.clusters = num_clusters; + data.expect_prefer_sockets.cpus *= num_clusters; + data.expect_prefer_sockets.max_cpus *= num_clusters; + data.expect_prefer_cores.clusters = num_clusters; + data.expect_prefer_cores.cpus *= num_clusters; + data.expect_prefer_cores.max_cpus *= num_clusters; + + smp_parse_test(ms, &data, true); + } + + for (i = 0; i < ARRAY_SIZE(data_with_clusters_invalid); i++) { + data = data_with_clusters_invalid[i]; + unsupported_params_init(mc, &data); + + smp_parse_test(ms, &data, false); + } + + object_unref(obj); +} + /* Type info of the tested machine */ static const TypeInfo smp_machine_types[] = { { @@ -628,6 +737,10 @@ static const TypeInfo smp_machine_types[] = { .name = MACHINE_TYPE_NAME("smp-with-dies"), .parent = TYPE_MACHINE, .class_init = machine_with_dies_class_init, + }, { + .name = MACHINE_TYPE_NAME("smp-with-clusters"), + .parent = TYPE_MACHINE, + .class_init = machine_with_clusters_class_init, } }; @@ -648,6 +761,9 @@ int main(int argc, char *argv[]) g_test_add_data_func("/test-smp-parse/with_dies", MACHINE_TYPE_NAME("smp-with-dies"), test_with_dies); + g_test_add_data_func("/test-smp-parse/with_clusters", + MACHINE_TYPE_NAME("smp-with-clusters"), + test_with_clusters); g_test_run(); -- cgit v1.2.3 From 16f573847697038fae6657e2ed84ad2e1c4786ad Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Tue, 28 Dec 2021 17:22:12 +0800 Subject: tests/unit/test-smp-parse: No need to explicitly zero MachineClass members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default value of the MachineClass members is 0, which means we don't have to explicitly zero them. Also the value of "mc->smp_props.prefer_sockets" will be taken care of by smp_parse_test(), we don't necessarily need the statement in machine_base_class_init() either. Signed-off-by: Yanan Wang Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211228092221.21068-6-wangyanan55@huawei.com> Signed-off-by: Philippe Mathieu-Daudé --- tests/unit/test-smp-parse.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 331719bbc4..72d83d1bbc 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -523,8 +523,6 @@ static void machine_base_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - mc->smp_props.prefer_sockets = true; - mc->name = g_strdup(SMP_MACHINE_NAME); } @@ -534,9 +532,6 @@ static void machine_generic_valid_class_init(ObjectClass *oc, void *data) mc->min_cpus = MIN_CPUS; mc->max_cpus = MAX_CPUS; - - mc->smp_props.dies_supported = false; - mc->smp_props.clusters_supported = false; } static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) @@ -546,9 +541,6 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) /* Force invalid min CPUs and max CPUs */ mc->min_cpus = 2; mc->max_cpus = 511; - - mc->smp_props.dies_supported = false; - mc->smp_props.clusters_supported = false; } static void machine_with_dies_class_init(ObjectClass *oc, void *data) @@ -559,7 +551,6 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data) mc->max_cpus = MAX_CPUS; mc->smp_props.dies_supported = true; - mc->smp_props.clusters_supported = false; } static void machine_with_clusters_class_init(ObjectClass *oc, void *data) @@ -570,7 +561,6 @@ static void machine_with_clusters_class_init(ObjectClass *oc, void *data) mc->max_cpus = MAX_CPUS; mc->smp_props.clusters_supported = true; - mc->smp_props.dies_supported = false; } static void test_generic_valid(const void *opaque) -- cgit v1.2.3 From a2348fa23247f565ef0b0fcc5679b2a6d5c3acf6 Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Tue, 28 Dec 2021 17:22:13 +0800 Subject: tests/unit/test-smp-parse: Keep default MIN/MAX CPUs in machine_base_class_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most machine types in test-smp-parse will be OK to have the default MIN/MAX CPUs except "smp-generic-invalid", let's keep the default values in machine_base_class_init which will be inherited. And if we hope a different value for a specific machine, modify it in its own initialization function. Signed-off-by: Yanan Wang Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211228092221.21068-7-wangyanan55@huawei.com> Signed-off-by: Philippe Mathieu-Daudé --- tests/unit/test-smp-parse.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 72d83d1bbc..fdc39a846c 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -523,15 +523,10 @@ static void machine_base_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - mc->name = g_strdup(SMP_MACHINE_NAME); -} - -static void machine_generic_valid_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - mc->min_cpus = MIN_CPUS; mc->max_cpus = MAX_CPUS; + + mc->name = g_strdup(SMP_MACHINE_NAME); } static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) @@ -547,9 +542,6 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - mc->min_cpus = MIN_CPUS; - mc->max_cpus = MAX_CPUS; - mc->smp_props.dies_supported = true; } @@ -557,9 +549,6 @@ static void machine_with_clusters_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - mc->min_cpus = MIN_CPUS; - mc->max_cpus = MAX_CPUS; - mc->smp_props.clusters_supported = true; } @@ -718,7 +707,6 @@ static const TypeInfo smp_machine_types[] = { }, { .name = MACHINE_TYPE_NAME("smp-generic-valid"), .parent = TYPE_MACHINE, - .class_init = machine_generic_valid_class_init, }, { .name = MACHINE_TYPE_NAME("smp-generic-invalid"), .parent = TYPE_MACHINE, -- cgit v1.2.3 From da7595cad36fd8db17a0e812f656ee163bfa6701 Mon Sep 17 00:00:00 2001 From: Yanan Wang Date: Tue, 28 Dec 2021 17:22:14 +0800 Subject: MAINTAINERS: Self-recommended as reviewer of "Machine core" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I've built interests in the generic machine subsystem and have also been working on projects related to this part, self-recommand myself as a reviewer so that I can help to review some patches familiar to me, and have a chance to learn more continuously. Signed-off-by: Yanan Wang Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211228092221.21068-8-wangyanan55@huawei.com> Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5456536805..fe5eea76f6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1631,6 +1631,7 @@ Machine core M: Eduardo Habkost M: Marcel Apfelbaum R: Philippe Mathieu-Daudé +R: Yanan Wang S: Supported F: cpu.c F: hw/core/cpu.c -- cgit v1.2.3 From 90f285fd8370f404a376adb63f1555a667689745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 29 Dec 2021 17:06:39 +0100 Subject: MAINTAINERS: Change philmd's email address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The philmd@redhat.com email address will stop working on 2022-01-01, change it to my personal email address. Update .mailmap in case anyone wants to send me an email because of some past commit I authored. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211231000759.707519-1-philmd@redhat.com> --- .gitlab-ci.d/edk2/Dockerfile | 2 +- .mailmap | 1 + MAINTAINERS | 18 +++++++++--------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.d/edk2/Dockerfile b/.gitlab-ci.d/edk2/Dockerfile index b4584d1cf6..13029310f6 100644 --- a/.gitlab-ci.d/edk2/Dockerfile +++ b/.gitlab-ci.d/edk2/Dockerfile @@ -3,7 +3,7 @@ # FROM ubuntu:16.04 -MAINTAINER Philippe Mathieu-Daudé +MAINTAINER Philippe Mathieu-Daudé # Install packages required to build EDK2 RUN apt update \ diff --git a/.mailmap b/.mailmap index c45d1c5301..5113f55b3a 100644 --- a/.mailmap +++ b/.mailmap @@ -63,6 +63,7 @@ Paul Burton Paul Burton Paul Burton Paul Burton +Philippe Mathieu-Daudé Stefan Brankovic Yongbok Kim diff --git a/MAINTAINERS b/MAINTAINERS index fe5eea76f6..ae6c74f3ff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1630,7 +1630,7 @@ F: pc-bios/bios-microvm.bin Machine core M: Eduardo Habkost M: Marcel Apfelbaum -R: Philippe Mathieu-Daudé +R: Philippe Mathieu-Daudé R: Yanan Wang S: Supported F: cpu.c @@ -1811,7 +1811,7 @@ F: docs/virtio-net-failover.rst T: git https://github.com/jasowang/qemu.git net Parallel NOR Flash devices -M: Philippe Mathieu-Daudé +M: Philippe Mathieu-Daudé T: git https://gitlab.com/philmd/qemu.git pflash-next S: Maintained F: hw/block/pflash_cfi*.c @@ -2227,7 +2227,7 @@ F: hw/isa/piix4.c F: include/hw/southbridge/piix.h Firmware configuration (fw_cfg) -M: Philippe Mathieu-Daudé +M: Philippe Mathieu-Daudé R: Gerd Hoffmann S: Supported F: docs/specs/fw_cfg.txt @@ -2525,7 +2525,7 @@ F: scripts/coccinelle/errp-guard.cocci GDB stub M: Alex Bennée -R: Philippe Mathieu-Daudé +R: Philippe Mathieu-Daudé S: Maintained F: gdbstub* F: include/exec/gdbstub.h @@ -2536,7 +2536,7 @@ Memory API M: Paolo Bonzini M: Peter Xu M: David Hildenbrand -R: Philippe Mathieu-Daudé +R: Philippe Mathieu-Daudé S: Supported F: include/exec/ioport.h F: include/exec/memop.h @@ -3030,14 +3030,14 @@ F: include/hw/i2c/smbus_slave.h F: include/hw/i2c/smbus_eeprom.h Firmware schema specifications -M: Philippe Mathieu-Daudé +M: Philippe Mathieu-Daudé R: Daniel P. Berrange R: Kashyap Chamarthy S: Maintained F: docs/interop/firmware.json EDK2 Firmware -M: Philippe Mathieu-Daudé +M: Philippe Mathieu-Daudé R: Gerd Hoffmann S: Supported F: hw/i386/*ovmf* @@ -3275,7 +3275,7 @@ F: block/null.c NVMe Block Driver M: Stefan Hajnoczi R: Fam Zheng -R: Philippe Mathieu-Daudé +R: Philippe Mathieu-Daudé L: qemu-block@nongnu.org S: Supported F: block/nvme* @@ -3518,7 +3518,7 @@ F: tests/tcg/Makefile.include Integration Testing with the Avocado framework W: https://trello.com/b/6Qi1pxVn/avocado-qemu R: Cleber Rosa -R: Philippe Mathieu-Daudé +R: Philippe Mathieu-Daudé R: Wainer dos Santos Moschetta R: Beraldo Leal S: Odd Fixes -- cgit v1.2.3 From 2ece6e64846e1929c4ed338c73328d3b126e48d3 Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Fri, 31 Dec 2021 13:09:01 +0800 Subject: MAINTAINERS: email address change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fujitsu's mail service has migrated to O365 months ago, the lizhijian@cn.fujitsu.com address will stop working on 2022-06-01, change it to my new email address lizhijian@fujitsu.com. Signed-off-by: Li Zhijian Acked-by: Zhang Chen Message-Id: <20211231050901.360-1-lizhijian@cn.fujitsu.com> Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index ae6c74f3ff..f871d759fd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2982,7 +2982,7 @@ F: docs/COLO-FT.txt COLO Proxy M: Zhang Chen -M: Li Zhijian +M: Li Zhijian S: Supported F: docs/colo-proxy.txt F: net/colo* -- cgit v1.2.3