throttle: Make LeakyBucket.avg and LeakyBucket.max integer types
Both the throttling limits set with the throttling.iops-* and throttling.bps-* options and their QMP equivalents defined in the BlockIOThrottle struct are integer values. Those limits are also reported in the BlockDeviceInfo struct and they are integers there as well. Therefore there's no reason to store them internally as double and do the conversion everytime we're setting or querying them, so this patch uses uint64_t for those types. Let's also use an unsigned type because we don't allow negative values anyway. LeakyBucket.level and LeakyBucket.burst_level do however remain double because their value changes depending on the fraction of time elapsed since the previous I/O operation. Signed-off-by: Alberto Garcia <berto@igalia.com> Message-id: f29b840422767b5be2c41c2dfdbbbf6c5f8fedf8.1503580370.git.berto@igalia.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
2a8be39eba
commit
d00e6923b1
@ -77,8 +77,8 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct LeakyBucket {
|
typedef struct LeakyBucket {
|
||||||
double avg; /* average goal in units per second */
|
uint64_t avg; /* average goal in units per second */
|
||||||
double max; /* leaky bucket max burst in units */
|
uint64_t max; /* leaky bucket max burst in units */
|
||||||
double level; /* bucket level in units */
|
double level; /* bucket level in units */
|
||||||
double burst_level; /* bucket level in units (for computing bursts) */
|
double burst_level; /* bucket level in units (for computing bursts) */
|
||||||
unsigned burst_length; /* max length of the burst period, in seconds */
|
unsigned burst_length; /* max length of the burst period, in seconds */
|
||||||
|
@ -284,13 +284,14 @@ static void test_enabled(void)
|
|||||||
for (i = 0; i < BUCKETS_COUNT; i++) {
|
for (i = 0; i < BUCKETS_COUNT; i++) {
|
||||||
throttle_config_init(&cfg);
|
throttle_config_init(&cfg);
|
||||||
set_cfg_value(false, i, 150);
|
set_cfg_value(false, i, 150);
|
||||||
|
g_assert(throttle_is_valid(&cfg, NULL));
|
||||||
g_assert(throttle_enabled(&cfg));
|
g_assert(throttle_enabled(&cfg));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < BUCKETS_COUNT; i++) {
|
for (i = 0; i < BUCKETS_COUNT; i++) {
|
||||||
throttle_config_init(&cfg);
|
throttle_config_init(&cfg);
|
||||||
set_cfg_value(false, i, -150);
|
set_cfg_value(false, i, -150);
|
||||||
g_assert(!throttle_enabled(&cfg));
|
g_assert(!throttle_is_valid(&cfg, NULL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +106,13 @@ int64_t throttle_compute_wait(LeakyBucket *bkt)
|
|||||||
/* If bkt->max is 0 we still want to allow short bursts of I/O
|
/* If bkt->max is 0 we still want to allow short bursts of I/O
|
||||||
* from the guest, otherwise every other request will be throttled
|
* from the guest, otherwise every other request will be throttled
|
||||||
* and performance will suffer considerably. */
|
* and performance will suffer considerably. */
|
||||||
bucket_size = bkt->avg / 10;
|
bucket_size = (double) bkt->avg / 10;
|
||||||
burst_bucket_size = 0;
|
burst_bucket_size = 0;
|
||||||
} else {
|
} else {
|
||||||
/* If we have a burst limit then we have to wait until all I/O
|
/* If we have a burst limit then we have to wait until all I/O
|
||||||
* at burst rate has finished before throttling to bkt->avg */
|
* at burst rate has finished before throttling to bkt->avg */
|
||||||
bucket_size = bkt->max * bkt->burst_length;
|
bucket_size = bkt->max * bkt->burst_length;
|
||||||
burst_bucket_size = bkt->max / 10;
|
burst_bucket_size = (double) bkt->max / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the main bucket is full then we have to wait */
|
/* If the main bucket is full then we have to wait */
|
||||||
@ -338,8 +338,7 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp)
|
|||||||
|
|
||||||
for (i = 0; i < BUCKETS_COUNT; i++) {
|
for (i = 0; i < BUCKETS_COUNT; i++) {
|
||||||
LeakyBucket *bkt = &cfg->buckets[i];
|
LeakyBucket *bkt = &cfg->buckets[i];
|
||||||
if (bkt->avg < 0 || bkt->max < 0 ||
|
if (bkt->avg > THROTTLE_VALUE_MAX || bkt->max > THROTTLE_VALUE_MAX) {
|
||||||
bkt->avg > THROTTLE_VALUE_MAX || bkt->max > THROTTLE_VALUE_MAX) {
|
|
||||||
error_setg(errp, "bps/iops/max values must be within [0, %lld]",
|
error_setg(errp, "bps/iops/max values must be within [0, %lld]",
|
||||||
THROTTLE_VALUE_MAX);
|
THROTTLE_VALUE_MAX);
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user