2015-06-08 18:17:42 +02:00
|
|
|
/*
|
|
|
|
* QEMU block throttling group infrastructure
|
|
|
|
*
|
|
|
|
* Copyright (C) Nodalink, EURL. 2014
|
|
|
|
* Copyright (C) Igalia, S.L. 2015
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Benoît Canet <benoit.canet@nodalink.com>
|
|
|
|
* Alberto Garcia <berto@igalia.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 or
|
|
|
|
* (at your option) version 3 of the License.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef THROTTLE_GROUPS_H
|
|
|
|
#define THROTTLE_GROUPS_H
|
|
|
|
|
|
|
|
#include "qemu/throttle.h"
|
|
|
|
#include "block/block_int.h"
|
|
|
|
|
2017-08-25 15:20:23 +02:00
|
|
|
/* The ThrottleGroupMember structure indicates membership in a ThrottleGroup
|
|
|
|
* and holds related data.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct ThrottleGroupMember {
|
2017-08-25 15:20:24 +02:00
|
|
|
AioContext *aio_context;
|
2017-08-25 15:20:23 +02:00
|
|
|
/* throttled_reqs_lock protects the CoQueues for throttled requests. */
|
|
|
|
CoMutex throttled_reqs_lock;
|
|
|
|
CoQueue throttled_reqs[2];
|
|
|
|
|
|
|
|
/* Nonzero if the I/O limits are currently being ignored; generally
|
|
|
|
* it is zero. Accessed with atomic operations.
|
|
|
|
*/
|
|
|
|
unsigned int io_limits_disabled;
|
|
|
|
|
|
|
|
/* The following fields are protected by the ThrottleGroup lock.
|
|
|
|
* See the ThrottleGroup documentation for details.
|
|
|
|
* throttle_state tells us if I/O limits are configured. */
|
|
|
|
ThrottleState *throttle_state;
|
|
|
|
ThrottleTimers throttle_timers;
|
|
|
|
unsigned pending_reqs[2];
|
|
|
|
QLIST_ENTRY(ThrottleGroupMember) round_robin;
|
|
|
|
|
|
|
|
} ThrottleGroupMember;
|
|
|
|
|
block: convert ThrottleGroup to object with QOM
ThrottleGroup is converted to an object. This will allow the future
throttle block filter drive easy creation and configuration of throttle
groups in QMP and cli.
A new QAPI struct, ThrottleLimits, is introduced to provide a shared
struct for all throttle configuration needs in QMP.
ThrottleGroups can be created via CLI as
-object throttle-group,id=foo,x-iops-total=100,x-..
where x-* are individual limit properties. Since we can't add non-scalar
properties in -object this interface must be used instead. However,
setting these properties must be disabled after initialization because
certain combinations of limits are forbidden and thus configuration
changes should be done in one transaction. The individual properties
will go away when support for non-scalar values in CLI is implemented
and thus are marked as experimental.
ThrottleGroup also has a `limits` property that uses the ThrottleLimits
struct. It can be used to create ThrottleGroups or set the
configuration in existing groups as follows:
{ "execute": "object-add",
"arguments": {
"qom-type": "throttle-group",
"id": "foo",
"props" : {
"limits": {
"iops-total": 100
}
}
}
}
{ "execute" : "qom-set",
"arguments" : {
"path" : "foo",
"property" : "limits",
"value" : {
"iops-total" : 99
}
}
}
This also means a group's configuration can be fetched with qom-get.
Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-08-25 15:20:26 +02:00
|
|
|
#define TYPE_THROTTLE_GROUP "throttle-group"
|
|
|
|
#define THROTTLE_GROUP(obj) OBJECT_CHECK(ThrottleGroup, (obj), TYPE_THROTTLE_GROUP)
|
|
|
|
|
2017-08-25 15:20:23 +02:00
|
|
|
const char *throttle_group_get_name(ThrottleGroupMember *tgm);
|
2015-06-08 18:17:42 +02:00
|
|
|
|
2015-10-19 17:53:23 +02:00
|
|
|
ThrottleState *throttle_group_incref(const char *name);
|
|
|
|
void throttle_group_unref(ThrottleState *ts);
|
|
|
|
|
2017-08-25 15:20:23 +02:00
|
|
|
void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
|
|
|
|
void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
|
2015-06-08 18:17:42 +02:00
|
|
|
|
2017-08-25 15:20:23 +02:00
|
|
|
void throttle_group_register_tgm(ThrottleGroupMember *tgm,
|
2017-08-25 15:20:24 +02:00
|
|
|
const char *groupname,
|
|
|
|
AioContext *ctx);
|
2017-08-25 15:20:23 +02:00
|
|
|
void throttle_group_unregister_tgm(ThrottleGroupMember *tgm);
|
|
|
|
void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
|
2015-06-08 18:17:42 +02:00
|
|
|
|
2017-08-25 15:20:23 +02:00
|
|
|
void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
|
2015-06-08 18:17:44 +02:00
|
|
|
unsigned int bytes,
|
|
|
|
bool is_write);
|
2017-08-25 15:20:24 +02:00
|
|
|
void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
|
|
|
|
AioContext *new_context);
|
|
|
|
void throttle_group_detach_aio_context(ThrottleGroupMember *tgm);
|
2017-08-25 15:20:27 +02:00
|
|
|
/*
|
|
|
|
* throttle_group_exists() must be called under the global
|
|
|
|
* mutex.
|
|
|
|
*/
|
|
|
|
bool throttle_group_exists(const char *name);
|
2015-06-08 18:17:44 +02:00
|
|
|
|
2015-06-08 18:17:42 +02:00
|
|
|
#endif
|