xref: /openbmc/qemu/include/block/throttle-groups.h (revision bc19a0a6e4505390f99d3c593ebaf11b7962cc59)
12ff1f2e3SAlberto Garcia /*
22ff1f2e3SAlberto Garcia  * QEMU block throttling group infrastructure
32ff1f2e3SAlberto Garcia  *
42ff1f2e3SAlberto Garcia  * Copyright (C) Nodalink, EURL. 2014
52ff1f2e3SAlberto Garcia  * Copyright (C) Igalia, S.L. 2015
62ff1f2e3SAlberto Garcia  *
72ff1f2e3SAlberto Garcia  * Authors:
82ff1f2e3SAlberto Garcia  *   Benoît Canet <benoit.canet@nodalink.com>
92ff1f2e3SAlberto Garcia  *   Alberto Garcia <berto@igalia.com>
102ff1f2e3SAlberto Garcia  *
112ff1f2e3SAlberto Garcia  * This program is free software; you can redistribute it and/or
122ff1f2e3SAlberto Garcia  * modify it under the terms of the GNU General Public License as
132ff1f2e3SAlberto Garcia  * published by the Free Software Foundation; either version 2 or
142ff1f2e3SAlberto Garcia  * (at your option) version 3 of the License.
152ff1f2e3SAlberto Garcia  *
162ff1f2e3SAlberto Garcia  * This program is distributed in the hope that it will be useful,
172ff1f2e3SAlberto Garcia  * but WITHOUT ANY WARRANTY; without even the implied warranty of
182ff1f2e3SAlberto Garcia  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
192ff1f2e3SAlberto Garcia  * GNU General Public License for more details.
202ff1f2e3SAlberto Garcia  *
212ff1f2e3SAlberto Garcia  * You should have received a copy of the GNU General Public License
222ff1f2e3SAlberto Garcia  * along with this program; if not, see <http://www.gnu.org/licenses/>.
232ff1f2e3SAlberto Garcia  */
242ff1f2e3SAlberto Garcia 
252ff1f2e3SAlberto Garcia #ifndef THROTTLE_GROUPS_H
262ff1f2e3SAlberto Garcia #define THROTTLE_GROUPS_H
272ff1f2e3SAlberto Garcia 
282ff1f2e3SAlberto Garcia #include "qemu/throttle.h"
292ff1f2e3SAlberto Garcia #include "block/block_int.h"
302ff1f2e3SAlberto Garcia 
31022cdc9fSManos Pitsidianakis /* The ThrottleGroupMember structure indicates membership in a ThrottleGroup
32022cdc9fSManos Pitsidianakis  * and holds related data.
33022cdc9fSManos Pitsidianakis  */
34022cdc9fSManos Pitsidianakis 
35022cdc9fSManos Pitsidianakis typedef struct ThrottleGroupMember {
36c61791fcSManos Pitsidianakis     AioContext   *aio_context;
37022cdc9fSManos Pitsidianakis     /* throttled_reqs_lock protects the CoQueues for throttled requests.  */
38022cdc9fSManos Pitsidianakis     CoMutex      throttled_reqs_lock;
39022cdc9fSManos Pitsidianakis     CoQueue      throttled_reqs[2];
40022cdc9fSManos Pitsidianakis 
41022cdc9fSManos Pitsidianakis     /* Nonzero if the I/O limits are currently being ignored; generally
42022cdc9fSManos Pitsidianakis      * it is zero.  Accessed with atomic operations.
43022cdc9fSManos Pitsidianakis      */
44022cdc9fSManos Pitsidianakis     unsigned int io_limits_disabled;
45022cdc9fSManos Pitsidianakis 
46*bc19a0a6SStefan Hajnoczi     /* Number of pending throttle_group_restart_queue_entry() coroutines.
47*bc19a0a6SStefan Hajnoczi      * Accessed with atomic operations.
48*bc19a0a6SStefan Hajnoczi      */
49*bc19a0a6SStefan Hajnoczi     unsigned int restart_pending;
50*bc19a0a6SStefan Hajnoczi 
51022cdc9fSManos Pitsidianakis     /* The following fields are protected by the ThrottleGroup lock.
52022cdc9fSManos Pitsidianakis      * See the ThrottleGroup documentation for details.
53022cdc9fSManos Pitsidianakis      * throttle_state tells us if I/O limits are configured. */
54022cdc9fSManos Pitsidianakis     ThrottleState *throttle_state;
55022cdc9fSManos Pitsidianakis     ThrottleTimers throttle_timers;
56022cdc9fSManos Pitsidianakis     unsigned       pending_reqs[2];
57022cdc9fSManos Pitsidianakis     QLIST_ENTRY(ThrottleGroupMember) round_robin;
58022cdc9fSManos Pitsidianakis 
59022cdc9fSManos Pitsidianakis } ThrottleGroupMember;
60022cdc9fSManos Pitsidianakis 
61432d889eSManos Pitsidianakis #define TYPE_THROTTLE_GROUP "throttle-group"
62432d889eSManos Pitsidianakis #define THROTTLE_GROUP(obj) OBJECT_CHECK(ThrottleGroup, (obj), TYPE_THROTTLE_GROUP)
63432d889eSManos Pitsidianakis 
64022cdc9fSManos Pitsidianakis const char *throttle_group_get_name(ThrottleGroupMember *tgm);
652ff1f2e3SAlberto Garcia 
66973f2ddfSMax Reitz ThrottleState *throttle_group_incref(const char *name);
67973f2ddfSMax Reitz void throttle_group_unref(ThrottleState *ts);
68973f2ddfSMax Reitz 
69022cdc9fSManos Pitsidianakis void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
70022cdc9fSManos Pitsidianakis void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
712ff1f2e3SAlberto Garcia 
72022cdc9fSManos Pitsidianakis void throttle_group_register_tgm(ThrottleGroupMember *tgm,
73c61791fcSManos Pitsidianakis                                 const char *groupname,
74c61791fcSManos Pitsidianakis                                 AioContext *ctx);
75022cdc9fSManos Pitsidianakis void throttle_group_unregister_tgm(ThrottleGroupMember *tgm);
76022cdc9fSManos Pitsidianakis void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
772ff1f2e3SAlberto Garcia 
78022cdc9fSManos Pitsidianakis void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
7976f4afb4SAlberto Garcia                                                         unsigned int bytes,
8076f4afb4SAlberto Garcia                                                         bool is_write);
81c61791fcSManos Pitsidianakis void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
82c61791fcSManos Pitsidianakis                                        AioContext *new_context);
83c61791fcSManos Pitsidianakis void throttle_group_detach_aio_context(ThrottleGroupMember *tgm);
84d8e7d87eSManos Pitsidianakis /*
85d8e7d87eSManos Pitsidianakis  * throttle_group_exists() must be called under the global
86d8e7d87eSManos Pitsidianakis  * mutex.
87d8e7d87eSManos Pitsidianakis  */
88d8e7d87eSManos Pitsidianakis bool throttle_group_exists(const char *name);
8976f4afb4SAlberto Garcia 
902ff1f2e3SAlberto Garcia #endif
91