xref: /qemu/include/qemu/throttle.h (revision f2ad72b3)
1 /*
2  * QEMU throttling infrastructure
3  *
4  * Copyright (C) Nodalink, EURL. 2013-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_H
26 #define THROTTLE_H
27 
28 #include <stdint.h>
29 #include "qemu-common.h"
30 #include "qemu/timer.h"
31 
32 #define THROTTLE_VALUE_MAX 1000000000000000LL
33 
34 typedef enum {
35     THROTTLE_BPS_TOTAL,
36     THROTTLE_BPS_READ,
37     THROTTLE_BPS_WRITE,
38     THROTTLE_OPS_TOTAL,
39     THROTTLE_OPS_READ,
40     THROTTLE_OPS_WRITE,
41     BUCKETS_COUNT,
42 } BucketType;
43 
44 /*
45  * The max parameter of the leaky bucket throttling algorithm can be used to
46  * allow the guest to do bursts.
47  * The max value is a pool of I/O that the guest can use without being throttled
48  * at all. Throttling is triggered once this pool is empty.
49  */
50 
51 typedef struct LeakyBucket {
52     double  avg;              /* average goal in units per second */
53     double  max;              /* leaky bucket max burst in units */
54     double  level;            /* bucket level in units */
55 } LeakyBucket;
56 
57 /* The following structure is used to configure a ThrottleState
58  * It contains a bit of state: the bucket field of the LeakyBucket structure.
59  * However it allows to keep the code clean and the bucket field is reset to
60  * zero at the right time.
61  */
62 typedef struct ThrottleConfig {
63     LeakyBucket buckets[BUCKETS_COUNT]; /* leaky buckets */
64     uint64_t op_size;         /* size of an operation in bytes */
65 } ThrottleConfig;
66 
67 typedef struct ThrottleState {
68     ThrottleConfig cfg;       /* configuration */
69     int64_t previous_leak;    /* timestamp of the last leak done */
70 } ThrottleState;
71 
72 typedef struct ThrottleTimers {
73     QEMUTimer *timers[2];     /* timers used to do the throttling */
74     QEMUClockType clock_type; /* the clock used */
75 
76     /* Callbacks */
77     QEMUTimerCB *read_timer_cb;
78     QEMUTimerCB *write_timer_cb;
79     void *timer_opaque;
80 } ThrottleTimers;
81 
82 /* operations on single leaky buckets */
83 void throttle_leak_bucket(LeakyBucket *bkt, int64_t delta);
84 
85 int64_t throttle_compute_wait(LeakyBucket *bkt);
86 
87 /* expose timer computation function for unit tests */
88 bool throttle_compute_timer(ThrottleState *ts,
89                             bool is_write,
90                             int64_t now,
91                             int64_t *next_timestamp);
92 
93 /* init/destroy cycle */
94 void throttle_init(ThrottleState *ts);
95 
96 void throttle_timers_init(ThrottleTimers *tt,
97                           AioContext *aio_context,
98                           QEMUClockType clock_type,
99                           QEMUTimerCB *read_timer_cb,
100                           QEMUTimerCB *write_timer_cb,
101                           void *timer_opaque);
102 
103 void throttle_timers_destroy(ThrottleTimers *tt);
104 
105 void throttle_timers_detach_aio_context(ThrottleTimers *tt);
106 
107 void throttle_timers_attach_aio_context(ThrottleTimers *tt,
108                                         AioContext *new_context);
109 
110 bool throttle_timers_are_initialized(ThrottleTimers *tt);
111 
112 /* configuration */
113 bool throttle_enabled(ThrottleConfig *cfg);
114 
115 bool throttle_conflicting(ThrottleConfig *cfg);
116 
117 bool throttle_is_valid(ThrottleConfig *cfg);
118 
119 bool throttle_max_is_missing_limit(ThrottleConfig *cfg);
120 
121 void throttle_config(ThrottleState *ts,
122                      ThrottleTimers *tt,
123                      ThrottleConfig *cfg);
124 
125 void throttle_get_config(ThrottleState *ts, ThrottleConfig *cfg);
126 
127 /* usage */
128 bool throttle_schedule_timer(ThrottleState *ts,
129                              ThrottleTimers *tt,
130                              bool is_write);
131 
132 void throttle_account(ThrottleState *ts, bool is_write, uint64_t size);
133 
134 #endif
135