1 | /* |
2 | * QEMU block throttling group infrastructure |
3 | * |
4 | * Copyright (C) Nodalink, EURL. 2014 |
5 | * Copyright (C) Igalia, S.L. 2015 |
6 | * |
7 | * Authors: |
8 | * BenoƮt Canet <benoit.canet@nodalink.com> |
9 | * Alberto Garcia <berto@igalia.com> |
10 | * |
11 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License as |
13 | * published by the Free Software Foundation; either version 2 or |
14 | * (at your option) version 3 of the License. |
15 | * |
16 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. |
20 | * |
21 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
23 | */ |
24 | |
25 | #ifndef THROTTLE_GROUPS_H |
26 | #define THROTTLE_GROUPS_H |
27 | |
28 | #include "qemu/throttle.h" |
29 | #include "block/block_int.h" |
30 | |
31 | /* The ThrottleGroupMember structure indicates membership in a ThrottleGroup |
32 | * and holds related data. |
33 | */ |
34 | |
35 | typedef struct ThrottleGroupMember { |
36 | AioContext *aio_context; |
37 | /* throttled_reqs_lock protects the CoQueues for throttled requests. */ |
38 | CoMutex throttled_reqs_lock; |
39 | CoQueue throttled_reqs[2]; |
40 | |
41 | /* Nonzero if the I/O limits are currently being ignored; generally |
42 | * it is zero. Accessed with atomic operations. |
43 | */ |
44 | unsigned int io_limits_disabled; |
45 | |
46 | /* Number of pending throttle_group_restart_queue_entry() coroutines. |
47 | * Accessed with atomic operations. |
48 | */ |
49 | unsigned int restart_pending; |
50 | |
51 | /* The following fields are protected by the ThrottleGroup lock. |
52 | * See the ThrottleGroup documentation for details. |
53 | * throttle_state tells us if I/O limits are configured. */ |
54 | ThrottleState *throttle_state; |
55 | ThrottleTimers throttle_timers; |
56 | unsigned pending_reqs[2]; |
57 | QLIST_ENTRY(ThrottleGroupMember) round_robin; |
58 | |
59 | } ThrottleGroupMember; |
60 | |
61 | #define TYPE_THROTTLE_GROUP "throttle-group" |
62 | #define THROTTLE_GROUP(obj) OBJECT_CHECK(ThrottleGroup, (obj), TYPE_THROTTLE_GROUP) |
63 | |
64 | const char *throttle_group_get_name(ThrottleGroupMember *tgm); |
65 | |
66 | ThrottleState *throttle_group_incref(const char *name); |
67 | void throttle_group_unref(ThrottleState *ts); |
68 | |
69 | void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg); |
70 | void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg); |
71 | |
72 | void throttle_group_register_tgm(ThrottleGroupMember *tgm, |
73 | const char *groupname, |
74 | AioContext *ctx); |
75 | void throttle_group_unregister_tgm(ThrottleGroupMember *tgm); |
76 | void throttle_group_restart_tgm(ThrottleGroupMember *tgm); |
77 | |
78 | void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm, |
79 | unsigned int bytes, |
80 | bool is_write); |
81 | void throttle_group_attach_aio_context(ThrottleGroupMember *tgm, |
82 | AioContext *new_context); |
83 | void throttle_group_detach_aio_context(ThrottleGroupMember *tgm); |
84 | /* |
85 | * throttle_group_exists() must be called under the global |
86 | * mutex. |
87 | */ |
88 | bool throttle_group_exists(const char *name); |
89 | |
90 | #endif |
91 | |