From 7d5983e3c8c40b1d0668faba31d79905c4fadd7d Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Mon, 25 Apr 2022 09:57:21 +0200 Subject: Introduce event-loop-base abstract class Introduce the 'event-loop-base' abstract class, it'll hold the properties common to all event loops and provide the necessary hooks for their creation and maintenance. Then have iothread inherit from it. EventLoopBaseClass is defined as user creatable and provides a hook for its children to attach themselves to the user creatable class 'complete' function. It also provides an update_params() callback to propagate property changes onto its children. The new 'event-loop-base' class will live in the root directory. It is built on its own using the 'link_whole' option (there are no direct function dependencies between the class and its children, it all happens trough 'constructor' magic). And also imposes new compilation dependencies: qom <- event-loop-base <- blockdev (iothread.c) And in subsequent patches: qom <- event-loop-base <- qemuutil (util/main-loop.c) All this forced some amount of reordering in meson.build: - Moved qom build definition before qemuutil. Doing it the other way around (i.e. moving qemuutil after qom) isn't possible as a lot of core libraries that live in between the two depend on it. - Process the 'hw' subdir earlier, as it introduces files into the 'qom' source set. No functional changes intended. Signed-off-by: Nicolas Saenz Julienne Reviewed-by: Stefan Hajnoczi Acked-by: Markus Armbruster Message-id: 20220425075723.20019-2-nsaenzju@redhat.com Signed-off-by: Stefan Hajnoczi --- qapi/qom.json | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'qapi') diff --git a/qapi/qom.json b/qapi/qom.json index eeb5395..a243953 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -500,6 +500,20 @@ '*grab-toggle': 'GrabToggleKeys' } } ## +# @EventLoopBaseProperties: +# +# Common properties for event loops +# +# @aio-max-batch: maximum number of requests in a batch for the AIO engine, +# 0 means that the engine will use its default. +# (default: 0) +# +# Since: 7.1 +## +{ 'struct': 'EventLoopBaseProperties', + 'data': { '*aio-max-batch': 'int' } } + +## # @IothreadProperties: # # Properties for iothread objects. @@ -516,17 +530,15 @@ # algorithm detects it is spending too long polling without # encountering events. 0 selects a default behaviour (default: 0) # -# @aio-max-batch: maximum number of requests in a batch for the AIO engine, -# 0 means that the engine will use its default -# (default:0, since 6.1) +# The @aio-max-batch option is available since 6.1. # # Since: 2.0 ## { 'struct': 'IothreadProperties', + 'base': 'EventLoopBaseProperties', 'data': { '*poll-max-ns': 'int', '*poll-grow': 'int', - '*poll-shrink': 'int', - '*aio-max-batch': 'int' } } + '*poll-shrink': 'int' } } ## # @MemoryBackendProperties: -- cgit v1.1 From 70ac26b9e5ca8374bb3ef3f30b871726673c9f27 Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Mon, 25 Apr 2022 09:57:22 +0200 Subject: util/main-loop: Introduce the main loop into QOM 'event-loop-base' provides basic property handling for all 'AioContext' based event loops. So let's define a new 'MainLoopClass' that inherits from it. This will permit tweaking the main loop's properties through qapi as well as through the command line using the '-object' keyword[1]. Only one instance of 'MainLoopClass' might be created at any time. 'EventLoopBaseClass' learns a new callback, 'can_be_deleted()' so as to mark 'MainLoop' as non-deletable. [1] For example: -object main-loop,id=main-loop,aio-max-batch= Signed-off-by: Nicolas Saenz Julienne Reviewed-by: Stefan Hajnoczi Acked-by: Markus Armbruster Message-id: 20220425075723.20019-3-nsaenzju@redhat.com Signed-off-by: Stefan Hajnoczi --- qapi/qom.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'qapi') diff --git a/qapi/qom.json b/qapi/qom.json index a243953..7d4a2ac 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -541,6 +541,17 @@ '*poll-shrink': 'int' } } ## +# @MainLoopProperties: +# +# Properties for the main-loop object. +# +# Since: 7.1 +## +{ 'struct': 'MainLoopProperties', + 'base': 'EventLoopBaseProperties', + 'data': {} } + +## # @MemoryBackendProperties: # # Properties for objects of classes derived from memory-backend. @@ -830,6 +841,7 @@ { 'name': 'input-linux', 'if': 'CONFIG_LINUX' }, 'iothread', + 'main-loop', { 'name': 'memory-backend-epc', 'if': 'CONFIG_LINUX' }, 'memory-backend-file', @@ -895,6 +907,7 @@ 'input-linux': { 'type': 'InputLinuxProperties', 'if': 'CONFIG_LINUX' }, 'iothread': 'IothreadProperties', + 'main-loop': 'MainLoopProperties', 'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties', 'if': 'CONFIG_LINUX' }, 'memory-backend-file': 'MemoryBackendFileProperties', -- cgit v1.1 From 71ad4713cc1d7fca24388b828ef31ae6cb38a31c Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Mon, 25 Apr 2022 09:57:23 +0200 Subject: util/event-loop-base: Introduce options to set the thread pool size The thread pool regulates itself: when idle, it kills threads until empty, when in demand, it creates new threads until full. This behaviour doesn't play well with latency sensitive workloads where the price of creating a new thread is too high. For example, when paired with qemu's '-mlock', or using safety features like SafeStack, creating a new thread has been measured take multiple milliseconds. In order to mitigate this let's introduce a new 'EventLoopBase' property to set the thread pool size. The threads will be created during the pool's initialization or upon updating the property's value, remain available during its lifetime regardless of demand, and destroyed upon freeing it. A properly characterized workload will then be able to configure the pool to avoid any latency spikes. Signed-off-by: Nicolas Saenz Julienne Reviewed-by: Stefan Hajnoczi Acked-by: Markus Armbruster Message-id: 20220425075723.20019-4-nsaenzju@redhat.com Signed-off-by: Stefan Hajnoczi --- qapi/qom.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'qapi') diff --git a/qapi/qom.json b/qapi/qom.json index 7d4a2ac..6a653c6 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -508,10 +508,18 @@ # 0 means that the engine will use its default. # (default: 0) # +# @thread-pool-min: minimum number of threads reserved in the thread pool +# (default:0) +# +# @thread-pool-max: maximum number of threads the thread pool can contain +# (default:64) +# # Since: 7.1 ## { 'struct': 'EventLoopBaseProperties', - 'data': { '*aio-max-batch': 'int' } } + 'data': { '*aio-max-batch': 'int', + '*thread-pool-min': 'int', + '*thread-pool-max': 'int' } } ## # @IothreadProperties: -- cgit v1.1