* [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver
@ 2017-06-11 1:14 Manos Pitsidianakis
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember Manos Pitsidianakis
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Manos Pitsidianakis @ 2017-06-11 1:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Alberto Garcia, Kevin Wolf, Stefan Hajnoczi, qemu-block
block: move ThrottleGroup membership to ThrottleGroupMember
block: add throttle block filter driver
block/Makefile.objs | 1 +
block/block-backend.c | 75 +++++----
block/qapi.c | 8 +-
block/throttle-groups.c | 315 +++++++++++++++-------------------
block/throttle.c | 364 ++++++++++++++++++++++++++++++++++++++++
blockdev.c | 4 +-
include/block/throttle-groups.h | 21 ++-
include/qemu/throttle-options.h | 60 ++++---
include/qemu/throttle.h | 64 +++++++
include/sysemu/block-backend.h | 22 +--
tests/test-throttle.c | 53 +++---
util/throttle.c | 5 +
12 files changed, 709 insertions(+), 283 deletions(-)
create mode 100644 block/throttle.c
--
2.11.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember
2017-06-11 1:14 [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver Manos Pitsidianakis
@ 2017-06-11 1:14 ` Manos Pitsidianakis
2017-06-13 8:48 ` Alberto Garcia
2017-06-13 10:01 ` Kevin Wolf
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 2/2] block: add throttle block filter driver Manos Pitsidianakis
2017-06-11 1:28 ` [Qemu-devel] [PATCH RFC v2 0/2] IO throttling " no-reply
2 siblings, 2 replies; 7+ messages in thread
From: Manos Pitsidianakis @ 2017-06-11 1:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Alberto Garcia, Kevin Wolf, Stefan Hajnoczi, qemu-block
This commit gathers ThrottleGroup membership details from BlockBackendPublic
into ThrottleGroupMember and refactors existing code to use the structure.
Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
---
block/block-backend.c | 75 ++++++----
block/qapi.c | 8 +-
block/throttle-groups.c | 305 +++++++++++++++++-----------------------
blockdev.c | 4 +-
include/block/throttle-groups.h | 15 +-
include/qemu/throttle.h | 64 +++++++++
include/sysemu/block-backend.h | 22 +--
tests/test-throttle.c | 53 +++----
util/throttle.c | 5 +
9 files changed, 293 insertions(+), 258 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index f3a60081a7..1d6b35c34d 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -209,6 +209,7 @@ static const BdrvChildRole child_root = {
BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
{
BlockBackend *blk;
+ BlockBackendPublic *blkp;
blk = g_new0(BlockBackend, 1);
blk->refcnt = 1;
@@ -216,8 +217,9 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
blk->shared_perm = shared_perm;
blk_set_enable_write_cache(blk, true);
- qemu_co_queue_init(&blk->public.throttled_reqs[0]);
- qemu_co_queue_init(&blk->public.throttled_reqs[1]);
+ blkp = blk_get_public(blk);
+ qemu_co_queue_init(&blkp->throttle_group_member.throttled_reqs[0]);
+ qemu_co_queue_init(&blkp->throttle_group_member.throttled_reqs[1]);
notifier_list_init(&blk->remove_bs_notifiers);
notifier_list_init(&blk->insert_bs_notifiers);
@@ -284,7 +286,7 @@ static void blk_delete(BlockBackend *blk)
assert(!blk->refcnt);
assert(!blk->name);
assert(!blk->dev);
- if (blk->public.throttle_state) {
+ if (blk_get_public(blk)->throttle_group_member.throttle_state) {
blk_io_limits_disable(blk);
}
if (blk->root) {
@@ -596,8 +598,10 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
void blk_remove_bs(BlockBackend *blk)
{
notifier_list_notify(&blk->remove_bs_notifiers, blk);
- if (blk->public.throttle_state) {
- throttle_timers_detach_aio_context(&blk->public.throttle_timers);
+ BlockBackendPublic *blkp = blk_get_public(blk);
+ if (blkp->throttle_group_member.throttle_state) {
+ ThrottleTimers *tt = &blkp->throttle_group_member.throttle_timers;
+ throttle_timers_detach_aio_context(tt);
}
blk_update_root_state(blk);
@@ -619,9 +623,10 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
bdrv_ref(bs);
notifier_list_notify(&blk->insert_bs_notifiers, blk);
- if (blk->public.throttle_state) {
+ if (blk_get_public(blk)->throttle_group_member.throttle_state) {
throttle_timers_attach_aio_context(
- &blk->public.throttle_timers, bdrv_get_aio_context(bs));
+ &blk_get_public(blk)->throttle_group_member.throttle_timers,
+ bdrv_get_aio_context(bs));
}
return 0;
@@ -972,6 +977,7 @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
{
int ret;
BlockDriverState *bs = blk_bs(blk);
+ BlockBackendPublic *blkp;
trace_blk_co_preadv(blk, bs, offset, bytes, flags);
@@ -981,10 +987,12 @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
}
bdrv_inc_in_flight(bs);
+ blkp = blk_get_public(blk);
/* throttling disk I/O */
- if (blk->public.throttle_state) {
- throttle_group_co_io_limits_intercept(blk, bytes, false);
+ if (blkp->throttle_group_member.throttle_state) {
+ throttle_group_co_io_limits_intercept(&blkp->throttle_group_member,
+ bytes, false);
}
ret = bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
@@ -998,6 +1006,7 @@ int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
{
int ret;
BlockDriverState *bs = blk_bs(blk);
+ BlockBackendPublic *blkp;
trace_blk_co_pwritev(blk, bs, offset, bytes, flags);
@@ -1007,10 +1016,11 @@ int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
}
bdrv_inc_in_flight(bs);
-
+ blkp = blk_get_public(blk);
/* throttling disk I/O */
- if (blk->public.throttle_state) {
- throttle_group_co_io_limits_intercept(blk, bytes, true);
+ if (blkp->throttle_group_member.throttle_state) {
+ throttle_group_co_io_limits_intercept(&blkp->throttle_group_member,
+ bytes, true);
}
if (!blk->enable_write_cache) {
@@ -1681,13 +1691,15 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
BlockDriverState *bs = blk_bs(blk);
if (bs) {
- if (blk->public.throttle_state) {
- throttle_timers_detach_aio_context(&blk->public.throttle_timers);
+ BlockBackendPublic *blkp = blk_get_public(blk);
+ if (blkp->throttle_group_member.throttle_state) {
+ ThrottleTimers *tt = &blkp->throttle_group_member.throttle_timers;
+ throttle_timers_detach_aio_context(tt);
}
bdrv_set_aio_context(bs, new_context);
- if (blk->public.throttle_state) {
- throttle_timers_attach_aio_context(&blk->public.throttle_timers,
- new_context);
+ if (blkp->throttle_group_member.throttle_state) {
+ ThrottleTimers *tt = &blkp->throttle_group_member.throttle_timers;
+ throttle_timers_attach_aio_context(tt, new_context);
}
}
}
@@ -1905,33 +1917,39 @@ int blk_commit_all(void)
/* throttling disk I/O limits */
void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
{
- throttle_group_config(blk, cfg);
+ throttle_group_config(&blk_get_public(blk)->throttle_group_member, cfg);
}
void blk_io_limits_disable(BlockBackend *blk)
{
- assert(blk->public.throttle_state);
+ assert(blk_get_public(blk)->throttle_group_member.throttle_state);
bdrv_drained_begin(blk_bs(blk));
- throttle_group_unregister_blk(blk);
+ throttle_group_unregister_tgm(&blk_get_public(blk)->throttle_group_member);
bdrv_drained_end(blk_bs(blk));
}
/* should be called before blk_set_io_limits if a limit is set */
void blk_io_limits_enable(BlockBackend *blk, const char *group)
{
- assert(!blk->public.throttle_state);
- throttle_group_register_blk(blk, group);
+ BlockBackendPublic *blkp = blk_get_public(blk);
+
+ assert(!blkp->throttle_group_member.throttle_state);
+
+ blkp->throttle_group_member.aio_context = blk_get_aio_context(blk);
+ throttle_group_register_tgm(&blkp->throttle_group_member, group);
}
void blk_io_limits_update_group(BlockBackend *blk, const char *group)
{
+ BlockBackendPublic *blkp = blk_get_public(blk);
/* this BB is not part of any group */
- if (!blk->public.throttle_state) {
+ if (!blkp->throttle_group_member.throttle_state) {
return;
}
/* this BB is a part of the same group than the one we want */
- if (!g_strcmp0(throttle_group_get_name(blk), group)) {
+ if (!g_strcmp0(throttle_group_get_name(&blkp->throttle_group_member),
+ group)) {
return;
}
@@ -1953,8 +1971,9 @@ static void blk_root_drained_begin(BdrvChild *child)
/* Note that blk->root may not be accessible here yet if we are just
* attaching to a BlockDriverState that is drained. Use child instead. */
- if (blk->public.io_limits_disabled++ == 0) {
- throttle_group_restart_blk(blk);
+ if (blk_get_public(blk)->throttle_group_member.io_limits_disabled++ == 0) {
+ BlockBackendPublic *blkp = blk_get_public(blk);
+ throttle_group_restart_tgm(&blkp->throttle_group_member);
}
}
@@ -1963,8 +1982,8 @@ static void blk_root_drained_end(BdrvChild *child)
BlockBackend *blk = child->opaque;
assert(blk->quiesce_counter);
- assert(blk->public.io_limits_disabled);
- --blk->public.io_limits_disabled;
+ assert(blk_get_public(blk)->throttle_group_member.io_limits_disabled);
+ --blk_get_public(blk)->throttle_group_member.io_limits_disabled;
if (--blk->quiesce_counter == 0) {
if (blk->dev_ops && blk->dev_ops->drained_end) {
diff --git a/block/qapi.c b/block/qapi.c
index a40922ea26..d7fc1345df 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -67,10 +67,11 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
info->backing_file_depth = bdrv_get_backing_file_depth(bs);
info->detect_zeroes = bs->detect_zeroes;
- if (blk && blk_get_public(blk)->throttle_state) {
+ if (blk && blk_get_public(blk)->throttle_group_member.throttle_state) {
ThrottleConfig cfg;
+ BlockBackendPublic *blkp = blk_get_public(blk);
- throttle_group_get_config(blk, &cfg);
+ throttle_group_get_config(&blkp->throttle_group_member, &cfg);
info->bps = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
info->bps_rd = cfg.buckets[THROTTLE_BPS_READ].avg;
@@ -118,7 +119,8 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
info->iops_size = cfg.op_size;
info->has_group = true;
- info->group = g_strdup(throttle_group_get_name(blk));
+ info->group =
+ g_strdup(throttle_group_get_name(&blkp->throttle_group_member));
}
info->write_threshold = bdrv_write_threshold_get(bs);
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
index b73e7a800b..d8bf990ccb 100644
--- a/block/throttle-groups.c
+++ b/block/throttle-groups.c
@@ -29,43 +29,6 @@
#include "qemu/thread.h"
#include "sysemu/qtest.h"
-/* The ThrottleGroup structure (with its ThrottleState) is shared
- * among different BlockBackends and it's independent from
- * AioContext, so in order to use it from different threads it needs
- * its own locking.
- *
- * This locking is however handled internally in this file, so it's
- * transparent to outside users.
- *
- * The whole ThrottleGroup structure is private and invisible to
- * outside users, that only use it through its ThrottleState.
- *
- * In addition to the ThrottleGroup structure, BlockBackendPublic has
- * fields that need to be accessed by other members of the group and
- * therefore also need to be protected by this lock. Once a
- * BlockBackend is registered in a group those fields can be accessed
- * by other threads any time.
- *
- * Again, all this is handled internally and is mostly transparent to
- * the outside. The 'throttle_timers' field however has an additional
- * constraint because it may be temporarily invalid (see for example
- * bdrv_set_aio_context()). Therefore in this file a thread will
- * access some other BlockBackend's timers only after verifying that
- * that BlockBackend has throttled requests in the queue.
- */
-typedef struct ThrottleGroup {
- char *name; /* This is constant during the lifetime of the group */
-
- QemuMutex lock; /* This lock protects the following four fields */
- ThrottleState ts;
- QLIST_HEAD(, BlockBackendPublic) head;
- BlockBackend *tokens[2];
- bool any_timer_armed[2];
-
- /* These two are protected by the global throttle_groups_lock */
- unsigned refcount;
- QTAILQ_ENTRY(ThrottleGroup) list;
-} ThrottleGroup;
static QemuMutex throttle_groups_lock;
static QTAILQ_HEAD(, ThrottleGroup) throttle_groups =
@@ -133,114 +96,113 @@ void throttle_group_unref(ThrottleState *ts)
qemu_mutex_unlock(&throttle_groups_lock);
}
-/* Get the name from a BlockBackend's ThrottleGroup. The name (and the pointer)
+/* Get the name from a ThrottleGroupMember's group. The name (and the pointer)
* is guaranteed to remain constant during the lifetime of the group.
*
- * @blk: a BlockBackend that is member of a throttling group
+ * @tgm: a ThrottleGroupMember
* @ret: the name of the group.
*/
-const char *throttle_group_get_name(BlockBackend *blk)
+const char *throttle_group_get_name(ThrottleGroupMember *tgm)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+ ThrottleState *ts = tgm->throttle_state;
+ ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
return tg->name;
}
-/* Return the next BlockBackend in the round-robin sequence, simulating a
- * circular list.
+/* Return the next ThrottleGroupMember in the round-robin sequence, simulating
+ * a circular list.
*
* This assumes that tg->lock is held.
*
- * @blk: the current BlockBackend
- * @ret: the next BlockBackend in the sequence
+ * @tgm: the current ThrottleGroupMember
+ * @ret: the next ThrottleGroupMember in the sequence
*/
-static BlockBackend *throttle_group_next_blk(BlockBackend *blk)
+static ThrottleGroupMember *throttle_group_next_tgm(ThrottleGroupMember *tgm)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleState *ts = blkp->throttle_state;
+ ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
- BlockBackendPublic *next = QLIST_NEXT(blkp, round_robin);
+ ThrottleGroupMember *next = QLIST_NEXT(tgm, round_robin);
if (!next) {
next = QLIST_FIRST(&tg->head);
}
- return blk_by_public(next);
+ return next;
}
/*
- * Return whether a BlockBackend has pending requests.
+ * Return whether a ThrottleGroupMember has pending requests.
*
* This assumes that tg->lock is held.
*
- * @blk: the BlockBackend
- * @is_write: the type of operation (read/write)
- * @ret: whether the BlockBackend has pending requests.
+ * @tgm: the ThrottleGroupMember
+ * @is_write: the type of operation (read/write)
+ * @ret: whether the ThrottleGroupMember has pending requests.
*/
-static inline bool blk_has_pending_reqs(BlockBackend *blk,
+static inline bool tgm_has_pending_reqs(ThrottleGroupMember *tgm,
bool is_write)
{
- const BlockBackendPublic *blkp = blk_get_public(blk);
- return blkp->pending_reqs[is_write];
+ return tgm->pending_reqs[is_write];
}
-/* Return the next BlockBackend in the round-robin sequence with pending I/O
- * requests.
+/* Return the next ThrottleGroupMember in the round-robin sequence with pending
+ * I/O requests.
*
* This assumes that tg->lock is held.
*
- * @blk: the current BlockBackend
+ * @tgm: the current ThrottleGroupMember
* @is_write: the type of operation (read/write)
- * @ret: the next BlockBackend with pending requests, or blk if there is
- * none.
+ * @ret: the next ThrottleGroupMember with pending requests, or tgm if
+ * there is none.
*/
-static BlockBackend *next_throttle_token(BlockBackend *blk, bool is_write)
+static ThrottleGroupMember *next_throttle_token(ThrottleGroupMember *tgm,
+ bool is_write)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
- BlockBackend *token, *start;
+ ThrottleState *ts = tgm->throttle_state;
+ ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+ ThrottleGroupMember *token, *start;
start = token = tg->tokens[is_write];
/* get next bs round in round robin style */
- token = throttle_group_next_blk(token);
- while (token != start && !blk_has_pending_reqs(token, is_write)) {
- token = throttle_group_next_blk(token);
+ token = throttle_group_next_tgm(token);
+ while (token != start && !tgm_has_pending_reqs(token, is_write)) {
+ token = throttle_group_next_tgm(token);
}
/* If no IO are queued for scheduling on the next round robin token
- * then decide the token is the current bs because chances are
- * the current bs get the current request queued.
+ * then decide the token is the current TGM because chances are
+ * the current TGM get the current request queued.
*/
- if (token == start && !blk_has_pending_reqs(token, is_write)) {
- token = blk;
+ if (token == start && !tgm_has_pending_reqs(token, is_write)) {
+ token = tgm;
}
- /* Either we return the original BB, or one with pending requests */
- assert(token == blk || blk_has_pending_reqs(token, is_write));
+ /* Either we return the original TGM, or one with pending requests */
+ assert(token == tgm || tgm_has_pending_reqs(token, is_write));
return token;
}
-/* Check if the next I/O request for a BlockBackend needs to be throttled or
- * not. If there's no timer set in this group, set one and update the token
- * accordingly.
+/* Check if the next I/O request for a ThrottleGroupMember needs to be
+ * throttled or not. If there's no timer set in this group, set one and update
+ * the token accordingly.
*
* This assumes that tg->lock is held.
*
- * @blk: the current BlockBackend
+ * @tgm: the current ThrottleGroupMember
* @is_write: the type of operation (read/write)
* @ret: whether the I/O request needs to be throttled or not
*/
-static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
+static bool throttle_group_schedule_timer(ThrottleGroupMember *tgm,
+ bool is_write)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleState *ts = blkp->throttle_state;
- ThrottleTimers *tt = &blkp->throttle_timers;
+ ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+ ThrottleTimers *tt = &tgm->throttle_timers;
bool must_wait;
- if (blkp->io_limits_disabled) {
+ if (tgm->io_limits_disabled) {
return false;
}
@@ -251,9 +213,9 @@ static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
must_wait = throttle_schedule_timer(ts, tt, is_write);
- /* If a timer just got armed, set blk as the current token */
+ /* If a timer just got armed, set tgm as the current token */
if (must_wait) {
- tg->tokens[is_write] = blk;
+ tg->tokens[is_write] = tgm;
tg->any_timer_armed[is_write] = true;
}
@@ -264,19 +226,19 @@ static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
*
* This assumes that tg->lock is held.
*
- * @blk: the current BlockBackend
+ * @tgm: the current ThrottleGroupMember
* @is_write: the type of operation (read/write)
*/
-static void schedule_next_request(BlockBackend *blk, bool is_write)
+static void schedule_next_request(ThrottleGroupMember *tgm, bool is_write)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+ ThrottleState *ts = tgm->throttle_state;
+ ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
bool must_wait;
- BlockBackend *token;
+ ThrottleGroupMember *token;
/* Check if there's any pending request to schedule next */
- token = next_throttle_token(blk, is_write);
- if (!blk_has_pending_reqs(token, is_write)) {
+ token = next_throttle_token(tgm, is_write);
+ if (!tgm_has_pending_reqs(token, is_write)) {
return;
}
@@ -285,12 +247,12 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
/* If it doesn't have to wait, queue it for immediate execution */
if (!must_wait) {
- /* Give preference to requests from the current blk */
+ /* Give preference to requests from the current tgm */
if (qemu_in_coroutine() &&
- qemu_co_queue_next(&blkp->throttled_reqs[is_write])) {
- token = blk;
+ qemu_co_queue_next(&tgm->throttled_reqs[is_write])) {
+ token = tgm;
} else {
- ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
+ ThrottleTimers *tt = &token->throttle_timers;
int64_t now = qemu_clock_get_ns(tt->clock_type);
timer_mod(tt->timers[is_write], now + 1);
tg->any_timer_armed[is_write] = true;
@@ -299,71 +261,66 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
}
}
-/* Check if an I/O request needs to be throttled, wait and set a timer
- * if necessary, and schedule the next request using a round robin
- * algorithm.
+/* Check if an I/O request needs to be throttled, wait and set a timer if
+ * necessary, and schedule the next request using a round robin algorithm.
*
- * @blk: the current BlockBackend
+ * @tgm: the current ThrottleGroupMember
* @bytes: the number of bytes for this I/O
* @is_write: the type of operation (read/write)
*/
-void coroutine_fn throttle_group_co_io_limits_intercept(BlockBackend *blk,
+void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
unsigned int bytes,
bool is_write)
{
bool must_wait;
- BlockBackend *token;
-
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+ ThrottleGroupMember *token;
+ ThrottleState *ts = tgm->throttle_state;
+ ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
qemu_mutex_lock(&tg->lock);
/* First we check if this I/O has to be throttled. */
- token = next_throttle_token(blk, is_write);
+ token = next_throttle_token(tgm, is_write);
must_wait = throttle_group_schedule_timer(token, is_write);
/* Wait if there's a timer set or queued requests of this type */
- if (must_wait || blkp->pending_reqs[is_write]) {
- blkp->pending_reqs[is_write]++;
+ if (must_wait || tgm->pending_reqs[is_write]) {
+ tgm->pending_reqs[is_write]++;
qemu_mutex_unlock(&tg->lock);
- qemu_co_queue_wait(&blkp->throttled_reqs[is_write], NULL);
+ qemu_co_queue_wait(&tgm->throttled_reqs[is_write], NULL);
qemu_mutex_lock(&tg->lock);
- blkp->pending_reqs[is_write]--;
+ tgm->pending_reqs[is_write]--;
}
/* The I/O will be executed, so do the accounting */
- throttle_account(blkp->throttle_state, is_write, bytes);
+ throttle_account(tgm->throttle_state, is_write, bytes);
/* Schedule the next request */
- schedule_next_request(blk, is_write);
+ schedule_next_request(tgm, is_write);
qemu_mutex_unlock(&tg->lock);
}
-void throttle_group_restart_blk(BlockBackend *blk)
+void throttle_group_restart_tgm(ThrottleGroupMember *tgm)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
int i;
for (i = 0; i < 2; i++) {
- while (qemu_co_enter_next(&blkp->throttled_reqs[i])) {
+ while (qemu_co_enter_next(&tgm->throttled_reqs[i])) {
;
}
}
}
-/* Update the throttle configuration for a particular group. Similar
- * to throttle_config(), but guarantees atomicity within the
- * throttling group.
+/* Update the throttle configuration for a particular group. Similar to
+ * throttle_config(), but guarantees atomicity within the throttling group.
*
- * @blk: a BlockBackend that is a member of the group
- * @cfg: the configuration to set
+ * @tgm: a ThrottleGroupMember that is a member of the group
+ * @cfg: the configuration to set
*/
-void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
+void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleTimers *tt = &blkp->throttle_timers;
- ThrottleState *ts = blkp->throttle_state;
+ ThrottleTimers *tt = &tgm->throttle_timers;
+ ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
qemu_mutex_lock(&tg->lock);
/* throttle_config() cancels the timers */
@@ -376,37 +333,34 @@ void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
throttle_config(ts, tt, cfg);
qemu_mutex_unlock(&tg->lock);
- qemu_co_enter_next(&blkp->throttled_reqs[0]);
- qemu_co_enter_next(&blkp->throttled_reqs[1]);
+ qemu_co_enter_next(&tgm->throttled_reqs[0]);
+ qemu_co_enter_next(&tgm->throttled_reqs[1]);
}
/* Get the throttle configuration from a particular group. Similar to
- * throttle_get_config(), but guarantees atomicity within the
- * throttling group.
+ * throttle_get_config(), but guarantees atomicity within the throttling group.
*
- * @blk: a BlockBackend that is a member of the group
- * @cfg: the configuration will be written here
+ * @tgm: a ThrottleGroupMember that is a member of the group
+ * @cfg: the configuration will be written here
*/
-void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg)
+void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleState *ts = blkp->throttle_state;
+ ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
qemu_mutex_lock(&tg->lock);
throttle_get_config(ts, cfg);
qemu_mutex_unlock(&tg->lock);
}
-/* ThrottleTimers callback. This wakes up a request that was waiting
- * because it had been throttled.
+/* ThrottleTimers callback. This wakes up a request that was waiting because it
+ * had been throttled.
*
- * @blk: the BlockBackend whose request had been throttled
+ * @tgm: the ThrottleGroupMember whose request had been throttled
* @is_write: the type of operation (read/write)
*/
-static void timer_cb(BlockBackend *blk, bool is_write)
+static void timer_cb(ThrottleGroupMember *tgm, bool is_write)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleState *ts = blkp->throttle_state;
+ ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
bool empty_queue;
@@ -416,15 +370,15 @@ static void timer_cb(BlockBackend *blk, bool is_write)
qemu_mutex_unlock(&tg->lock);
/* Run the request that was waiting for this timer */
- aio_context_acquire(blk_get_aio_context(blk));
- empty_queue = !qemu_co_enter_next(&blkp->throttled_reqs[is_write]);
- aio_context_release(blk_get_aio_context(blk));
+ aio_context_acquire(tgm->aio_context);
+ empty_queue = !qemu_co_enter_next(&tgm->throttled_reqs[is_write]);
+ aio_context_release(tgm->aio_context);
/* If the request queue was empty then we have to take care of
* scheduling the next one */
if (empty_queue) {
qemu_mutex_lock(&tg->lock);
- schedule_next_request(blk, is_write);
+ schedule_next_request(tgm, is_write);
qemu_mutex_unlock(&tg->lock);
}
}
@@ -439,17 +393,17 @@ static void write_timer_cb(void *opaque)
timer_cb(opaque, true);
}
-/* Register a BlockBackend in the throttling group, also initializing its
- * timers and updating its throttle_state pointer to point to it. If a
+/* Register a ThrottleGroupMember from the throttling group, also initializing
+ * its timers and updating its throttle_state pointer to point to it. If a
* throttling group with that name does not exist yet, it will be created.
*
- * @blk: the BlockBackend to insert
+ * @tgm: the ThrottleGroupMember to insert
* @groupname: the name of the group
*/
-void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
+void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+ const char *groupname)
{
int i;
- BlockBackendPublic *blkp = blk_get_public(blk);
ThrottleState *ts = throttle_group_incref(groupname);
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
int clock_type = QEMU_CLOCK_REALTIME;
@@ -459,67 +413,68 @@ void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
clock_type = QEMU_CLOCK_VIRTUAL;
}
- blkp->throttle_state = ts;
+ tgm->throttle_state = ts;
qemu_mutex_lock(&tg->lock);
- /* If the ThrottleGroup is new set this BlockBackend as the token */
+ /* If the ThrottleGroup is new set this ThrottleGroupMember as the token */
for (i = 0; i < 2; i++) {
if (!tg->tokens[i]) {
- tg->tokens[i] = blk;
+ tg->tokens[i] = tgm;
}
}
- QLIST_INSERT_HEAD(&tg->head, blkp, round_robin);
+ QLIST_INSERT_HEAD(&tg->head, tgm, round_robin);
- throttle_timers_init(&blkp->throttle_timers,
- blk_get_aio_context(blk),
+ throttle_timers_init(&tgm->throttle_timers,
+ tgm->aio_context,
clock_type,
read_timer_cb,
write_timer_cb,
- blk);
+ tgm);
qemu_mutex_unlock(&tg->lock);
}
-/* Unregister a BlockBackend from its group, removing it from the list,
+/* Unregister a ThrottleGroupMember from its group, removing it from the list,
* destroying the timers and setting the throttle_state pointer to NULL.
*
- * The BlockBackend must not have pending throttled requests, so the caller has
- * to drain them first.
+ * The ThrottleGroupMember must not have pending throttled requests, so the
+ * caller has to drain them first.
*
* The group will be destroyed if it's empty after this operation.
*
- * @blk: the BlockBackend to remove
+ * @tgm the ThrottleGroupMember to remove
*/
-void throttle_group_unregister_blk(BlockBackend *blk)
+void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
{
- BlockBackendPublic *blkp = blk_get_public(blk);
- ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+ ThrottleState *ts = tgm->throttle_state;
+ ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+ ThrottleGroupMember *token;
int i;
- assert(blkp->pending_reqs[0] == 0 && blkp->pending_reqs[1] == 0);
- assert(qemu_co_queue_empty(&blkp->throttled_reqs[0]));
- assert(qemu_co_queue_empty(&blkp->throttled_reqs[1]));
+ assert(tgm->pending_reqs[0] == 0 && tgm->pending_reqs[1] == 0);
+ assert(qemu_co_queue_empty(&tgm->throttled_reqs[0]));
+ assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
qemu_mutex_lock(&tg->lock);
for (i = 0; i < 2; i++) {
- if (tg->tokens[i] == blk) {
- BlockBackend *token = throttle_group_next_blk(blk);
- /* Take care of the case where this is the last blk in the group */
- if (token == blk) {
+ if (tg->tokens[i] == tgm) {
+ token = throttle_group_next_tgm(tgm);
+ /* Take care of the case where this is the last tgm in the group */
+ if (token == tgm) {
token = NULL;
}
tg->tokens[i] = token;
}
}
- /* remove the current blk from the list */
- QLIST_REMOVE(blkp, round_robin);
- throttle_timers_destroy(&blkp->throttle_timers);
+ /* remove the current tgm from the list */
+ QLIST_REMOVE(tgm, round_robin);
+ throttle_timers_destroy(&tgm->throttle_timers);
qemu_mutex_unlock(&tg->lock);
throttle_group_unref(&tg->ts);
- blkp->throttle_state = NULL;
+ tgm->throttle_state = NULL;
}
static void throttle_groups_init(void)
diff --git a/blockdev.c b/blockdev.c
index c63f4e82c7..ad8cec8008 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2706,7 +2706,7 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
if (throttle_enabled(&cfg)) {
/* Enable I/O limits if they're not enabled yet, otherwise
* just update the throttling group. */
- if (!blk_get_public(blk)->throttle_state) {
+ if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
blk_io_limits_enable(blk,
arg->has_group ? arg->group :
arg->has_device ? arg->device :
@@ -2716,7 +2716,7 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
}
/* Set the new throttling configuration */
blk_set_io_limits(blk, &cfg);
- } else if (blk_get_public(blk)->throttle_state) {
+ } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
/* If all throttling settings are set to 0, disable I/O limits */
blk_io_limits_disable(blk);
}
diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
index d983d34074..487b2da461 100644
--- a/include/block/throttle-groups.h
+++ b/include/block/throttle-groups.h
@@ -28,19 +28,20 @@
#include "qemu/throttle.h"
#include "block/block_int.h"
-const char *throttle_group_get_name(BlockBackend *blk);
+const char *throttle_group_get_name(ThrottleGroupMember *tgm);
ThrottleState *throttle_group_incref(const char *name);
void throttle_group_unref(ThrottleState *ts);
-void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg);
-void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg);
+void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
+void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
-void throttle_group_register_blk(BlockBackend *blk, const char *groupname);
-void throttle_group_unregister_blk(BlockBackend *blk);
-void throttle_group_restart_blk(BlockBackend *blk);
+void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+ const char *groupname);
+void throttle_group_unregister_tgm(ThrottleGroupMember *tgm);
+void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
-void coroutine_fn throttle_group_co_io_limits_intercept(BlockBackend *blk,
+void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
unsigned int bytes,
bool is_write);
diff --git a/include/qemu/throttle.h b/include/qemu/throttle.h
index 9109657609..8b67fbfdfb 100644
--- a/include/qemu/throttle.h
+++ b/include/qemu/throttle.h
@@ -27,6 +27,9 @@
#include "qemu-common.h"
#include "qemu/timer.h"
+#include "qemu/queue.h"
+#include "qemu/thread.h"
+#include "qemu/coroutine.h"
#define THROTTLE_VALUE_MAX 1000000000000000LL
@@ -153,4 +156,65 @@ bool throttle_schedule_timer(ThrottleState *ts,
void throttle_account(ThrottleState *ts, bool is_write, uint64_t size);
+/* The ThrottleGroup structure (with its ThrottleState) is shared among
+ * different ThrottleGroupMembers and it's independent from AioContext, so in
+ * order to use it from different threads it needs its own locking.
+ *
+ * This locking is however handled internally in block/throttle-groups.c so
+ * it's transparent to outside users.
+ *
+ * The whole ThrottleGroup structure is private and invisible to outside users,
+ * that only use it through its ThrottleState.
+ *
+ * In addition to the ThrottleGroup structure, ThrottleGroupMember has fields
+ * that need to be accessed by other members of the group and therefore also
+ * need to be protected by this lock. Once a ThrottleGroupMember is registered
+ * in a group those fields can be accessed by other threads any time.
+ *
+ * Again, all this is handled internally in block/throttle-groups.c and is
+ * mostly transparent to the outside. The 'throttle_timers' field however has
+ * an additional constraint because it may be temporarily invalid (see for
+ * example bdrv_set_aio_context()). Therefore block/throttle-groups.c will
+ * access some other ThrottleGroupMember's timers only after verifying that
+ * ThrottleGroupMember has throttled requests in the queue.
+ */
+
+typedef struct ThrottleGroup {
+ char *name; /* This is constant during the lifetime of the group */
+
+ QemuMutex lock; /* This lock protects the following four fields */
+ ThrottleState ts;
+ QLIST_HEAD(, ThrottleGroupMember) head;
+ struct ThrottleGroupMember *tokens[2];
+ bool any_timer_armed[2];
+
+ /* These two are protected by the global throttle_groups_lock */
+ unsigned refcount;
+ QTAILQ_ENTRY(ThrottleGroup) list;
+} ThrottleGroup;
+
+/* The ThrottleGroupMember structure indicates membership in a ThrottleGroup
+ * and holds related data.
+ */
+
+typedef struct ThrottleGroupMember {
+ AioContext *aio_context;
+ /* I/O throttling has its own locking, but also some fields are
+ * protected by the AioContext lock.
+ */
+
+ /* Protected by AioContext lock. */
+ CoQueue throttled_reqs[2];
+
+ /* Nonzero if the I/O limits are currently being ignored; generally
+ * it is zero. */
+ unsigned int io_limits_disabled;
+
+ ThrottleState *throttle_state;
+ ThrottleTimers throttle_timers;
+ unsigned pending_reqs[2];
+ QLIST_ENTRY(ThrottleGroupMember) round_robin;
+
+} ThrottleGroupMember;
+
#endif
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 840ad6134c..4fec907b7f 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -70,26 +70,10 @@ typedef struct BlockDevOps {
/* This struct is embedded in (the private) BlockBackend struct and contains
* fields that must be public. This is in particular for QLIST_ENTRY() and
- * friends so that BlockBackends can be kept in lists outside block-backend.c */
+ * friends so that BlockBackends can be kept in lists outside block-backend.c
+ * */
typedef struct BlockBackendPublic {
- /* I/O throttling has its own locking, but also some fields are
- * protected by the AioContext lock.
- */
-
- /* Protected by AioContext lock. */
- CoQueue throttled_reqs[2];
-
- /* Nonzero if the I/O limits are currently being ignored; generally
- * it is zero. */
- 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(BlockBackendPublic) round_robin;
+ ThrottleGroupMember throttle_group_member;
} BlockBackendPublic;
BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm);
diff --git a/tests/test-throttle.c b/tests/test-throttle.c
index a9201b1fea..0f95da2592 100644
--- a/tests/test-throttle.c
+++ b/tests/test-throttle.c
@@ -592,6 +592,7 @@ static void test_groups(void)
ThrottleConfig cfg1, cfg2;
BlockBackend *blk1, *blk2, *blk3;
BlockBackendPublic *blkp1, *blkp2, *blkp3;
+ ThrottleGroupMember *tgm1, *tgm2, *tgm3;
/* No actual I/O is performed on these devices */
blk1 = blk_new(0, BLK_PERM_ALL);
@@ -602,21 +603,25 @@ static void test_groups(void)
blkp2 = blk_get_public(blk2);
blkp3 = blk_get_public(blk3);
- g_assert(blkp1->throttle_state == NULL);
- g_assert(blkp2->throttle_state == NULL);
- g_assert(blkp3->throttle_state == NULL);
+ tgm1 = &blkp1->throttle_group_member;
+ tgm2 = &blkp2->throttle_group_member;
+ tgm3 = &blkp3->throttle_group_member;
- throttle_group_register_blk(blk1, "bar");
- throttle_group_register_blk(blk2, "foo");
- throttle_group_register_blk(blk3, "bar");
+ g_assert(tgm1->throttle_state == NULL);
+ g_assert(tgm2->throttle_state == NULL);
+ g_assert(tgm3->throttle_state == NULL);
- g_assert(blkp1->throttle_state != NULL);
- g_assert(blkp2->throttle_state != NULL);
- g_assert(blkp3->throttle_state != NULL);
+ throttle_group_register_tgm(tgm1, "bar");
+ throttle_group_register_tgm(tgm2, "foo");
+ throttle_group_register_tgm(tgm3, "bar");
- g_assert(!strcmp(throttle_group_get_name(blk1), "bar"));
- g_assert(!strcmp(throttle_group_get_name(blk2), "foo"));
- g_assert(blkp1->throttle_state == blkp3->throttle_state);
+ g_assert(tgm1->throttle_state != NULL);
+ g_assert(tgm2->throttle_state != NULL);
+ g_assert(tgm3->throttle_state != NULL);
+
+ g_assert(!strcmp(throttle_group_get_name(tgm1), "bar"));
+ g_assert(!strcmp(throttle_group_get_name(tgm2), "foo"));
+ g_assert(tgm1->throttle_state == tgm3->throttle_state);
/* Setting the config of a group member affects the whole group */
throttle_config_init(&cfg1);
@@ -624,29 +629,29 @@ static void test_groups(void)
cfg1.buckets[THROTTLE_BPS_WRITE].avg = 285000;
cfg1.buckets[THROTTLE_OPS_READ].avg = 20000;
cfg1.buckets[THROTTLE_OPS_WRITE].avg = 12000;
- throttle_group_config(blk1, &cfg1);
+ throttle_group_config(tgm1, &cfg1);
- throttle_group_get_config(blk1, &cfg1);
- throttle_group_get_config(blk3, &cfg2);
+ throttle_group_get_config(tgm1, &cfg1);
+ throttle_group_get_config(tgm3, &cfg2);
g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
cfg2.buckets[THROTTLE_BPS_READ].avg = 4547;
cfg2.buckets[THROTTLE_BPS_WRITE].avg = 1349;
cfg2.buckets[THROTTLE_OPS_READ].avg = 123;
cfg2.buckets[THROTTLE_OPS_WRITE].avg = 86;
- throttle_group_config(blk3, &cfg1);
+ throttle_group_config(tgm3, &cfg1);
- throttle_group_get_config(blk1, &cfg1);
- throttle_group_get_config(blk3, &cfg2);
+ throttle_group_get_config(tgm1, &cfg1);
+ throttle_group_get_config(tgm3, &cfg2);
g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
- throttle_group_unregister_blk(blk1);
- throttle_group_unregister_blk(blk2);
- throttle_group_unregister_blk(blk3);
+ throttle_group_unregister_tgm(tgm1);
+ throttle_group_unregister_tgm(tgm2);
+ throttle_group_unregister_tgm(tgm3);
- g_assert(blkp1->throttle_state == NULL);
- g_assert(blkp2->throttle_state == NULL);
- g_assert(blkp3->throttle_state == NULL);
+ g_assert(tgm1->throttle_state == NULL);
+ g_assert(tgm2->throttle_state == NULL);
+ g_assert(tgm3->throttle_state == NULL);
}
int main(int argc, char **argv)
diff --git a/util/throttle.c b/util/throttle.c
index 3570ed25fc..ec1fe73dbd 100644
--- a/util/throttle.c
+++ b/util/throttle.c
@@ -185,6 +185,9 @@ static bool throttle_compute_timer(ThrottleState *ts,
void throttle_timers_attach_aio_context(ThrottleTimers *tt,
AioContext *new_context)
{
+ ThrottleGroupMember *tgm = container_of(tt, ThrottleGroupMember, throttle_timers);
+ tgm->aio_context = new_context;
+
tt->timers[0] = aio_timer_new(new_context, tt->clock_type, SCALE_NS,
tt->read_timer_cb, tt->timer_opaque);
tt->timers[1] = aio_timer_new(new_context, tt->clock_type, SCALE_NS,
@@ -241,6 +244,8 @@ static void throttle_timer_destroy(QEMUTimer **timer)
/* Remove timers from event loop */
void throttle_timers_detach_aio_context(ThrottleTimers *tt)
{
+ ThrottleGroupMember *tgm = container_of(tt, ThrottleGroupMember, throttle_timers);
+ tgm->aio_context = NULL;
int i;
for (i = 0; i < 2; i++) {
--
2.11.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH RFC v2 2/2] block: add throttle block filter driver
2017-06-11 1:14 [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver Manos Pitsidianakis
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember Manos Pitsidianakis
@ 2017-06-11 1:14 ` Manos Pitsidianakis
2017-06-11 1:28 ` [Qemu-devel] [PATCH RFC v2 0/2] IO throttling " no-reply
2 siblings, 0 replies; 7+ messages in thread
From: Manos Pitsidianakis @ 2017-06-11 1:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Alberto Garcia, Kevin Wolf, Stefan Hajnoczi, qemu-block
block/throttle.c uses existing I/O throttle infrastructure inside a
block filter driver. I/O operations are intercepted in the filter's
read/write coroutines, and referred to block/throttle-groups.c
The driver can be used with the command
-drive driver=throttle,file.filename=foo.qcow2,iops-total=...
The configuration flags and semantics are identical to the hardcoded
throttling ones.
Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
---
block/Makefile.objs | 1 +
block/throttle-groups.c | 16 +-
block/throttle.c | 364 ++++++++++++++++++++++++++++++++++++++++
include/block/throttle-groups.h | 6 +-
include/qemu/throttle-options.h | 60 ++++---
5 files changed, 419 insertions(+), 28 deletions(-)
create mode 100644 block/throttle.c
diff --git a/block/Makefile.objs b/block/Makefile.objs
index ea955302c8..bb811a4d01 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -25,6 +25,7 @@ block-obj-y += accounting.o dirty-bitmap.o
block-obj-y += write-threshold.o
block-obj-y += backup.o
block-obj-$(CONFIG_REPLICATION) += replication.o
+block-obj-y += throttle.o
block-obj-y += crypto.o
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
index d8bf990ccb..9008b73cc9 100644
--- a/block/throttle-groups.c
+++ b/block/throttle-groups.c
@@ -29,11 +29,11 @@
#include "qemu/thread.h"
#include "sysemu/qtest.h"
-
-static QemuMutex throttle_groups_lock;
-static QTAILQ_HEAD(, ThrottleGroup) throttle_groups =
+QemuMutex throttle_groups_lock;
+QTAILQ_HEAD(throttle_groups_head, ThrottleGroup) throttle_groups =
QTAILQ_HEAD_INITIALIZER(throttle_groups);
+
/* Increments the reference count of a ThrottleGroup given its name.
*
* If no ThrottleGroup is found with the given name a new one is
@@ -117,7 +117,7 @@ const char *throttle_group_get_name(ThrottleGroupMember *tgm)
* @tgm: the current ThrottleGroupMember
* @ret: the next ThrottleGroupMember in the sequence
*/
-static ThrottleGroupMember *throttle_group_next_tgm(ThrottleGroupMember *tgm)
+ThrottleGroupMember *throttle_group_next_tgm(ThrottleGroupMember *tgm)
{
ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
@@ -229,7 +229,7 @@ static bool throttle_group_schedule_timer(ThrottleGroupMember *tgm,
* @tgm: the current ThrottleGroupMember
* @is_write: the type of operation (read/write)
*/
-static void schedule_next_request(ThrottleGroupMember *tgm, bool is_write)
+void schedule_next_request(ThrottleGroupMember *tgm, bool is_write)
{
ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
@@ -358,7 +358,7 @@ void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg)
* @tgm: the ThrottleGroupMember whose request had been throttled
* @is_write: the type of operation (read/write)
*/
-static void timer_cb(ThrottleGroupMember *tgm, bool is_write)
+void timer_cb(ThrottleGroupMember *tgm, bool is_write)
{
ThrottleState *ts = tgm->throttle_state;
ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
@@ -383,12 +383,12 @@ static void timer_cb(ThrottleGroupMember *tgm, bool is_write)
}
}
-static void read_timer_cb(void *opaque)
+void read_timer_cb(void *opaque)
{
timer_cb(opaque, false);
}
-static void write_timer_cb(void *opaque)
+void write_timer_cb(void *opaque)
{
timer_cb(opaque, true);
}
diff --git a/block/throttle.c b/block/throttle.c
new file mode 100644
index 0000000000..6be5d3de59
--- /dev/null
+++ b/block/throttle.c
@@ -0,0 +1,364 @@
+/*
+ * QEMU block throttling filter driver 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/>.
+ */
+
+#include "qemu/osdep.h"
+#include "block/throttle-groups.h"
+#include "qemu/throttle-options.h"
+#include "qapi/error.h"
+
+
+static QemuOptsList throttle_opts = {
+ .name = "throttle",
+ .head = QTAILQ_HEAD_INITIALIZER(throttle_opts.head),
+ .desc = {
+ {
+ .name = QEMU_OPT_IOPS_TOTAL,
+ .type = QEMU_OPT_NUMBER,
+ .help = "limit total I/O operations per second",
+ },{
+ .name = QEMU_OPT_IOPS_READ,
+ .type = QEMU_OPT_NUMBER,
+ .help = "limit read operations per second",
+ },{
+ .name = QEMU_OPT_IOPS_WRITE,
+ .type = QEMU_OPT_NUMBER,
+ .help = "limit write operations per second",
+ },{
+ .name = QEMU_OPT_BPS_TOTAL,
+ .type = QEMU_OPT_NUMBER,
+ .help = "limit total bytes per second",
+ },{
+ .name = QEMU_OPT_BPS_READ,
+ .type = QEMU_OPT_NUMBER,
+ .help = "limit read bytes per second",
+ },{
+ .name = QEMU_OPT_BPS_WRITE,
+ .type = QEMU_OPT_NUMBER,
+ .help = "limit write bytes per second",
+ },{
+ .name = QEMU_OPT_IOPS_TOTAL_MAX,
+ .type = QEMU_OPT_NUMBER,
+ .help = "I/O operations burst",
+ },{
+ .name = QEMU_OPT_IOPS_READ_MAX,
+ .type = QEMU_OPT_NUMBER,
+ .help = "I/O operations read burst",
+ },{
+ .name = QEMU_OPT_IOPS_WRITE_MAX,
+ .type = QEMU_OPT_NUMBER,
+ .help = "I/O operations write burst",
+ },{
+ .name = QEMU_OPT_BPS_TOTAL_MAX,
+ .type = QEMU_OPT_NUMBER,
+ .help = "total bytes burst",
+ },{
+ .name = QEMU_OPT_BPS_READ_MAX,
+ .type = QEMU_OPT_NUMBER,
+ .help = "total bytes read burst",
+ },{
+ .name = QEMU_OPT_BPS_WRITE_MAX,
+ .type = QEMU_OPT_NUMBER,
+ .help = "total bytes write burst",
+ },{
+ .name = QEMU_OPT_IOPS_TOTAL_MAX_LENGTH,
+ .type = QEMU_OPT_NUMBER,
+ .help = "length of the iopstotalmax burst period, in seconds",
+ },{
+ .name = QEMU_OPT_IOPS_READ_MAX_LENGTH,
+ .type = QEMU_OPT_NUMBER,
+ .help = "length of the iopsreadmax burst period, in seconds",
+ },{
+ .name = QEMU_OPT_IOPS_WRITE_MAX_LENGTH,
+ .type = QEMU_OPT_NUMBER,
+ .help = "length of the iopswritemax burst period, in seconds",
+ },{
+ .name = QEMU_OPT_BPS_TOTAL_MAX_LENGTH,
+ .type = QEMU_OPT_NUMBER,
+ .help = "length of the bpstotalmax burst period, in seconds",
+ },{
+ .name = QEMU_OPT_BPS_READ_MAX_LENGTH,
+ .type = QEMU_OPT_NUMBER,
+ .help = "length of the bpsreadmax burst period, in seconds",
+ },{
+ .name = QEMU_OPT_BPS_WRITE_MAX_LENGTH,
+ .type = QEMU_OPT_NUMBER,
+ .help = "length of the bpswritemax burst period, in seconds",
+ },{
+ .name = QEMU_OPT_IOPS_SIZE,
+ .type = QEMU_OPT_NUMBER,
+ .help = "when limiting by iops max size of an I/O in bytes",
+ },
+ {
+ .name = QEMU_OPT_THROTTLE_GROUP_NAME,
+ .type = QEMU_OPT_STRING,
+ .help = "throttle group name",
+ },
+ { /* end of list */ }
+ },
+};
+
+static int throttle_open(BlockDriverState *bs, QDict *options,
+ int flags, Error **errp)
+{
+ int ret = 0;
+ ThrottleGroupMember *tgm = bs->opaque;
+ Error *local_err = NULL;
+ QemuOpts *opts = NULL;
+ const char *group_name = NULL;
+
+ bs->file = bdrv_open_child(NULL, options, "file",
+ bs, &child_file, false, &local_err);
+
+ if (local_err) {
+ ret = -EINVAL;
+ error_propagate(errp, local_err);
+ return ret;
+ }
+
+ qdict_flatten(options);
+ opts = qemu_opts_create(&throttle_opts, NULL, 0, &error_abort);
+ qemu_opts_absorb_qdict(opts, options, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto fin;
+ }
+
+ group_name = qemu_opt_get(opts, QEMU_OPT_THROTTLE_GROUP_NAME);
+ if (!group_name) {
+ group_name = bdrv_get_device_or_node_name(bs);
+ if (!strlen(group_name)) {
+ error_setg(&local_err,
+ "A group name must be specified for this device.");
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto fin;
+ }
+ }
+
+ tgm->aio_context = bdrv_get_aio_context(bs);
+ throttle_group_register_tgm(tgm, group_name);
+ ThrottleState *ts = tgm->throttle_state;
+ ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+ ThrottleConfig *throttle_cfg = &ts->cfg;
+
+
+ qemu_mutex_lock(&tg->lock);
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_TOTAL)) {
+ throttle_cfg->buckets[THROTTLE_BPS_TOTAL].avg =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_TOTAL, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_READ)) {
+ throttle_cfg->buckets[THROTTLE_BPS_READ].avg =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_READ, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_WRITE)) {
+ throttle_cfg->buckets[THROTTLE_BPS_WRITE].avg =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_WRITE, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_TOTAL)) {
+ throttle_cfg->buckets[THROTTLE_OPS_TOTAL].avg =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_TOTAL, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_READ)) {
+ throttle_cfg->buckets[THROTTLE_OPS_READ].avg =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_READ, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_WRITE)) {
+ throttle_cfg->buckets[THROTTLE_OPS_WRITE].avg =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_WRITE, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_TOTAL_MAX)) {
+ throttle_cfg->buckets[THROTTLE_BPS_TOTAL].max =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_TOTAL_MAX, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_READ_MAX)) {
+ throttle_cfg->buckets[THROTTLE_BPS_READ].max =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_READ_MAX, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_WRITE_MAX)) {
+ throttle_cfg->buckets[THROTTLE_BPS_WRITE].max =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_WRITE_MAX, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_TOTAL_MAX)) {
+ throttle_cfg->buckets[THROTTLE_OPS_TOTAL].max =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_TOTAL_MAX, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_READ_MAX)) {
+ throttle_cfg->buckets[THROTTLE_OPS_READ].max =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_READ_MAX, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_WRITE_MAX)) {
+ throttle_cfg->buckets[THROTTLE_OPS_WRITE].max =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_WRITE_MAX, 0);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_TOTAL_MAX_LENGTH)) {
+ throttle_cfg->buckets[THROTTLE_BPS_TOTAL].burst_length =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_TOTAL_MAX_LENGTH, 1);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_READ_MAX_LENGTH)) {
+ throttle_cfg->buckets[THROTTLE_BPS_READ].burst_length =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_READ_MAX_LENGTH, 1);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_BPS_WRITE_MAX_LENGTH)) {
+ throttle_cfg->buckets[THROTTLE_BPS_WRITE].burst_length =
+ qemu_opt_get_number(opts, QEMU_OPT_BPS_WRITE_MAX_LENGTH, 1);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_TOTAL_MAX_LENGTH)) {
+ throttle_cfg->buckets[THROTTLE_OPS_TOTAL].burst_length =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_TOTAL_MAX_LENGTH, 1);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_READ_MAX_LENGTH)) {
+ throttle_cfg->buckets[THROTTLE_OPS_READ].burst_length =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_READ_MAX_LENGTH, 1);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_WRITE_MAX_LENGTH)) {
+ throttle_cfg->buckets[THROTTLE_OPS_WRITE].burst_length =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_WRITE_MAX_LENGTH, 1);
+ }
+ if (qemu_opt_get(opts, QEMU_OPT_IOPS_SIZE)) {
+ throttle_cfg->op_size =
+ qemu_opt_get_number(opts, QEMU_OPT_IOPS_SIZE, 0);
+ }
+
+ if (!throttle_is_valid(throttle_cfg, &local_err)) {
+ error_propagate(errp, local_err);
+ throttle_group_unregister_tgm(tgm);
+ ret = -EINVAL;
+ goto fin;
+ }
+
+ qemu_mutex_unlock(&tg->lock);
+
+ qemu_co_queue_init(&tgm->throttled_reqs[0]);
+ qemu_co_queue_init(&tgm->throttled_reqs[1]);
+
+fin:
+ qemu_opts_del(opts);
+ return ret;
+}
+
+static void throttle_close(BlockDriverState *bs)
+{
+ ThrottleGroupMember *tgm = bs->opaque;
+ throttle_group_unregister_tgm(tgm);
+ return;
+}
+
+
+static int64_t throttle_getlength(BlockDriverState *bs)
+{
+ return bdrv_getlength(bs->file->bs);
+}
+
+
+static int coroutine_fn throttle_co_preadv(BlockDriverState *bs, uint64_t offset,
+ uint64_t bytes, QEMUIOVector *qiov,
+ int flags)
+{
+
+ ThrottleGroupMember *tgm = bs->opaque;
+ throttle_group_co_io_limits_intercept(tgm, bytes, false);
+
+ return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
+}
+
+static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs, uint64_t offset,
+ uint64_t bytes, QEMUIOVector *qiov,
+ int flags)
+{
+ ThrottleGroupMember *tgm = bs->opaque;
+ throttle_group_co_io_limits_intercept(tgm, bytes, true);
+
+ return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
+}
+
+static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
+ int64_t offset, int bytes, BdrvRequestFlags flags)
+{
+ ThrottleGroupMember *tgm = bs->opaque;
+ throttle_group_co_io_limits_intercept(tgm, bytes, true);
+
+ return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
+}
+
+static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
+ int64_t offset, int bytes)
+{
+ ThrottleGroupMember *tgm = bs->opaque;
+ throttle_group_co_io_limits_intercept(tgm, bytes, true);
+
+ return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
+}
+
+static int throttle_co_flush(BlockDriverState *bs)
+{
+ return bdrv_co_flush(bs->file->bs);
+}
+
+static void throttle_detach_aio_context(BlockDriverState *bs)
+{
+ ThrottleGroupMember *tgm = bs->opaque;
+ throttle_timers_detach_aio_context(&tgm->throttle_timers);
+}
+
+static void throttle_attach_aio_context(BlockDriverState *bs,
+ AioContext *new_context)
+{
+ ThrottleGroupMember *tgm = bs->opaque;
+ throttle_timers_attach_aio_context(&tgm->throttle_timers, new_context);
+}
+static BlockDriver bdrv_throttle = {
+ .format_name = "throttle",
+ .protocol_name = "throttle",
+ .instance_size = sizeof(ThrottleGroupMember),
+
+ .bdrv_file_open = throttle_open,
+ .bdrv_close = throttle_close,
+ .bdrv_co_flush = throttle_co_flush,
+
+ .bdrv_child_perm = bdrv_filter_default_perms,
+
+ .bdrv_getlength = throttle_getlength,
+
+ .bdrv_co_preadv = throttle_co_preadv,
+ .bdrv_co_pwritev = throttle_co_pwritev,
+
+ .bdrv_co_pwrite_zeroes = throttle_co_pwrite_zeroes,
+ .bdrv_co_pdiscard = throttle_co_pdiscard,
+
+ .bdrv_recurse_is_first_non_filter = bdrv_recurse_is_first_non_filter,
+
+ .bdrv_attach_aio_context = throttle_attach_aio_context,
+ .bdrv_detach_aio_context = throttle_detach_aio_context,
+
+ .is_filter = true,
+};
+
+static void bdrv_throttle_init(void)
+{
+ bdrv_register(&bdrv_throttle);
+}
+
+block_init(bdrv_throttle_init);
diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
index 487b2da461..67b6c69fe4 100644
--- a/include/block/throttle-groups.h
+++ b/include/block/throttle-groups.h
@@ -44,5 +44,9 @@ void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
unsigned int bytes,
bool is_write);
-
+ThrottleGroupMember *throttle_group_next_tgm(ThrottleGroupMember *tgm);
+void schedule_next_request(struct ThrottleGroupMember *tgm, bool is_write);
+void timer_cb(ThrottleGroupMember *tgm, bool is_write);
+void read_timer_cb(void *opaque);
+void write_timer_cb(void *opaque);
#endif
diff --git a/include/qemu/throttle-options.h b/include/qemu/throttle-options.h
index 3133d1ca40..3528a8f4a2 100644
--- a/include/qemu/throttle-options.h
+++ b/include/qemu/throttle-options.h
@@ -10,81 +10,103 @@
#ifndef THROTTLE_OPTIONS_H
#define THROTTLE_OPTIONS_H
+#define QEMU_OPT_IOPS_TOTAL "iops-total"
+#define QEMU_OPT_IOPS_TOTAL_MAX "iops-total-max"
+#define QEMU_OPT_IOPS_TOTAL_MAX_LENGTH "iops-total-max-length"
+#define QEMU_OPT_IOPS_READ "iops-read"
+#define QEMU_OPT_IOPS_READ_MAX "iops-read-max"
+#define QEMU_OPT_IOPS_READ_MAX_LENGTH "iops-read-max-length"
+#define QEMU_OPT_IOPS_WRITE "iops-write"
+#define QEMU_OPT_IOPS_WRITE_MAX "iops-write-max"
+#define QEMU_OPT_IOPS_WRITE_MAX_LENGTH "iops-write-max-length"
+#define QEMU_OPT_BPS_TOTAL "bps-total"
+#define QEMU_OPT_BPS_TOTAL_MAX "bps-total-max"
+#define QEMU_OPT_BPS_TOTAL_MAX_LENGTH "bps-total-max-length"
+#define QEMU_OPT_BPS_READ "bps-read"
+#define QEMU_OPT_BPS_READ_MAX "bps-read-max"
+#define QEMU_OPT_BPS_READ_MAX_LENGTH "bps-read-max-length"
+#define QEMU_OPT_BPS_WRITE "bps-write"
+#define QEMU_OPT_BPS_WRITE_MAX "bps-write-max"
+#define QEMU_OPT_BPS_WRITE_MAX_LENGTH "bps-write-max-length"
+#define QEMU_OPT_IOPS_SIZE "iops-size"
+#define QEMU_OPT_THROTTLE_GROUP_NAME "throttle-group"
+
+#define THROTTLE_OPT_PREFIX "throttling."
#define THROTTLE_OPTS \
{ \
- .name = "throttling.iops-total",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL,\
.type = QEMU_OPT_NUMBER,\
.help = "limit total I/O operations per second",\
},{ \
- .name = "throttling.iops-read",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ,\
.type = QEMU_OPT_NUMBER,\
.help = "limit read operations per second",\
},{ \
- .name = "throttling.iops-write",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE,\
.type = QEMU_OPT_NUMBER,\
.help = "limit write operations per second",\
},{ \
- .name = "throttling.bps-total",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL,\
.type = QEMU_OPT_NUMBER,\
.help = "limit total bytes per second",\
},{ \
- .name = "throttling.bps-read",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ,\
.type = QEMU_OPT_NUMBER,\
.help = "limit read bytes per second",\
},{ \
- .name = "throttling.bps-write",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE,\
.type = QEMU_OPT_NUMBER,\
.help = "limit write bytes per second",\
},{ \
- .name = "throttling.iops-total-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "I/O operations burst",\
},{ \
- .name = "throttling.iops-read-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "I/O operations read burst",\
},{ \
- .name = "throttling.iops-write-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "I/O operations write burst",\
},{ \
- .name = "throttling.bps-total-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "total bytes burst",\
},{ \
- .name = "throttling.bps-read-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "total bytes read burst",\
},{ \
- .name = "throttling.bps-write-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "total bytes write burst",\
},{ \
- .name = "throttling.iops-total-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the iops-total-max burst period, in seconds",\
},{ \
- .name = "throttling.iops-read-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the iops-read-max burst period, in seconds",\
},{ \
- .name = "throttling.iops-write-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the iops-write-max burst period, in seconds",\
},{ \
- .name = "throttling.bps-total-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the bps-total-max burst period, in seconds",\
},{ \
- .name = "throttling.bps-read-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the bps-read-max burst period, in seconds",\
},{ \
- .name = "throttling.bps-write-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the bps-write-max burst period, in seconds",\
},{ \
- .name = "throttling.iops-size",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_SIZE,\
.type = QEMU_OPT_NUMBER,\
.help = "when limiting by iops max size of an I/O in bytes",\
}
--
2.11.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver
2017-06-11 1:14 [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver Manos Pitsidianakis
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember Manos Pitsidianakis
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 2/2] block: add throttle block filter driver Manos Pitsidianakis
@ 2017-06-11 1:28 ` no-reply
2017-06-11 1:37 ` Manos Pitsidianakis
2 siblings, 1 reply; 7+ messages in thread
From: no-reply @ 2017-06-11 1:28 UTC (permalink / raw)
To: el13635; +Cc: famz, qemu-devel, kwolf, berto, qemu-block, stefanha
Hi,
This series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.
Type: series
Message-id: 20170611011427.6713-1-el13635@mail.ntua.gr
Subject: [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver
=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=8
time make docker-test-quick@centos6
time make docker-test-mingw@fedora
time make docker-test-build@min-glib
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
* [new tag] patchew/20170611011427.6713-1-el13635@mail.ntua.gr -> patchew/20170611011427.6713-1-el13635@mail.ntua.gr
Switched to a new branch 'test'
3d679a2 block: add throttle block filter driver
1ce33bd block: move ThrottleGroup membership to ThrottleGroupMember
=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-1sb30q_4/src/dtc'...
Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d'
BUILD centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-1sb30q_4/src'
ARCHIVE qemu.tgz
ARCHIVE dtc.tgz
COPY RUNNER
RUN test-quick in qemu:centos6
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
gcc-4.4.7-17.el6.x86_64
git-1.7.1-4.el6_7.1.x86_64
glib2-devel-2.28.8-5.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64
Environment variables:
PACKAGES=libfdt-devel ccache tar git make gcc g++ zlib-devel glib2-devel SDL-devel pixman-devel epel-release
HOSTNAME=952851f3178e
TERM=xterm
MAKEFLAGS= -j8
HISTSIZE=1000
J=8
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env
Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix /var/tmp/qemu-build/install
BIOS directory /var/tmp/qemu-build/install/share/qemu
binary directory /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory /var/tmp/qemu-build/install/etc
local state directory /var/tmp/qemu-build/install/var
Manual directory /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path /tmp/qemu-test/src
C compiler cc
Host C compiler cc
C++ compiler
Objective-C compiler cc
ARFLAGS rv
CFLAGS -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g
QEMU_CFLAGS -I/usr/include/pixman-1 -I$(SRC_PATH)/dtc/libfdt -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wendif-labels -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g
make make
install install
python python -B
smbd /usr/sbin/smbd
module support no
host CPU x86_64
host big endian no
target list x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled no
sparse enabled no
strip binaries yes
profiler no
static build no
pixman system
SDL support yes (1.2.14)
GTK support no
GTK GL support no
VTE support no
TLS priority NORMAL
GNUTLS support no
GNUTLS rnd no
libgcrypt no
libgcrypt kdf no
nettle no
nettle kdf no
libtasn1 no
curses support no
virgl support no
curl support no
mingw32 support no
Audio drivers oss
Block whitelist (rw)
Block whitelist (ro)
VirtFS support no
VNC support yes
VNC SASL support no
VNC JPEG support no
VNC PNG support no
xen support no
brlapi support no
bluez support no
Documentation no
PIE yes
vde support no
netmap support no
Linux AIO support no
ATTR/XATTR support yes
Install blobs yes
KVM support yes
HAX support no
RDMA support no
TCG interpreter no
fdt support yes
preadv support yes
fdatasync yes
madvise yes
posix_madvise yes
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
Trace backends log
spice support no
rbd support no
xfsctl support no
smartcard support no
libusb no
usb net redir no
OpenGL support no
OpenGL dmabufs no
libiscsi support no
libnfs support no
build guest agent yes
QGA VSS support no
QGA w32 disk info no
QGA MSI support no
seccomp support no
coroutine backend ucontext
coroutine pool yes
debug stack usage no
GlusterFS support no
gcov gcov
gcov enabled no
TPM support yes
libssh2 support no
TPM passthrough yes
QOM debugging yes
Live block migration yes
lzo support no
snappy support no
bzip2 support no
NUMA host support no
tcmalloc support no
jemalloc support no
avx2 optimization no
replication support yes
VxHS block device no
GEN x86_64-softmmu/config-devices.mak.tmp
mkdir -p dtc/libfdt
GEN config-host.h
GEN aarch64-softmmu/config-devices.mak.tmp
mkdir -p dtc/tests
GEN qemu-options.def
GEN qapi-visit.h
GEN qmp-commands.h
GEN qapi-types.h
GEN qapi-event.h
GEN x86_64-softmmu/config-devices.mak
GEN aarch64-softmmu/config-devices.mak
GEN qmp-marshal.c
GEN qapi-types.c
GEN qapi-visit.c
GEN qapi-event.c
GEN qmp-introspect.h
GEN trace/generated-tcg-tracers.h
GEN qmp-introspect.c
GEN trace/generated-helpers-wrappers.h
GEN trace/generated-helpers.h
GEN trace/generated-helpers.c
GEN module_block.h
GEN tests/test-qapi-types.h
GEN tests/test-qapi-visit.h
GEN tests/test-qapi-event.h
GEN tests/test-qmp-commands.h
GEN tests/test-qmp-introspect.h
GEN trace-root.h
GEN util/trace.h
GEN crypto/trace.h
GEN io/trace.h
GEN migration/trace.h
GEN block/trace.h
GEN backends/trace.h
GEN chardev/trace.h
GEN hw/block/trace.h
GEN hw/block/dataplane/trace.h
GEN hw/char/trace.h
GEN hw/intc/trace.h
GEN hw/net/trace.h
GEN hw/virtio/trace.h
GEN hw/audio/trace.h
GEN hw/misc/trace.h
GEN hw/usb/trace.h
GEN hw/scsi/trace.h
GEN hw/nvram/trace.h
GEN hw/display/trace.h
GEN hw/input/trace.h
GEN hw/timer/trace.h
GEN hw/dma/trace.h
GEN hw/sparc/trace.h
GEN hw/sd/trace.h
GEN hw/isa/trace.h
GEN hw/mem/trace.h
GEN hw/i386/trace.h
GEN hw/i386/xen/trace.h
GEN hw/9pfs/trace.h
GEN hw/ppc/trace.h
GEN hw/pci/trace.h
GEN hw/s390x/trace.h
GEN hw/vfio/trace.h
GEN hw/acpi/trace.h
GEN hw/arm/trace.h
GEN hw/alpha/trace.h
GEN hw/xen/trace.h
GEN ui/trace.h
GEN audio/trace.h
GEN net/trace.h
GEN target/arm/trace.h
GEN target/i386/trace.h
GEN target/mips/trace.h
GEN target/sparc/trace.h
GEN target/s390x/trace.h
GEN target/ppc/trace.h
GEN qom/trace.h
GEN linux-user/trace.h
GEN qapi/trace.h
GEN trace-root.c
GEN util/trace.c
GEN crypto/trace.c
GEN io/trace.c
GEN migration/trace.c
GEN block/trace.c
GEN backends/trace.c
GEN chardev/trace.c
GEN hw/block/trace.c
GEN hw/block/dataplane/trace.c
GEN hw/char/trace.c
GEN hw/intc/trace.c
GEN hw/net/trace.c
GEN hw/virtio/trace.c
GEN hw/audio/trace.c
GEN hw/misc/trace.c
GEN hw/usb/trace.c
GEN hw/scsi/trace.c
GEN hw/nvram/trace.c
GEN hw/display/trace.c
GEN hw/input/trace.c
GEN hw/timer/trace.c
GEN hw/dma/trace.c
GEN hw/sparc/trace.c
GEN hw/sd/trace.c
GEN hw/isa/trace.c
GEN hw/mem/trace.c
GEN hw/i386/trace.c
GEN hw/i386/xen/trace.c
GEN hw/9pfs/trace.c
GEN hw/ppc/trace.c
GEN hw/pci/trace.c
GEN hw/s390x/trace.c
GEN hw/vfio/trace.c
GEN hw/acpi/trace.c
GEN hw/arm/trace.c
GEN hw/alpha/trace.c
GEN hw/xen/trace.c
GEN ui/trace.c
GEN audio/trace.c
GEN net/trace.c
GEN target/arm/trace.c
GEN target/i386/trace.c
GEN target/mips/trace.c
GEN target/sparc/trace.c
GEN target/s390x/trace.c
GEN target/ppc/trace.c
GEN qom/trace.c
GEN linux-user/trace.c
GEN qapi/trace.c
GEN config-all-devices.mak
DEP /tmp/qemu-test/src/dtc/tests/dumptrees.c
DEP /tmp/qemu-test/src/dtc/tests/trees.S
DEP /tmp/qemu-test/src/dtc/tests/value-labels.c
DEP /tmp/qemu-test/src/dtc/tests/testutils.c
DEP /tmp/qemu-test/src/dtc/tests/asm_tree_dump.c
DEP /tmp/qemu-test/src/dtc/tests/truncated_property.c
DEP /tmp/qemu-test/src/dtc/tests/check_path.c
DEP /tmp/qemu-test/src/dtc/tests/overlay_bad_fixup.c
DEP /tmp/qemu-test/src/dtc/tests/overlay.c
DEP /tmp/qemu-test/src/dtc/tests/subnode_iterate.c
DEP /tmp/qemu-test/src/dtc/tests/integer-expressions.c
DEP /tmp/qemu-test/src/dtc/tests/property_iterate.c
DEP /tmp/qemu-test/src/dtc/tests/utilfdt_test.c
DEP /tmp/qemu-test/src/dtc/tests/path_offset_aliases.c
DEP /tmp/qemu-test/src/dtc/tests/add_subnode_with_nops.c
DEP /tmp/qemu-test/src/dtc/tests/dtbs_equal_unordered.c
DEP /tmp/qemu-test/src/dtc/tests/dtb_reverse.c
DEP /tmp/qemu-test/src/dtc/tests/dtbs_equal_ordered.c
DEP /tmp/qemu-test/src/dtc/tests/extra-terminating-null.c
DEP /tmp/qemu-test/src/dtc/tests/incbin.c
DEP /tmp/qemu-test/src/dtc/tests/boot-cpuid.c
DEP /tmp/qemu-test/src/dtc/tests/phandle_format.c
DEP /tmp/qemu-test/src/dtc/tests/path-references.c
DEP /tmp/qemu-test/src/dtc/tests/references.c
DEP /tmp/qemu-test/src/dtc/tests/string_escapes.c
DEP /tmp/qemu-test/src/dtc/tests/propname_escapes.c
DEP /tmp/qemu-test/src/dtc/tests/appendprop2.c
DEP /tmp/qemu-test/src/dtc/tests/appendprop1.c
DEP /tmp/qemu-test/src/dtc/tests/del_node.c
DEP /tmp/qemu-test/src/dtc/tests/del_property.c
DEP /tmp/qemu-test/src/dtc/tests/setprop.c
DEP /tmp/qemu-test/src/dtc/tests/set_name.c
DEP /tmp/qemu-test/src/dtc/tests/rw_tree1.c
DEP /tmp/qemu-test/src/dtc/tests/open_pack.c
DEP /tmp/qemu-test/src/dtc/tests/nopulate.c
DEP /tmp/qemu-test/src/dtc/tests/mangle-layout.c
DEP /tmp/qemu-test/src/dtc/tests/move_and_save.c
DEP /tmp/qemu-test/src/dtc/tests/sw_tree1.c
DEP /tmp/qemu-test/src/dtc/tests/nop_node.c
DEP /tmp/qemu-test/src/dtc/tests/nop_property.c
DEP /tmp/qemu-test/src/dtc/tests/setprop_inplace.c
DEP /tmp/qemu-test/src/dtc/tests/stringlist.c
DEP /tmp/qemu-test/src/dtc/tests/addr_size_cells.c
DEP /tmp/qemu-test/src/dtc/tests/notfound.c
DEP /tmp/qemu-test/src/dtc/tests/sized_cells.c
DEP /tmp/qemu-test/src/dtc/tests/char_literal.c
DEP /tmp/qemu-test/src/dtc/tests/get_alias.c
DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_compatible.c
DEP /tmp/qemu-test/src/dtc/tests/node_check_compatible.c
DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_phandle.c
DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_prop_value.c
DEP /tmp/qemu-test/src/dtc/tests/supernode_atdepth_offset.c
DEP /tmp/qemu-test/src/dtc/tests/parent_offset.c
DEP /tmp/qemu-test/src/dtc/tests/get_path.c
DEP /tmp/qemu-test/src/dtc/tests/get_phandle.c
DEP /tmp/qemu-test/src/dtc/tests/get_name.c
DEP /tmp/qemu-test/src/dtc/tests/getprop.c
DEP /tmp/qemu-test/src/dtc/tests/path_offset.c
DEP /tmp/qemu-test/src/dtc/tests/subnode_offset.c
DEP /tmp/qemu-test/src/dtc/tests/find_property.c
DEP /tmp/qemu-test/src/dtc/tests/root_node.c
DEP /tmp/qemu-test/src/dtc/tests/get_mem_rsv.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_overlay.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_addresses.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_empty_tree.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_strerror.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_rw.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_sw.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_wip.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt_ro.c
DEP /tmp/qemu-test/src/dtc/libfdt/fdt.c
DEP /tmp/qemu-test/src/dtc/util.c
DEP /tmp/qemu-test/src/dtc/fdtput.c
DEP /tmp/qemu-test/src/dtc/fdtget.c
DEP /tmp/qemu-test/src/dtc/fdtdump.c
LEX convert-dtsv0-lexer.lex.c
make[1]: flex: Command not found
DEP /tmp/qemu-test/src/dtc/srcpos.c
LEX dtc-lexer.lex.c
DEP /tmp/qemu-test/src/dtc/treesource.c
make[1]: flex: Command not found
DEP /tmp/qemu-test/src/dtc/fstree.c
BISON dtc-parser.tab.c
DEP /tmp/qemu-test/src/dtc/flattree.c
DEP /tmp/qemu-test/src/dtc/livetree.c
make[1]: bison: Command not found
DEP /tmp/qemu-test/src/dtc/dtc.c
DEP /tmp/qemu-test/src/dtc/data.c
DEP /tmp/qemu-test/src/dtc/checks.c
CHK version_gen.h
LEX convert-dtsv0-lexer.lex.c
BISON dtc-parser.tab.c
make[1]: flex: Command not found
make[1]: bison: Command not found
LEX dtc-lexer.lex.c
UPD version_gen.h
make[1]: flex: Command not found
DEP /tmp/qemu-test/src/dtc/util.c
LEX convert-dtsv0-lexer.lex.c
make[1]: flex: Command not found
BISON dtc-parser.tab.c
make[1]: bison: Command not found
LEX dtc-lexer.lex.c
make[1]: flex: Command not found
CC libfdt/fdt.o
CC libfdt/fdt_sw.o
CC libfdt/fdt_ro.o
CC libfdt/fdt_rw.o
CC libfdt/fdt_wip.o
CC libfdt/fdt_strerror.o
CC libfdt/fdt_empty_tree.o
CC libfdt/fdt_overlay.o
CC libfdt/fdt_addresses.o
AR libfdt/libfdt.a
ar: creating libfdt/libfdt.a
a - libfdt/fdt.o
a - libfdt/fdt_ro.o
a - libfdt/fdt_wip.o
a - libfdt/fdt_sw.o
a - libfdt/fdt_rw.o
a - libfdt/fdt_strerror.o
a - libfdt/fdt_empty_tree.o
a - libfdt/fdt_addresses.o
a - libfdt/fdt_overlay.o
LEX dtc-lexer.lex.c
LEX convert-dtsv0-lexer.lex.c
make[1]: flex: Command not found
make[1]: flex: Command not found
BISON dtc-parser.tab.c
make[1]: bison: Command not found
GEN qga/qapi-generated/qga-qapi-visit.h
CC tests/qemu-iotests/socket_scm_helper.o
GEN qga/qapi-generated/qga-qmp-commands.h
GEN qga/qapi-generated/qga-qapi-types.h
GEN qga/qapi-generated/qga-qapi-visit.c
GEN qga/qapi-generated/qga-qapi-types.c
CC qmp-introspect.o
GEN qga/qapi-generated/qga-qmp-marshal.c
CC qapi-types.o
CC qapi-visit.o
CC qapi-event.o
CC qapi/qapi-visit-core.o
CC qapi/qapi-dealloc-visitor.o
CC qapi/qobject-input-visitor.o
CC qapi/qobject-output-visitor.o
CC qapi/qmp-registry.o
CC qapi/qmp-dispatch.o
CC qapi/string-input-visitor.o
CC qapi/string-output-visitor.o
CC qapi/opts-visitor.o
CC qapi/qapi-clone-visitor.o
CC qapi/qmp-event.o
CC qapi/qapi-util.o
CC qobject/qnull.o
CC qobject/qint.o
CC qobject/qdict.o
CC qobject/qstring.o
CC qobject/qlist.o
CC qobject/qfloat.o
CC qobject/qjson.o
CC qobject/qbool.o
CC qobject/qobject.o
CC qobject/json-lexer.o
CC qobject/json-streamer.o
CC trace/control.o
CC qobject/json-parser.o
CC trace/qmp.o
CC util/osdep.o
CC util/cutils.o
CC util/unicode.o
CC util/qemu-timer-common.o
CC util/bufferiszero.o
CC util/lockcnt.o
CC util/aiocb.o
CC util/async.o
CC util/thread-pool.o
CC util/qemu-timer.o
CC util/main-loop.o
CC util/iohandler.o
CC util/aio-posix.o
CC util/compatfd.o
CC util/event_notifier-posix.o
CC util/mmap-alloc.o
CC util/oslib-posix.o
CC util/qemu-openpty.o
CC util/qemu-thread-posix.o
CC util/memfd.o
CC util/envlist.o
CC util/path.o
CC util/module.o
CC util/host-utils.o
CC util/bitmap.o
CC util/bitops.o
CC util/hbitmap.o
CC util/fifo8.o
CC util/acl.o
CC util/error.o
CC util/qemu-error.o
CC util/id.o
CC util/iov.o
CC util/qemu-config.o
CC util/qemu-sockets.o
CC util/uri.o
CC util/notify.o
CC util/qemu-option.o
CC util/qemu-progress.o
CC util/keyval.o
CC util/hexdump.o
CC util/crc32c.o
CC util/uuid.o
CC util/throttle.o
CC util/getauxval.o
CC util/readline.o
CC util/rcu.o
CC util/qemu-coroutine.o
CC util/qemu-coroutine-lock.o
CC util/qemu-coroutine-io.o
CC util/qemu-coroutine-sleep.o
CC util/coroutine-ucontext.o
CC util/buffer.o
CC util/timed-average.o
CC util/base64.o
CC util/log.o
CC util/qdist.o
CC util/qht.o
CC util/range.o
CC trace-root.o
CC util/systemd.o
CC util/trace.o
CC crypto/trace.o
CC io/trace.o
CC migration/trace.o
CC block/trace.o
CC backends/trace.o
CC chardev/trace.o
CC hw/block/trace.o
CC hw/block/dataplane/trace.o
CC hw/char/trace.o
CC hw/intc/trace.o
CC hw/net/trace.o
CC hw/virtio/trace.o
CC hw/audio/trace.o
CC hw/misc/trace.o
CC hw/usb/trace.o
CC hw/scsi/trace.o
CC hw/nvram/trace.o
CC hw/display/trace.o
CC hw/input/trace.o
CC hw/timer/trace.o
CC hw/dma/trace.o
CC hw/sd/trace.o
CC hw/sparc/trace.o
CC hw/isa/trace.o
CC hw/mem/trace.o
CC hw/i386/trace.o
CC hw/i386/xen/trace.o
CC hw/9pfs/trace.o
CC hw/ppc/trace.o
CC hw/pci/trace.o
CC hw/s390x/trace.o
CC hw/vfio/trace.o
CC hw/arm/trace.o
CC hw/acpi/trace.o
CC hw/alpha/trace.o
CC hw/xen/trace.o
CC ui/trace.o
CC audio/trace.o
CC net/trace.o
CC target/arm/trace.o
CC target/i386/trace.o
CC target/sparc/trace.o
CC target/mips/trace.o
CC target/s390x/trace.o
CC target/ppc/trace.o
CC qom/trace.o
CC linux-user/trace.o
CC qapi/trace.o
CC crypto/pbkdf-stub.o
CC stubs/arch-query-cpu-def.o
CC stubs/arch-query-cpu-model-expansion.o
CC stubs/arch-query-cpu-model-comparison.o
CC stubs/arch-query-cpu-model-baseline.o
CC stubs/bdrv-next-monitor-owned.o
CC stubs/blockdev-close-all-bdrv-states.o
CC stubs/blk-commit-all.o
CC stubs/clock-warp.o
CC stubs/cpu-get-clock.o
CC stubs/cpu-get-icount.o
CC stubs/dump.o
CC stubs/error-printf.o
CC stubs/fdset.o
CC stubs/gdbstub.o
CC stubs/iothread.o
CC stubs/get-vm-name.o
CC stubs/iothread-lock.o
CC stubs/is-daemonized.o
CC stubs/machine-init-done.o
CC stubs/migr-blocker.o
CC stubs/monitor.o
CC stubs/notify-event.o
CC stubs/qtest.o
CC stubs/replay.o
CC stubs/runstate-check.o
CC stubs/set-fd-handler.o
CC stubs/slirp.o
CC stubs/sysbus.o
CC stubs/trace-control.o
CC stubs/uuid.o
CC stubs/vm-stop.o
CC stubs/vmstate.o
CC stubs/qmp_pc_dimm_device_list.o
CC stubs/target-monitor-defs.o
CC stubs/target-get-monitor-def.o
CC stubs/pc_madt_cpu_entry.o
CC stubs/vmgenid.o
CC stubs/xen-common.o
CC stubs/xen-hvm.o
CC contrib/ivshmem-client/ivshmem-client.o
CC contrib/ivshmem-client/main.o
CC contrib/ivshmem-server/ivshmem-server.o
CC contrib/ivshmem-server/main.o
CC qemu-nbd.o
CC blockjob.o
CC block.o
CC qemu-io-cmds.o
CC replication.o
CC block/raw-format.o
CC block/qcow.o
CC block/vdi.o
CC block/vmdk.o
CC block/cloop.o
CC block/bochs.o
CC block/vpc.o
CC block/vvfat.o
CC block/dmg.o
CC block/qcow2.o
CC block/qcow2-refcount.o
CC block/qcow2-cluster.o
CC block/qcow2-snapshot.o
CC block/qcow2-cache.o
CC block/qed.o
CC block/qed-gencb.o
CC block/qed-l2-cache.o
CC block/qed-table.o
CC block/qed-cluster.o
CC block/qed-check.o
CC block/vhdx.o
CC block/vhdx-endian.o
CC block/vhdx-log.o
CC block/quorum.o
CC block/parallels.o
CC block/blkdebug.o
CC block/blkverify.o
CC block/blkreplay.o
CC block/block-backend.o
CC block/null.o
CC block/file-posix.o
CC block/snapshot.o
CC block/mirror.o
CC block/qapi.o
CC block/commit.o
CC block/io.o
CC block/throttle-groups.o
CC block/nbd.o
CC block/nbd-client.o
CC block/sheepdog.o
CC block/accounting.o
CC block/dirty-bitmap.o
CC block/write-threshold.o
CC block/backup.o
CC block/replication.o
CC block/throttle.o
CC block/crypto.o
CC nbd/server.o
CC nbd/client.o
CC nbd/common.o
CC crypto/init.o
CC crypto/hash.o
CC crypto/hash-glib.o
CC crypto/hmac.o
CC crypto/hmac-glib.o
CC crypto/aes.o
CC crypto/desrfb.o
CC crypto/cipher.o
CC crypto/tlscreds.o
CC crypto/tlscredsanon.o
CC crypto/tlscredsx509.o
CC crypto/tlssession.o
CC crypto/secret.o
CC crypto/random-platform.o
CC crypto/pbkdf.o
CC crypto/ivgen.o
CC crypto/ivgen-essiv.o
CC crypto/ivgen-plain.o
CC crypto/ivgen-plain64.o
CC crypto/xts.o
CC crypto/afsplit.o
CC crypto/block.o
CC crypto/block-qcow.o
CC io/channel.o
CC crypto/block-luks.o
CC io/channel-buffer.o
CC io/channel-command.o
CC io/channel-file.o
CC io/channel-socket.o
CC io/channel-tls.o
CC io/channel-watch.o
CC io/channel-websock.o
CC io/channel-util.o
CC io/dns-resolver.o
CC io/task.o
CC qom/object.o
CC qom/container.o
CC qom/qom-qobject.o
CC qom/object_interfaces.o
GEN qemu-img-cmds.h
CC qemu-io.o
CC qemu-bridge-helper.o
CC blockdev.o
CC iothread.o
CC blockdev-nbd.o
CC device-hotplug.o
CC qdev-monitor.o
CC os-posix.o
CC bt-host.o
CC accel.o
CC bt-vhci.o
CC dma-helpers.o
CC vl.o
CC tpm.o
CC device_tree.o
CC qmp-marshal.o
CC qmp.o
CC hmp.o
CC cpus-common.o
CC audio/audio.o
CC audio/noaudio.o
CC audio/wavaudio.o
CC audio/mixeng.o
CC audio/sdlaudio.o
CC audio/wavcapture.o
CC audio/ossaudio.o
CC backends/rng.o
CC backends/rng-egd.o
CC backends/rng-random.o
CC backends/tpm.o
CC backends/hostmem.o
CC backends/hostmem-ram.o
CC backends/hostmem-file.o
CC backends/cryptodev.o
CC backends/cryptodev-builtin.o
CC block/stream.o
CC chardev/msmouse.o
CC chardev/wctablet.o
CC chardev/testdev.o
CC disas/arm.o
CC disas/i386.o
CC fsdev/qemu-fsdev-dummy.o
CC fsdev/qemu-fsdev-opts.o
CC fsdev/qemu-fsdev-throttle.o
CC hw/acpi/core.o
CC hw/acpi/piix4.o
CC hw/acpi/pcihp.o
CC hw/acpi/ich9.o
CC hw/acpi/tco.o
CC hw/acpi/cpu_hotplug.o
CC hw/acpi/memory_hotplug.o
CC hw/acpi/cpu.o
CC hw/acpi/nvdimm.o
CC hw/acpi/vmgenid.o
CC hw/acpi/acpi_interface.o
CC hw/acpi/bios-linker-loader.o
CC hw/acpi/aml-build.o
CC hw/acpi/ipmi.o
CC hw/acpi/acpi-stub.o
CC hw/acpi/ipmi-stub.o
CC hw/audio/sb16.o
CC hw/audio/es1370.o
CC hw/audio/ac97.o
CC hw/audio/fmopl.o
CC hw/audio/adlib.o
CC hw/audio/gus.o
CC hw/audio/gusemu_mixer.o
CC hw/audio/gusemu_hal.o
CC hw/audio/cs4231a.o
CC hw/audio/intel-hda.o
CC hw/audio/hda-codec.o
CC hw/audio/pcspk.o
CC hw/audio/wm8750.o
CC hw/audio/pl041.o
CC hw/audio/lm4549.o
CC hw/audio/marvell_88w8618.o
CC hw/audio/soundhw.o
CC hw/block/block.o
CC hw/block/hd-geometry.o
CC hw/block/cdrom.o
CC hw/block/fdc.o
CC hw/block/m25p80.o
CC hw/block/nand.o
CC hw/block/pflash_cfi01.o
CC hw/block/ecc.o
CC hw/block/pflash_cfi02.o
CC hw/block/onenand.o
CC hw/block/nvme.o
CC hw/bt/core.o
CC hw/bt/l2cap.o
CC hw/bt/sdp.o
CC hw/bt/hci.o
CC hw/bt/hid.o
CC hw/bt/hci-csr.o
CC hw/char/ipoctal232.o
CC hw/char/parallel.o
CC hw/char/pl011.o
CC hw/char/serial.o
CC hw/char/serial-isa.o
CC hw/char/serial-pci.o
CC hw/char/virtio-console.o
CC hw/char/cadence_uart.o
CC hw/char/debugcon.o
CC hw/char/imx_serial.o
CC hw/core/qdev.o
CC hw/core/qdev-properties.o
CC hw/core/bus.o
CC hw/core/reset.o
CC hw/core/fw-path-provider.o
CC hw/core/irq.o
CC hw/core/hotplug.o
CC hw/core/nmi.o
CC hw/core/sysbus.o
CC hw/core/ptimer.o
CC hw/core/loader.o
CC hw/core/machine.o
CC hw/core/qdev-properties-system.o
CC hw/core/register.o
CC hw/core/or-irq.o
CC hw/core/platform-bus.o
CC hw/display/ads7846.o
CC hw/display/cirrus_vga.o
CC hw/display/ssd0303.o
CC hw/display/pl110.o
CC hw/display/ssd0323.o
CC hw/display/vga-pci.o
CC hw/display/vga-isa.o
CC hw/display/vmware_vga.o
CC hw/display/blizzard.o
CC hw/display/exynos4210_fimd.o
CC hw/display/tc6393xb.o
CC hw/display/framebuffer.o
CC hw/dma/pl080.o
CC hw/dma/pl330.o
CC hw/dma/i8257.o
CC hw/gpio/max7310.o
CC hw/dma/xlnx-zynq-devcfg.o
CC hw/gpio/pl061.o
CC hw/gpio/zaurus.o
CC hw/gpio/gpio_key.o
CC hw/i2c/core.o
CC hw/i2c/smbus.o
CC hw/i2c/smbus_eeprom.o
CC hw/i2c/i2c-ddc.o
CC hw/i2c/versatile_i2c.o
CC hw/i2c/smbus_ich9.o
CC hw/i2c/pm_smbus.o
CC hw/i2c/exynos4210_i2c.o
CC hw/i2c/bitbang_i2c.o
CC hw/ide/core.o
CC hw/i2c/aspeed_i2c.o
CC hw/ide/atapi.o
CC hw/i2c/imx_i2c.o
CC hw/ide/qdev.o
CC hw/ide/pci.o
CC hw/ide/isa.o
CC hw/ide/piix.o
CC hw/ide/microdrive.o
CC hw/ide/ahci.o
CC hw/ide/ich.o
CC hw/input/hid.o
CC hw/input/lm832x.o
CC hw/input/pckbd.o
CC hw/input/pl050.o
CC hw/input/ps2.o
CC hw/input/stellaris_input.o
CC hw/input/tsc2005.o
CC hw/input/vmmouse.o
CC hw/input/virtio-input.o
CC hw/input/virtio-input-hid.o
CC hw/input/virtio-input-host.o
CC hw/intc/i8259_common.o
CC hw/intc/i8259.o
CC hw/intc/pl190.o
CC hw/intc/imx_avic.o
CC hw/intc/realview_gic.o
CC hw/intc/ioapic_common.o
CC hw/intc/arm_gic_common.o
CC hw/intc/arm_gic.o
CC hw/intc/arm_gicv2m.o
CC hw/intc/arm_gicv3_common.o
CC hw/intc/arm_gicv3.o
CC hw/intc/arm_gicv3_dist.o
CC hw/intc/arm_gicv3_redist.o
CC hw/intc/arm_gicv3_its_common.o
CC hw/intc/intc.o
CC hw/ipack/ipack.o
CC hw/ipack/tpci200.o
CC hw/ipmi/ipmi.o
CC hw/ipmi/ipmi_bmc_sim.o
CC hw/ipmi/ipmi_bmc_extern.o
CC hw/ipmi/isa_ipmi_kcs.o
CC hw/ipmi/isa_ipmi_bt.o
CC hw/isa/isa-bus.o
CC hw/isa/apm.o
CC hw/mem/pc-dimm.o
CC hw/misc/applesmc.o
CC hw/mem/nvdimm.o
CC hw/misc/max111x.o
CC hw/misc/tmp105.o
CC hw/misc/debugexit.o
CC hw/misc/sga.o
CC hw/misc/pc-testdev.o
CC hw/misc/pci-testdev.o
CC hw/misc/unimp.o
CC hw/misc/arm_l2x0.o
CC hw/misc/arm_integrator_debug.o
CC hw/misc/a9scu.o
CC hw/misc/arm11scu.o
CC hw/net/ne2000.o
CC hw/net/eepro100.o
CC hw/net/pcnet-pci.o
CC hw/net/pcnet.o
CC hw/net/e1000.o
CC hw/net/e1000x_common.o
CC hw/net/net_tx_pkt.o
CC hw/net/net_rx_pkt.o
CC hw/net/e1000e.o
CC hw/net/e1000e_core.o
CC hw/net/rtl8139.o
CC hw/net/vmxnet3.o
CC hw/net/smc91c111.o
CC hw/net/lan9118.o
CC hw/net/ne2000-isa.o
CC hw/net/xgmac.o
CC hw/net/allwinner_emac.o
CC hw/net/imx_fec.o
CC hw/net/cadence_gem.o
CC hw/net/stellaris_enet.o
CC hw/net/ftgmac100.o
CC hw/net/rocker/rocker.o
CC hw/net/rocker/rocker_fp.o
CC hw/net/rocker/rocker_desc.o
CC hw/net/rocker/rocker_world.o
CC hw/net/rocker/rocker_of_dpa.o
CC hw/nvram/eeprom93xx.o
CC hw/nvram/fw_cfg.o
CC hw/nvram/chrp_nvram.o
CC hw/pci-bridge/pci_bridge_dev.o
CC hw/pci-bridge/gen_pcie_root_port.o
CC hw/pci-bridge/pcie_root_port.o
CC hw/pci-bridge/xio3130_upstream.o
CC hw/pci-bridge/pci_expander_bridge.o
CC hw/pci-bridge/xio3130_downstream.o
CC hw/pci-bridge/ioh3420.o
CC hw/pci-bridge/i82801b11.o
CC hw/pci-host/versatile.o
CC hw/pci-host/pam.o
CC hw/pci-host/piix.o
CC hw/pci-host/q35.o
CC hw/pci-host/gpex.o
CC hw/pci/pci.o
CC hw/pci/msix.o
CC hw/pci/pci_bridge.o
CC hw/pci/shpc.o
CC hw/pci/msi.o
CC hw/pci/slotid_cap.o
CC hw/pci/pci_host.o
CC hw/pci/pcie_host.o
CC hw/pci/pcie.o
CC hw/pci/pcie_aer.o
CC hw/pci/pci-stub.o
CC hw/pci/pcie_port.o
CC hw/scsi/scsi-disk.o
CC hw/pcmcia/pcmcia.o
CC hw/scsi/scsi-generic.o
CC hw/scsi/scsi-bus.o
CC hw/scsi/lsi53c895a.o
CC hw/scsi/mptsas.o
CC hw/scsi/mptconfig.o
CC hw/scsi/mptendian.o
CC hw/scsi/megasas.o
CC hw/scsi/vmw_pvscsi.o
CC hw/scsi/esp.o
CC hw/scsi/esp-pci.o
CC hw/sd/pl181.o
CC hw/sd/ssi-sd.o
CC hw/sd/sd.o
CC hw/sd/core.o
CC hw/sd/sdhci.o
CC hw/smbios/smbios.o
CC hw/smbios/smbios_type_38.o
CC hw/smbios/smbios-stub.o
CC hw/smbios/smbios_type_38-stub.o
CC hw/ssi/pl022.o
CC hw/ssi/xilinx_spips.o
CC hw/ssi/ssi.o
CC hw/ssi/stm32f2xx_spi.o
CC hw/ssi/aspeed_smc.o
CC hw/timer/arm_timer.o
CC hw/timer/arm_mptimer.o
CC hw/timer/armv7m_systick.o
CC hw/timer/a9gtimer.o
CC hw/timer/cadence_ttc.o
CC hw/timer/ds1338.o
CC hw/timer/hpet.o
CC hw/timer/i8254_common.o
CC hw/timer/pl031.o
CC hw/timer/twl92230.o
CC hw/timer/i8254.o
CC hw/timer/imx_epit.o
CC hw/timer/imx_gpt.o
CC hw/timer/stm32f2xx_timer.o
CC hw/timer/aspeed_timer.o
CC hw/tpm/tpm_tis.o
CC hw/tpm/tpm_passthrough.o
CC hw/tpm/tpm_util.o
CC hw/usb/core.o
CC hw/usb/combined-packet.o
CC hw/usb/bus.o
CC hw/usb/libhw.o
CC hw/usb/desc.o
CC hw/usb/desc-msos.o
CC hw/usb/hcd-ohci.o
CC hw/usb/hcd-ehci.o
CC hw/usb/hcd-uhci.o
CC hw/usb/hcd-ehci-sysbus.o
CC hw/usb/hcd-ehci-pci.o
CC hw/usb/hcd-xhci.o
CC hw/usb/hcd-musb.o
CC hw/usb/hcd-xhci-nec.o
CC hw/usb/dev-hub.o
CC hw/usb/dev-hid.o
CC hw/usb/dev-wacom.o
CC hw/usb/dev-storage.o
CC hw/usb/dev-uas.o
CC hw/usb/dev-audio.o
CC hw/usb/dev-serial.o
CC hw/usb/dev-bluetooth.o
CC hw/usb/dev-smartcard-reader.o
CC hw/usb/dev-network.o
CC hw/usb/dev-mtp.o
CC hw/usb/host-stub.o
CC hw/virtio/virtio-rng.o
CC hw/virtio/virtio-pci.o
CC hw/virtio/virtio-bus.o
CC hw/virtio/virtio-mmio.o
CC hw/virtio/vhost-stub.o
CC hw/watchdog/watchdog.o
CC hw/watchdog/wdt_i6300esb.o
CC hw/watchdog/wdt_ib700.o
CC hw/watchdog/wdt_aspeed.o
CC migration/migration.o
CC migration/socket.o
CC migration/fd.o
CC migration/exec.o
CC migration/tls.o
CC migration/channel.o
CC migration/savevm.o
CC migration/colo-comm.o
CC migration/colo.o
CC migration/vmstate.o
CC migration/colo-failover.o
CC migration/vmstate-types.o
CC migration/page_cache.o
CC migration/qemu-file.o
CC migration/qemu-file-channel.o
CC migration/xbzrle.o
CC migration/qjson.o
CC migration/block.o
CC migration/postcopy-ram.o
CC net/net.o
CC net/queue.o
CC net/checksum.o
CC net/util.o
CC net/hub.o
CC net/socket.o
CC net/dump.o
CC net/eth.o
CC net/l2tpv3.o
CC net/vhost-user.o
CC net/slirp.o
CC net/filter.o
CC net/filter-buffer.o
CC net/colo-compare.o
CC net/filter-mirror.o
CC net/colo.o
CC net/filter-rewriter.o
CC net/filter-replay.o
CC net/tap.o
CC net/tap-linux.o
CC qom/cpu.o
CC replay/replay-internal.o
CC replay/replay.o
CC replay/replay-events.o
CC replay/replay-time.o
CC replay/replay-input.o
CC replay/replay-char.o
/tmp/qemu-test/src/replay/replay-internal.c: In function ‘replay_put_array’:
/tmp/qemu-test/src/replay/replay-internal.c:65: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
CC replay/replay-snapshot.o
CC replay/replay-net.o
CC replay/replay-audio.o
CC slirp/cksum.o
CC slirp/if.o
CC slirp/ip_icmp.o
CC slirp/ip6_icmp.o
CC slirp/ip6_input.o
CC slirp/ip6_output.o
CC slirp/ip_input.o
CC slirp/dnssearch.o
CC slirp/ip_output.o
CC slirp/dhcpv6.o
CC slirp/slirp.o
CC slirp/mbuf.o
CC slirp/misc.o
CC slirp/socket.o
CC slirp/tcp_input.o
CC slirp/sbuf.o
CC slirp/tcp_output.o
CC slirp/tcp_subr.o
CC slirp/tcp_timer.o
CC slirp/udp.o
CC slirp/udp6.o
CC slirp/bootp.o
CC slirp/tftp.o
/tmp/qemu-test/src/slirp/tcp_input.c: In function ‘tcp_input’:
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_p’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_len’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_tos’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_id’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_off’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_ttl’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_sum’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_src.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_dst.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:220: warning: ‘save_ip6.ip_nh’ may be used uninitialized in this function
CC slirp/ndp_table.o
CC slirp/arp_table.o
CC ui/console.o
CC slirp/ncsi.o
CC ui/keymaps.o
CC ui/cursor.o
CC ui/qemu-pixman.o
CC ui/input.o
CC ui/input-keymap.o
CC ui/input-legacy.o
CC ui/input-linux.o
CC ui/sdl.o
CC ui/sdl_zoom.o
CC ui/x_keymap.o
CC ui/vnc.o
CC ui/vnc-enc-zlib.o
CC ui/vnc-enc-hextile.o
CC ui/vnc-enc-tight.o
CC ui/vnc-palette.o
CC ui/vnc-enc-zrle.o
CC ui/vnc-auth-vencrypt.o
CC ui/vnc-ws.o
CC ui/vnc-jobs.o
CC chardev/char.o
CC chardev/char-fd.o
CC chardev/char-fe.o
CC chardev/char-file.o
CC chardev/char-io.o
CC chardev/char-mux.o
CC chardev/char-null.o
CC chardev/char-parallel.o
CC chardev/char-pipe.o
CC chardev/char-pty.o
CC chardev/char-ringbuf.o
CC chardev/char-serial.o
CC chardev/char-socket.o
CC chardev/char-stdio.o
CC chardev/char-udp.o
LINK tests/qemu-iotests/socket_scm_helper
CC qga/commands.o
CC qga/guest-agent-command-state.o
CC qga/main.o
CC qga/commands-posix.o
CC qga/qapi-generated/qga-qapi-types.o
CC qga/channel-posix.o
CC qga/qapi-generated/qga-qapi-visit.o
CC qga/qapi-generated/qga-qmp-marshal.o
AS optionrom/multiboot.o
AR libqemuutil.a
AS optionrom/linuxboot.o
CC optionrom/linuxboot_dma.o
cc: unrecognized option '-no-integrated-as'
cc: unrecognized option '-no-integrated-as'
AS optionrom/kvmvapic.o
AR libqemustub.a
CC qemu-img.o
BUILD optionrom/linuxboot.img
BUILD optionrom/multiboot.img
BUILD optionrom/linuxboot_dma.img
BUILD optionrom/kvmvapic.img
BUILD optionrom/linuxboot.raw
BUILD optionrom/multiboot.raw
BUILD optionrom/linuxboot_dma.raw
BUILD optionrom/kvmvapic.raw
SIGN optionrom/linuxboot_dma.bin
SIGN optionrom/multiboot.bin
SIGN optionrom/kvmvapic.bin
SIGN optionrom/linuxboot.bin
LINK qemu-ga
LINK ivshmem-client
LINK ivshmem-server
LINK qemu-nbd
LINK qemu-io
LINK qemu-bridge-helper
GEN x86_64-softmmu/hmp-commands.h
GEN x86_64-softmmu/hmp-commands-info.h
GEN x86_64-softmmu/config-target.h
GEN aarch64-softmmu/hmp-commands-info.h
GEN aarch64-softmmu/config-target.h
GEN aarch64-softmmu/hmp-commands.h
CC x86_64-softmmu/cpu-exec.o
CC x86_64-softmmu/translate-common.o
CC x86_64-softmmu/translate-all.o
CC x86_64-softmmu/cpu-exec-common.o
CC x86_64-softmmu/exec.o
CC x86_64-softmmu/tcg/tcg.o
CC aarch64-softmmu/exec.o
CC aarch64-softmmu/translate-all.o
CC aarch64-softmmu/cpu-exec.o
CC x86_64-softmmu/tcg/tcg-op.o
CC aarch64-softmmu/translate-common.o
CC x86_64-softmmu/tcg/optimize.o
CC x86_64-softmmu/tcg/tcg-common.o
LINK qemu-img
CC aarch64-softmmu/cpu-exec-common.o
CC x86_64-softmmu/fpu/softfloat.o
CC x86_64-softmmu/disas.o
CC x86_64-softmmu/tcg-runtime.o
GEN x86_64-softmmu/gdbstub-xml.c
CC aarch64-softmmu/tcg/tcg.o
CC aarch64-softmmu/tcg/tcg-op.o
CC aarch64-softmmu/tcg/optimize.o
CC x86_64-softmmu/hax-stub.o
CC x86_64-softmmu/arch_init.o
CC aarch64-softmmu/tcg/tcg-common.o
CC x86_64-softmmu/cpus.o
CC x86_64-softmmu/monitor.o
CC aarch64-softmmu/fpu/softfloat.o
CC x86_64-softmmu/gdbstub.o
CC x86_64-softmmu/balloon.o
CC aarch64-softmmu/disas.o
CC x86_64-softmmu/ioport.o
CC aarch64-softmmu/tcg-runtime.o
GEN aarch64-softmmu/gdbstub-xml.c
CC aarch64-softmmu/hax-stub.o
CC aarch64-softmmu/kvm-stub.o
CC x86_64-softmmu/numa.o
CC x86_64-softmmu/qtest.o
CC aarch64-softmmu/arch_init.o
CC x86_64-softmmu/bootdevice.o
CC aarch64-softmmu/cpus.o
CC x86_64-softmmu/kvm-all.o
CC aarch64-softmmu/gdbstub.o
CC aarch64-softmmu/monitor.o
CC aarch64-softmmu/balloon.o
CC aarch64-softmmu/ioport.o
CC aarch64-softmmu/numa.o
CC aarch64-softmmu/qtest.o
CC aarch64-softmmu/bootdevice.o
CC aarch64-softmmu/memory.o
CC aarch64-softmmu/cputlb.o
CC aarch64-softmmu/dump.o
CC aarch64-softmmu/memory_mapping.o
CC aarch64-softmmu/hw/adc/stm32f2xx_adc.o
CC aarch64-softmmu/migration/ram.o
CC x86_64-softmmu/memory.o
CC aarch64-softmmu/hw/block/virtio-blk.o
CC x86_64-softmmu/cputlb.o
CC aarch64-softmmu/hw/block/dataplane/virtio-blk.o
CC aarch64-softmmu/hw/char/exynos4210_uart.o
CC aarch64-softmmu/hw/char/omap_uart.o
CC aarch64-softmmu/hw/char/digic-uart.o
CC x86_64-softmmu/memory_mapping.o
CC aarch64-softmmu/hw/char/stm32f2xx_usart.o
CC x86_64-softmmu/dump.o
CC x86_64-softmmu/migration/ram.o
CC aarch64-softmmu/hw/char/bcm2835_aux.o
CC aarch64-softmmu/hw/char/virtio-serial-bus.o
CC x86_64-softmmu/hw/block/virtio-blk.o
CC x86_64-softmmu/hw/block/dataplane/virtio-blk.o
CC x86_64-softmmu/hw/char/virtio-serial-bus.o
CC aarch64-softmmu/hw/core/generic-loader.o
CC x86_64-softmmu/hw/core/generic-loader.o
CC x86_64-softmmu/hw/core/null-machine.o
CC aarch64-softmmu/hw/core/null-machine.o
CC x86_64-softmmu/hw/cpu/core.o
CC x86_64-softmmu/hw/display/vga.o
CC aarch64-softmmu/hw/cpu/arm11mpcore.o
CC aarch64-softmmu/hw/cpu/realview_mpcore.o
CC aarch64-softmmu/hw/cpu/a9mpcore.o
CC aarch64-softmmu/hw/cpu/a15mpcore.o
CC aarch64-softmmu/hw/cpu/core.o
CC aarch64-softmmu/hw/display/omap_dss.o
CC x86_64-softmmu/hw/display/virtio-gpu.o
CC aarch64-softmmu/hw/display/omap_lcdc.o
CC aarch64-softmmu/hw/display/pxa2xx_lcd.o
CC aarch64-softmmu/hw/display/bcm2835_fb.o
CC aarch64-softmmu/hw/display/vga.o
CC aarch64-softmmu/hw/display/virtio-gpu-3d.o
CC aarch64-softmmu/hw/display/virtio-gpu.o
CC aarch64-softmmu/hw/display/virtio-gpu-pci.o
CC aarch64-softmmu/hw/display/dpcd.o
CC aarch64-softmmu/hw/display/xlnx_dp.o
CC aarch64-softmmu/hw/dma/xlnx_dpdma.o
CC x86_64-softmmu/hw/display/virtio-gpu-3d.o
CC x86_64-softmmu/hw/display/virtio-gpu-pci.o
CC aarch64-softmmu/hw/dma/omap_dma.o
CC x86_64-softmmu/hw/display/virtio-vga.o
CC x86_64-softmmu/hw/intc/apic.o
CC x86_64-softmmu/hw/intc/apic_common.o
CC x86_64-softmmu/hw/intc/ioapic.o
CC aarch64-softmmu/hw/dma/soc_dma.o
CC x86_64-softmmu/hw/isa/lpc_ich9.o
CC x86_64-softmmu/hw/misc/vmport.o
CC x86_64-softmmu/hw/misc/ivshmem.o
CC x86_64-softmmu/hw/misc/pvpanic.o
CC aarch64-softmmu/hw/dma/pxa2xx_dma.o
CC aarch64-softmmu/hw/dma/bcm2835_dma.o
CC aarch64-softmmu/hw/gpio/omap_gpio.o
CC aarch64-softmmu/hw/gpio/imx_gpio.o
CC x86_64-softmmu/hw/misc/edu.o
CC x86_64-softmmu/hw/misc/hyperv_testdev.o
CC aarch64-softmmu/hw/gpio/bcm2835_gpio.o
CC x86_64-softmmu/hw/net/vhost_net.o
CC x86_64-softmmu/hw/scsi/virtio-scsi.o
CC x86_64-softmmu/hw/net/virtio-net.o
CC x86_64-softmmu/hw/scsi/virtio-scsi-dataplane.o
CC aarch64-softmmu/hw/i2c/omap_i2c.o
CC x86_64-softmmu/hw/scsi/vhost-scsi-common.o
CC aarch64-softmmu/hw/input/pxa2xx_keypad.o
CC x86_64-softmmu/hw/scsi/vhost-scsi.o
CC aarch64-softmmu/hw/input/tsc210x.o
CC aarch64-softmmu/hw/intc/armv7m_nvic.o
CC aarch64-softmmu/hw/intc/exynos4210_gic.o
CC aarch64-softmmu/hw/intc/exynos4210_combiner.o
CC aarch64-softmmu/hw/intc/omap_intc.o
CC x86_64-softmmu/hw/timer/mc146818rtc.o
CC aarch64-softmmu/hw/intc/bcm2835_ic.o
CC aarch64-softmmu/hw/intc/allwinner-a10-pic.o
CC aarch64-softmmu/hw/intc/bcm2836_control.o
CC x86_64-softmmu/hw/vfio/common.o
CC x86_64-softmmu/hw/vfio/pci.o
CC aarch64-softmmu/hw/intc/aspeed_vic.o
CC x86_64-softmmu/hw/vfio/pci-quirks.o
CC aarch64-softmmu/hw/intc/arm_gicv3_cpuif.o
CC x86_64-softmmu/hw/vfio/platform.o
CC x86_64-softmmu/hw/vfio/spapr.o
CC aarch64-softmmu/hw/misc/ivshmem.o
CC aarch64-softmmu/hw/misc/arm_sysctl.o
CC x86_64-softmmu/hw/virtio/virtio.o
CC x86_64-softmmu/hw/virtio/virtio-balloon.o
CC x86_64-softmmu/hw/virtio/vhost.o
CC x86_64-softmmu/hw/virtio/vhost-backend.o
CC aarch64-softmmu/hw/misc/cbus.o
CC aarch64-softmmu/hw/misc/exynos4210_pmu.o
CC x86_64-softmmu/hw/virtio/vhost-user.o
CC x86_64-softmmu/hw/virtio/vhost-vsock.o
CC aarch64-softmmu/hw/misc/exynos4210_clk.o
CC aarch64-softmmu/hw/misc/imx_ccm.o
CC x86_64-softmmu/hw/virtio/virtio-crypto.o
CC x86_64-softmmu/hw/virtio/virtio-crypto-pci.o
CC x86_64-softmmu/hw/i386/multiboot.o
CC aarch64-softmmu/hw/misc/imx31_ccm.o
CC x86_64-softmmu/hw/i386/pc.o
CC aarch64-softmmu/hw/misc/imx25_ccm.o
CC x86_64-softmmu/hw/i386/pc_piix.o
CC aarch64-softmmu/hw/misc/imx6_ccm.o
CC aarch64-softmmu/hw/misc/imx6_src.o
CC aarch64-softmmu/hw/misc/mst_fpga.o
CC aarch64-softmmu/hw/misc/omap_clk.o
CC aarch64-softmmu/hw/misc/omap_gpmc.o
CC x86_64-softmmu/hw/i386/pc_q35.o
CC aarch64-softmmu/hw/misc/omap_l4.o
CC aarch64-softmmu/hw/misc/omap_sdrc.o
CC aarch64-softmmu/hw/misc/omap_tap.o
CC aarch64-softmmu/hw/misc/bcm2835_mbox.o
CC x86_64-softmmu/hw/i386/pc_sysfw.o
CC aarch64-softmmu/hw/misc/bcm2835_property.o
CC aarch64-softmmu/hw/misc/bcm2835_rng.o
CC x86_64-softmmu/hw/i386/x86-iommu.o
CC aarch64-softmmu/hw/misc/zynq_slcr.o
CC aarch64-softmmu/hw/misc/zynq-xadc.o
/tmp/qemu-test/src/hw/i386/pc_piix.c: In function ‘igd_passthrough_isa_bridge_create’:
/tmp/qemu-test/src/hw/i386/pc_piix.c:1067: warning: ‘pch_rev_id’ may be used uninitialized in this function
CC aarch64-softmmu/hw/misc/stm32f2xx_syscfg.o
CC aarch64-softmmu/hw/misc/edu.o
CC x86_64-softmmu/hw/i386/intel_iommu.o
CC aarch64-softmmu/hw/misc/auxbus.o
CC aarch64-softmmu/hw/misc/aspeed_scu.o
CC aarch64-softmmu/hw/misc/aspeed_sdmc.o
CC x86_64-softmmu/hw/i386/amd_iommu.o
CC aarch64-softmmu/hw/net/virtio-net.o
CC aarch64-softmmu/hw/net/vhost_net.o
CC aarch64-softmmu/hw/pcmcia/pxa2xx.o
CC aarch64-softmmu/hw/scsi/virtio-scsi.o
CC aarch64-softmmu/hw/scsi/virtio-scsi-dataplane.o
CC aarch64-softmmu/hw/scsi/vhost-scsi.o
CC aarch64-softmmu/hw/scsi/vhost-scsi-common.o
CC x86_64-softmmu/hw/i386/kvmvapic.o
CC x86_64-softmmu/hw/i386/acpi-build.o
CC aarch64-softmmu/hw/sd/omap_mmc.o
CC aarch64-softmmu/hw/sd/pxa2xx_mmci.o
CC aarch64-softmmu/hw/sd/bcm2835_sdhost.o
CC aarch64-softmmu/hw/ssi/omap_spi.o
CC aarch64-softmmu/hw/ssi/imx_spi.o
CC aarch64-softmmu/hw/timer/exynos4210_mct.o
CC aarch64-softmmu/hw/timer/exynos4210_pwm.o
/tmp/qemu-test/src/hw/i386/acpi-build.c: In function ‘build_append_pci_bus_devices’:
/tmp/qemu-test/src/hw/i386/acpi-build.c:525: warning: ‘notify_method’ may be used uninitialized in this function
CC aarch64-softmmu/hw/timer/exynos4210_rtc.o
CC x86_64-softmmu/hw/i386/pci-assign-load-rom.o
CC aarch64-softmmu/hw/timer/omap_gptimer.o
CC aarch64-softmmu/hw/timer/omap_synctimer.o
CC x86_64-softmmu/hw/i386/kvm/clock.o
CC aarch64-softmmu/hw/timer/pxa2xx_timer.o
CC aarch64-softmmu/hw/timer/digic-timer.o
CC aarch64-softmmu/hw/timer/allwinner-a10-pit.o
CC aarch64-softmmu/hw/usb/tusb6010.o
CC aarch64-softmmu/hw/vfio/common.o
CC aarch64-softmmu/hw/vfio/pci.o
CC aarch64-softmmu/hw/vfio/pci-quirks.o
CC aarch64-softmmu/hw/vfio/platform.o
CC x86_64-softmmu/hw/i386/kvm/apic.o
CC aarch64-softmmu/hw/vfio/calxeda-xgmac.o
CC x86_64-softmmu/hw/i386/kvm/i8259.o
CC aarch64-softmmu/hw/vfio/amd-xgbe.o
CC aarch64-softmmu/hw/vfio/spapr.o
CC aarch64-softmmu/hw/virtio/virtio.o
CC aarch64-softmmu/hw/virtio/virtio-balloon.o
CC aarch64-softmmu/hw/virtio/vhost.o
CC aarch64-softmmu/hw/virtio/vhost-backend.o
CC aarch64-softmmu/hw/virtio/vhost-user.o
CC aarch64-softmmu/hw/virtio/vhost-vsock.o
CC aarch64-softmmu/hw/virtio/virtio-crypto.o
CC aarch64-softmmu/hw/virtio/virtio-crypto-pci.o
CC aarch64-softmmu/hw/arm/boot.o
CC x86_64-softmmu/hw/i386/kvm/ioapic.o
CC x86_64-softmmu/hw/i386/kvm/i8254.o
CC aarch64-softmmu/hw/arm/exynos4_boards.o
CC aarch64-softmmu/hw/arm/collie.o
CC aarch64-softmmu/hw/arm/gumstix.o
CC aarch64-softmmu/hw/arm/highbank.o
CC aarch64-softmmu/hw/arm/digic_boards.o
CC x86_64-softmmu/hw/i386/kvm/pci-assign.o
CC aarch64-softmmu/hw/arm/integratorcp.o
CC x86_64-softmmu/target/i386/translate.o
CC aarch64-softmmu/hw/arm/mainstone.o
CC aarch64-softmmu/hw/arm/musicpal.o
CC aarch64-softmmu/hw/arm/nseries.o
CC x86_64-softmmu/target/i386/helper.o
CC aarch64-softmmu/hw/arm/omap_sx1.o
CC x86_64-softmmu/target/i386/cpu.o
CC x86_64-softmmu/target/i386/bpt_helper.o
CC x86_64-softmmu/target/i386/excp_helper.o
CC aarch64-softmmu/hw/arm/palm.o
CC x86_64-softmmu/target/i386/fpu_helper.o
CC x86_64-softmmu/target/i386/cc_helper.o
CC x86_64-softmmu/target/i386/int_helper.o
CC aarch64-softmmu/hw/arm/spitz.o
CC aarch64-softmmu/hw/arm/realview.o
CC x86_64-softmmu/target/i386/svm_helper.o
CC x86_64-softmmu/target/i386/smm_helper.o
CC x86_64-softmmu/target/i386/misc_helper.o
CC aarch64-softmmu/hw/arm/stellaris.o
CC aarch64-softmmu/hw/arm/tosa.o
CC x86_64-softmmu/target/i386/mem_helper.o
CC x86_64-softmmu/target/i386/seg_helper.o
CC aarch64-softmmu/hw/arm/versatilepb.o
CC x86_64-softmmu/target/i386/mpx_helper.o
CC x86_64-softmmu/target/i386/gdbstub.o
CC x86_64-softmmu/target/i386/machine.o
CC aarch64-softmmu/hw/arm/vexpress.o
CC x86_64-softmmu/target/i386/arch_memory_mapping.o
CC aarch64-softmmu/hw/arm/virt.o
CC x86_64-softmmu/target/i386/arch_dump.o
CC x86_64-softmmu/target/i386/monitor.o
CC x86_64-softmmu/target/i386/kvm.o
CC aarch64-softmmu/hw/arm/xilinx_zynq.o
CC x86_64-softmmu/target/i386/hyperv.o
GEN trace/generated-helpers.c
CC aarch64-softmmu/hw/arm/z2.o
CC x86_64-softmmu/trace/control-target.o
CC x86_64-softmmu/gdbstub-xml.o
CC x86_64-softmmu/trace/generated-helpers.o
CC aarch64-softmmu/hw/arm/virt-acpi-build.o
LINK x86_64-softmmu/qemu-system-x86_64
CC aarch64-softmmu/hw/arm/netduino2.o
CC aarch64-softmmu/hw/arm/sysbus-fdt.o
CC aarch64-softmmu/hw/arm/armv7m.o
CC aarch64-softmmu/hw/arm/exynos4210.o
CC aarch64-softmmu/hw/arm/pxa2xx.o
CC aarch64-softmmu/hw/arm/pxa2xx_gpio.o
CC aarch64-softmmu/hw/arm/pxa2xx_pic.o
CC aarch64-softmmu/hw/arm/digic.o
CC aarch64-softmmu/hw/arm/omap1.o
CC aarch64-softmmu/hw/arm/omap2.o
CC aarch64-softmmu/hw/arm/strongarm.o
CC aarch64-softmmu/hw/arm/allwinner-a10.o
CC aarch64-softmmu/hw/arm/cubieboard.o
CC aarch64-softmmu/hw/arm/bcm2835_peripherals.o
CC aarch64-softmmu/hw/arm/bcm2836.o
CC aarch64-softmmu/hw/arm/raspi.o
CC aarch64-softmmu/hw/arm/stm32f205_soc.o
CC aarch64-softmmu/hw/arm/xlnx-zynqmp.o
CC aarch64-softmmu/hw/arm/xlnx-ep108.o
CC aarch64-softmmu/hw/arm/fsl-imx25.o
CC aarch64-softmmu/hw/arm/imx25_pdk.o
CC aarch64-softmmu/hw/arm/fsl-imx31.o
CC aarch64-softmmu/hw/arm/kzm.o
CC aarch64-softmmu/hw/arm/fsl-imx6.o
CC aarch64-softmmu/hw/arm/sabrelite.o
CC aarch64-softmmu/hw/arm/aspeed_soc.o
CC aarch64-softmmu/hw/arm/aspeed.o
CC aarch64-softmmu/target/arm/arm-semi.o
CC aarch64-softmmu/target/arm/machine.o
CC aarch64-softmmu/target/arm/psci.o
CC aarch64-softmmu/target/arm/arch_dump.o
CC aarch64-softmmu/target/arm/monitor.o
CC aarch64-softmmu/target/arm/kvm-stub.o
CC aarch64-softmmu/target/arm/translate.o
CC aarch64-softmmu/target/arm/op_helper.o
CC aarch64-softmmu/target/arm/helper.o
CC aarch64-softmmu/target/arm/cpu.o
CC aarch64-softmmu/target/arm/neon_helper.o
CC aarch64-softmmu/target/arm/iwmmxt_helper.o
CC aarch64-softmmu/target/arm/gdbstub.o
CC aarch64-softmmu/target/arm/cpu64.o
CC aarch64-softmmu/target/arm/translate-a64.o
CC aarch64-softmmu/target/arm/crypto_helper.o
CC aarch64-softmmu/target/arm/helper-a64.o
CC aarch64-softmmu/target/arm/gdbstub64.o
CC aarch64-softmmu/target/arm/arm-powerctl.o
GEN trace/generated-helpers.c
CC aarch64-softmmu/trace/control-target.o
CC aarch64-softmmu/gdbstub-xml.o
CC aarch64-softmmu/trace/generated-helpers.o
/tmp/qemu-test/src/target/arm/translate-a64.c: In function ‘handle_shri_with_rndacc’:
/tmp/qemu-test/src/target/arm/translate-a64.c:6365: warning: ‘tcg_src_hi’ may be used uninitialized in this function
/tmp/qemu-test/src/target/arm/translate-a64.c: In function ‘disas_simd_scalar_two_reg_misc’:
/tmp/qemu-test/src/target/arm/translate-a64.c:8092: warning: ‘rmode’ may be used uninitialized in this function
LINK aarch64-softmmu/qemu-system-aarch64
LEX convert-dtsv0-lexer.lex.c
BISON dtc-parser.tab.c
make[1]: flex: Command not found
make[1]: bison: Command not found
LEX dtc-lexer.lex.c
make[1]: flex: Command not found
TEST tests/qapi-schema/alternate-clash.out
TEST tests/qapi-schema/alternate-array.out
TEST tests/qapi-schema/alternate-base.out
TEST tests/qapi-schema/alternate-any.out
TEST tests/qapi-schema/alternate-conflict-dict.out
TEST tests/qapi-schema/alternate-conflict-enum-bool.out
TEST tests/qapi-schema/alternate-conflict-enum-int.out
TEST tests/qapi-schema/alternate-conflict-string.out
TEST tests/qapi-schema/alternate-empty.out
TEST tests/qapi-schema/alternate-nested.out
TEST tests/qapi-schema/alternate-unknown.out
TEST tests/qapi-schema/args-alternate.out
TEST tests/qapi-schema/args-array-empty.out
TEST tests/qapi-schema/args-any.out
TEST tests/qapi-schema/args-array-unknown.out
TEST tests/qapi-schema/args-bad-boxed.out
TEST tests/qapi-schema/args-boxed-anon.out
TEST tests/qapi-schema/args-boxed-empty.out
TEST tests/qapi-schema/args-boxed-string.out
TEST tests/qapi-schema/args-int.out
TEST tests/qapi-schema/args-invalid.out
TEST tests/qapi-schema/args-member-case.out
TEST tests/qapi-schema/args-member-array-bad.out
TEST tests/qapi-schema/args-member-unknown.out
TEST tests/qapi-schema/args-name-clash.out
TEST tests/qapi-schema/args-union.out
TEST tests/qapi-schema/args-unknown.out
TEST tests/qapi-schema/bad-base.out
TEST tests/qapi-schema/bad-data.out
TEST tests/qapi-schema/bad-ident.out
TEST tests/qapi-schema/bad-type-bool.out
TEST tests/qapi-schema/bad-type-dict.out
TEST tests/qapi-schema/bad-type-int.out
TEST tests/qapi-schema/base-cycle-direct.out
TEST tests/qapi-schema/base-cycle-indirect.out
TEST tests/qapi-schema/command-int.out
TEST tests/qapi-schema/comments.out
TEST tests/qapi-schema/doc-bad-alternate-member.out
TEST tests/qapi-schema/doc-bad-command-arg.out
TEST tests/qapi-schema/doc-bad-symbol.out
TEST tests/qapi-schema/doc-bad-union-member.out
TEST tests/qapi-schema/doc-before-include.out
TEST tests/qapi-schema/doc-before-pragma.out
TEST tests/qapi-schema/doc-duplicated-arg.out
TEST tests/qapi-schema/doc-duplicated-return.out
TEST tests/qapi-schema/doc-duplicated-since.out
TEST tests/qapi-schema/doc-empty-arg.out
TEST tests/qapi-schema/doc-empty-section.out
TEST tests/qapi-schema/doc-empty-symbol.out
TEST tests/qapi-schema/doc-interleaved-section.out
TEST tests/qapi-schema/doc-good.out
TEST tests/qapi-schema/doc-invalid-end.out
TEST tests/qapi-schema/doc-invalid-end2.out
TEST tests/qapi-schema/doc-invalid-return.out
TEST tests/qapi-schema/doc-invalid-section.out
TEST tests/qapi-schema/doc-missing.out
TEST tests/qapi-schema/doc-invalid-start.out
TEST tests/qapi-schema/doc-missing-colon.out
TEST tests/qapi-schema/doc-missing-expr.out
TEST tests/qapi-schema/doc-missing-space.out
TEST tests/qapi-schema/doc-no-symbol.out
TEST tests/qapi-schema/double-data.out
TEST tests/qapi-schema/double-type.out
TEST tests/qapi-schema/duplicate-key.out
TEST tests/qapi-schema/empty.out
TEST tests/qapi-schema/enum-bad-name.out
TEST tests/qapi-schema/enum-bad-prefix.out
TEST tests/qapi-schema/enum-clash-member.out
TEST tests/qapi-schema/enum-int-member.out
TEST tests/qapi-schema/enum-dict-member.out
TEST tests/qapi-schema/enum-missing-data.out
TEST tests/qapi-schema/enum-member-case.out
TEST tests/qapi-schema/enum-wrong-data.out
TEST tests/qapi-schema/escape-outside-string.out
TEST tests/qapi-schema/escape-too-big.out
TEST tests/qapi-schema/escape-too-short.out
TEST tests/qapi-schema/event-boxed-empty.out
TEST tests/qapi-schema/event-case.out
TEST tests/qapi-schema/event-nest-struct.out
TEST tests/qapi-schema/flat-union-array-branch.out
TEST tests/qapi-schema/flat-union-bad-base.out
TEST tests/qapi-schema/flat-union-bad-discriminator.out
TEST tests/qapi-schema/flat-union-base-any.out
TEST tests/qapi-schema/flat-union-base-union.out
TEST tests/qapi-schema/flat-union-clash-member.out
TEST tests/qapi-schema/flat-union-empty.out
TEST tests/qapi-schema/flat-union-incomplete-branch.out
TEST tests/qapi-schema/flat-union-inline.out
TEST tests/qapi-schema/flat-union-int-branch.out
TEST tests/qapi-schema/flat-union-invalid-branch-key.out
TEST tests/qapi-schema/flat-union-invalid-discriminator.out
TEST tests/qapi-schema/flat-union-no-base.out
TEST tests/qapi-schema/flat-union-optional-discriminator.out
TEST tests/qapi-schema/flat-union-string-discriminator.out
TEST tests/qapi-schema/funny-char.out
TEST tests/qapi-schema/ident-with-escape.out
TEST tests/qapi-schema/include-cycle.out
TEST tests/qapi-schema/include-extra-junk.out
TEST tests/qapi-schema/include-before-err.out
TEST tests/qapi-schema/include-format-err.out
TEST tests/qapi-schema/include-nested-err.out
TEST tests/qapi-schema/include-no-file.out
TEST tests/qapi-schema/include-non-file.out
TEST tests/qapi-schema/include-relpath.out
TEST tests/qapi-schema/include-self-cycle.out
TEST tests/qapi-schema/include-repetition.out
TEST tests/qapi-schema/include-simple.out
TEST tests/qapi-schema/indented-expr.out
TEST tests/qapi-schema/leading-comma-list.out
TEST tests/qapi-schema/leading-comma-object.out
TEST tests/qapi-schema/missing-colon.out
TEST tests/qapi-schema/missing-comma-list.out
TEST tests/qapi-schema/missing-comma-object.out
TEST tests/qapi-schema/missing-type.out
TEST tests/qapi-schema/nested-struct-data.out
TEST tests/qapi-schema/non-objects.out
TEST tests/qapi-schema/pragma-doc-required-crap.out
TEST tests/qapi-schema/pragma-extra-junk.out
TEST tests/qapi-schema/pragma-name-case-whitelist-crap.out
TEST tests/qapi-schema/pragma-non-dict.out
TEST tests/qapi-schema/pragma-returns-whitelist-crap.out
TEST tests/qapi-schema/qapi-schema-test.out
TEST tests/qapi-schema/quoted-structural-chars.out
TEST tests/qapi-schema/redefined-builtin.out
TEST tests/qapi-schema/redefined-command.out
TEST tests/qapi-schema/redefined-event.out
TEST tests/qapi-schema/redefined-type.out
TEST tests/qapi-schema/reserved-command-q.out
TEST tests/qapi-schema/reserved-member-has.out
TEST tests/qapi-schema/reserved-enum-q.out
TEST tests/qapi-schema/reserved-member-q.out
TEST tests/qapi-schema/reserved-member-u.out
TEST tests/qapi-schema/reserved-member-underscore.out
TEST tests/qapi-schema/reserved-type-kind.out
TEST tests/qapi-schema/reserved-type-list.out
TEST tests/qapi-schema/returns-array-bad.out
TEST tests/qapi-schema/returns-alternate.out
TEST tests/qapi-schema/returns-dict.out
TEST tests/qapi-schema/returns-unknown.out
TEST tests/qapi-schema/returns-whitelist.out
TEST tests/qapi-schema/struct-base-clash-deep.out
TEST tests/qapi-schema/struct-base-clash.out
TEST tests/qapi-schema/struct-data-invalid.out
TEST tests/qapi-schema/trailing-comma-list.out
TEST tests/qapi-schema/struct-member-invalid.out
TEST tests/qapi-schema/trailing-comma-object.out
TEST tests/qapi-schema/type-bypass-bad-gen.out
TEST tests/qapi-schema/unclosed-list.out
TEST tests/qapi-schema/unclosed-object.out
TEST tests/qapi-schema/unclosed-string.out
TEST tests/qapi-schema/unicode-str.out
TEST tests/qapi-schema/union-base-empty.out
TEST tests/qapi-schema/union-base-no-discriminator.out
TEST tests/qapi-schema/union-branch-case.out
TEST tests/qapi-schema/union-clash-branches.out
TEST tests/qapi-schema/union-empty.out
TEST tests/qapi-schema/union-invalid-base.out
TEST tests/qapi-schema/union-optional-branch.out
TEST tests/qapi-schema/union-unknown.out
TEST tests/qapi-schema/unknown-escape.out
TEST tests/qapi-schema/unknown-expr-key.out
GEN tests/qapi-schema/doc-good.test.texi
CC tests/check-qdict.o
CC tests/test-char.o
CC tests/check-qfloat.o
CC tests/check-qint.o
CC tests/check-qlist.o
CC tests/check-qstring.o
CC tests/check-qnull.o
CC tests/check-qjson.o
CC tests/test-qobject-output-visitor.o
GEN tests/test-qapi-visit.c
GEN tests/test-qapi-types.c
GEN tests/test-qapi-event.c
GEN tests/test-qmp-introspect.c
CC tests/test-clone-visitor.o
CC tests/test-qobject-input-visitor.o
CC tests/test-qmp-commands.o
GEN tests/test-qmp-marshal.c
CC tests/test-string-input-visitor.o
CC tests/test-string-output-visitor.o
CC tests/test-qmp-event.o
CC tests/test-opts-visitor.o
CC tests/test-coroutine.o
CC tests/iothread.o
CC tests/test-visitor-serialization.o
CC tests/test-iov.o
CC tests/test-aio.o
CC tests/test-aio-multithread.o
CC tests/test-throttle.o
CC tests/test-thread-pool.o
CC tests/test-hbitmap.o
CC tests/test-blockjob-txn.o
CC tests/test-blockjob.o
CC tests/test-x86-cpuid.o
CC tests/test-xbzrle.o
CC tests/test-vmstate.o
CC tests/test-cutils.o
CC tests/test-shift128.o
CC tests/test-mul64.o
CC tests/test-int128.o
CC tests/rcutorture.o
CC tests/test-rcu-list.o
CC tests/test-qdist.o
CC tests/test-qht.o
/tmp/qemu-test/src/tests/test-int128.c:180: warning: ‘__noclone__’ attribute directive ignored
CC tests/qht-bench.o
CC tests/test-qht-par.o
CC tests/test-bitops.o
CC tests/test-bitcnt.o
CC tests/check-qom-interface.o
CC tests/check-qom-proplist.o
CC tests/test-qemu-opts.o
CC tests/test-keyval.o
CC tests/test-write-threshold.o
CC tests/test-crypto-hash.o
/tmp/qemu-test/src/tests/test-throttle.c:144: error: static declaration of ‘read_timer_cb’ follows non-static declaration
/tmp/qemu-test/src/include/block/throttle-groups.h:50: note: previous declaration of ‘read_timer_cb’ was here
/tmp/qemu-test/src/tests/test-throttle.c:148: error: static declaration of ‘write_timer_cb’ follows non-static declaration
/tmp/qemu-test/src/include/block/throttle-groups.h:51: note: previous declaration of ‘write_timer_cb’ was here
make: *** [tests/test-throttle.o] Error 1
make: *** Waiting for unfinished jobs....
tests/docker/Makefile.include:118: recipe for target 'docker-run' failed
make[1]: *** [docker-run] Error 2
make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-1sb30q_4/src'
tests/docker/Makefile.include:149: recipe for target 'docker-run-test-quick@centos6' failed
make: *** [docker-run-test-quick@centos6] Error 2
=== OUTPUT END ===
Test command exited with code: 2
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver
2017-06-11 1:28 ` [Qemu-devel] [PATCH RFC v2 0/2] IO throttling " no-reply
@ 2017-06-11 1:37 ` Manos Pitsidianakis
0 siblings, 0 replies; 7+ messages in thread
From: Manos Pitsidianakis @ 2017-06-11 1:37 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, berto, qemu-block, stefanha
[-- Attachment #1: Type: text/plain, Size: 749 bytes --]
On Sat, Jun 10, 2017 at 06:28:42PM -0700, no-reply@patchew.org wrote:
>Hi,
>/tmp/qemu-test/src/tests/test-throttle.c:144: error: static declaration of ‘read_timer_cb’ follows non-static declaration
>/tmp/qemu-test/src/include/block/throttle-groups.h:50: note: previous declaration of ‘read_timer_cb’ was here
>/tmp/qemu-test/src/tests/test-throttle.c:148: error: static declaration of ‘write_timer_cb’ follows non-static declaration
>/tmp/qemu-test/src/include/block/throttle-groups.h:51: note: previous declaration of ‘write_timer_cb’ was here
>make: *** [tests/test-throttle.o] Error 1
>make: *** Waiting for unfinished jobs....
Looks like I forgot to port a last minute change to test-throttle.c,
will clean it up.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember Manos Pitsidianakis
@ 2017-06-13 8:48 ` Alberto Garcia
2017-06-13 10:01 ` Kevin Wolf
1 sibling, 0 replies; 7+ messages in thread
From: Alberto Garcia @ 2017-06-13 8:48 UTC (permalink / raw)
To: Manos Pitsidianakis, qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, qemu-block
On Sun 11 Jun 2017 03:14:26 AM CEST, Manos Pitsidianakis wrote:
> This commit gathers ThrottleGroup membership details from BlockBackendPublic
> into ThrottleGroupMember and refactors existing code to use the structure.
> --- a/block/throttle-groups.c
> +++ b/block/throttle-groups.c
> @@ -29,43 +29,6 @@
> #include "qemu/thread.h"
> #include "sysemu/qtest.h"
>
> -/* The ThrottleGroup structure (with its ThrottleState) is shared
> - * among different BlockBackends and it's independent from
> - * AioContext, so in order to use it from different threads it needs
> - * its own locking.
> - *
> - * This locking is however handled internally in this file, so it's
> - * transparent to outside users.
> - *
> - * The whole ThrottleGroup structure is private and invisible to
> - * outside users, that only use it through its ThrottleState.
> - *
> - * In addition to the ThrottleGroup structure, BlockBackendPublic has
> - * fields that need to be accessed by other members of the group and
> - * therefore also need to be protected by this lock. Once a
> - * BlockBackend is registered in a group those fields can be accessed
> - * by other threads any time.
> - *
> - * Again, all this is handled internally and is mostly transparent to
> - * the outside. The 'throttle_timers' field however has an additional
> - * constraint because it may be temporarily invalid (see for example
> - * bdrv_set_aio_context()). Therefore in this file a thread will
> - * access some other BlockBackend's timers only after verifying that
> - * that BlockBackend has throttled requests in the queue.
> - */
> -typedef struct ThrottleGroup {
> - char *name; /* This is constant during the lifetime of the group */
> -
> - QemuMutex lock; /* This lock protects the following four fields */
> - ThrottleState ts;
> - QLIST_HEAD(, BlockBackendPublic) head;
> - BlockBackend *tokens[2];
> - bool any_timer_armed[2];
> -
> - /* These two are protected by the global throttle_groups_lock */
> - unsigned refcount;
> - QTAILQ_ENTRY(ThrottleGroup) list;
> -} ThrottleGroup;
Wait a minute, why do you need to move this structure to a header file?
The idea is that ThrottleGroup, its members and locking rules are
handled internally in throttle-groups.c. In particular we don't want to
have to expose this QemuMutex and its locking rules to the outside.
Berto
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember Manos Pitsidianakis
2017-06-13 8:48 ` Alberto Garcia
@ 2017-06-13 10:01 ` Kevin Wolf
1 sibling, 0 replies; 7+ messages in thread
From: Kevin Wolf @ 2017-06-13 10:01 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Alberto Garcia, Stefan Hajnoczi, qemu-block
Am 11.06.2017 um 03:14 hat Manos Pitsidianakis geschrieben:
> This commit gathers ThrottleGroup membership details from BlockBackendPublic
> into ThrottleGroupMember and refactors existing code to use the structure.
>
> Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
> ---
> block/block-backend.c | 75 ++++++----
> block/qapi.c | 8 +-
> block/throttle-groups.c | 305 +++++++++++++++++-----------------------
> blockdev.c | 4 +-
> include/block/throttle-groups.h | 15 +-
> include/qemu/throttle.h | 64 +++++++++
> include/sysemu/block-backend.h | 22 +--
> tests/test-throttle.c | 53 +++----
> util/throttle.c | 5 +
> 9 files changed, 293 insertions(+), 258 deletions(-)
>
> diff --git a/block/block-backend.c b/block/block-backend.c
> index f3a60081a7..1d6b35c34d 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -209,6 +209,7 @@ static const BdrvChildRole child_root = {
> BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
> {
> BlockBackend *blk;
> + BlockBackendPublic *blkp;
>
> blk = g_new0(BlockBackend, 1);
> blk->refcnt = 1;
> @@ -216,8 +217,9 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
> blk->shared_perm = shared_perm;
> blk_set_enable_write_cache(blk, true);
>
> - qemu_co_queue_init(&blk->public.throttled_reqs[0]);
> - qemu_co_queue_init(&blk->public.throttled_reqs[1]);
> + blkp = blk_get_public(blk);
> + qemu_co_queue_init(&blkp->throttle_group_member.throttled_reqs[0]);
> + qemu_co_queue_init(&blkp->throttle_group_member.throttled_reqs[1]);
>
> notifier_list_init(&blk->remove_bs_notifiers);
> notifier_list_init(&blk->insert_bs_notifiers);
> @@ -284,7 +286,7 @@ static void blk_delete(BlockBackend *blk)
> assert(!blk->refcnt);
> assert(!blk->name);
> assert(!blk->dev);
> - if (blk->public.throttle_state) {
> + if (blk_get_public(blk)->throttle_group_member.throttle_state) {
> blk_io_limits_disable(blk);
> }
> if (blk->root) {
Is there a reason why you need to go from blk->public to
blk_get_public()? We're inside block-backend.c here, so I don't really
see the point of using a wrapper function. Other places use the function
because the struct definition of BlockBackend isn't visible to them.
Anyway, even if his did improve the code, we really try to have strictly
one change per patch. So factoring things out of BlockBackendPublic into
ThrottleGroupMember would be one patch, and using blk_get_public() would
be another one. Reasons for this include that it's much easier to review
when a patch does only one change, and that if something breaks,
bisecting directly leads to the problematic change.
> @@ -596,8 +598,10 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
> void blk_remove_bs(BlockBackend *blk)
> {
> notifier_list_notify(&blk->remove_bs_notifiers, blk);
> - if (blk->public.throttle_state) {
> - throttle_timers_detach_aio_context(&blk->public.throttle_timers);
> + BlockBackendPublic *blkp = blk_get_public(blk);
Please make sure that declarations are always at the top of the block
(though again I'm not sure why we're using blk_get_public()).
> + if (blkp->throttle_group_member.throttle_state) {
> + ThrottleTimers *tt = &blkp->throttle_group_member.throttle_timers;
> + throttle_timers_detach_aio_context(tt);
> }
>
> blk_update_root_state(blk);
> /* should be called before blk_set_io_limits if a limit is set */
> void blk_io_limits_enable(BlockBackend *blk, const char *group)
> {
> - assert(!blk->public.throttle_state);
> - throttle_group_register_blk(blk, group);
> + BlockBackendPublic *blkp = blk_get_public(blk);
> +
> + assert(!blkp->throttle_group_member.throttle_state);
> +
> + blkp->throttle_group_member.aio_context = blk_get_aio_context(blk);
> + throttle_group_register_tgm(&blkp->throttle_group_member, group);
> }
The aio_context assignment here is new and doesn't seem to be related to
the refactoring work that the commit message advertises. Refactoring
patches should be as mechanical as possible.
If this is needed, it should be in a separate patch where the commit
message explains why the change is made.
> void blk_io_limits_update_group(BlockBackend *blk, const char *group)
> {
> + BlockBackendPublic *blkp = blk_get_public(blk);
> /* this BB is not part of any group */
> - if (!blk->public.throttle_state) {
> + if (!blkp->throttle_group_member.throttle_state) {
> return;
> }
>
> /* this BB is a part of the same group than the one we want */
> - if (!g_strcmp0(throttle_group_get_name(blk), group)) {
> + if (!g_strcmp0(throttle_group_get_name(&blkp->throttle_group_member),
> + group)) {
This looks like refactoring, but not related to extracting fields from
BlockBackendPublic into ThrottleGroupMember.
Changing the argument of throttle_group_get_name() and similar functions
from BlockBackend to ThrottleGroupMember isn't strictly required for the
creation of ThrottleGroupMember, so it should be a separate patch.
> return;
> }
>
> --- a/block/throttle-groups.c
> +++ b/block/throttle-groups.c
> @@ -29,43 +29,6 @@
> #include "qemu/thread.h"
> #include "sysemu/qtest.h"
>
> -/* The ThrottleGroup structure (with its ThrottleState) is shared
> - * among different BlockBackends and it's independent from
> - * AioContext, so in order to use it from different threads it needs
> - * its own locking.
> - *
> - * This locking is however handled internally in this file, so it's
> - * transparent to outside users.
> - *
> - * The whole ThrottleGroup structure is private and invisible to
> - * outside users, that only use it through its ThrottleState.
> - *
> - * In addition to the ThrottleGroup structure, BlockBackendPublic has
> - * fields that need to be accessed by other members of the group and
> - * therefore also need to be protected by this lock. Once a
> - * BlockBackend is registered in a group those fields can be accessed
> - * by other threads any time.
> - *
> - * Again, all this is handled internally and is mostly transparent to
> - * the outside. The 'throttle_timers' field however has an additional
> - * constraint because it may be temporarily invalid (see for example
> - * bdrv_set_aio_context()). Therefore in this file a thread will
> - * access some other BlockBackend's timers only after verifying that
> - * that BlockBackend has throttled requests in the queue.
> - */
> -typedef struct ThrottleGroup {
> - char *name; /* This is constant during the lifetime of the group */
> -
> - QemuMutex lock; /* This lock protects the following four fields */
> - ThrottleState ts;
> - QLIST_HEAD(, BlockBackendPublic) head;
> - BlockBackend *tokens[2];
> - bool any_timer_armed[2];
> -
> - /* These two are protected by the global throttle_groups_lock */
> - unsigned refcount;
> - QTAILQ_ENTRY(ThrottleGroup) list;
> -} ThrottleGroup;
What Berto said. The comment explicitly says that this struct is
private, so preferably it shouldn't be moved to a header file, or if we
have to, the comment needs to be changed.
I see that you access it only in one place in block/throttle.c. Wouldn't
it be possible to just export helper functions in throttle-groups.c so
that the struct can stay private?
> --- a/util/throttle.c
> +++ b/util/throttle.c
> @@ -185,6 +185,9 @@ static bool throttle_compute_timer(ThrottleState *ts,
> void throttle_timers_attach_aio_context(ThrottleTimers *tt,
> AioContext *new_context)
> {
> + ThrottleGroupMember *tgm = container_of(tt, ThrottleGroupMember, throttle_timers);
> + tgm->aio_context = new_context;
> +
> tt->timers[0] = aio_timer_new(new_context, tt->clock_type, SCALE_NS,
> tt->read_timer_cb, tt->timer_opaque);
> tt->timers[1] = aio_timer_new(new_context, tt->clock_type, SCALE_NS,
> @@ -241,6 +244,8 @@ static void throttle_timer_destroy(QEMUTimer **timer)
> /* Remove timers from event loop */
> void throttle_timers_detach_aio_context(ThrottleTimers *tt)
> {
> + ThrottleGroupMember *tgm = container_of(tt, ThrottleGroupMember, throttle_timers);
> + tgm->aio_context = NULL;
> int i;
This part looks unrelated again.
Kevin
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-06-13 10:01 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-11 1:14 [Qemu-devel] [PATCH RFC v2 0/2] IO throttling block filter driver Manos Pitsidianakis
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 1/2] block: move ThrottleGroup membership to ThrottleGroupMember Manos Pitsidianakis
2017-06-13 8:48 ` Alberto Garcia
2017-06-13 10:01 ` Kevin Wolf
2017-06-11 1:14 ` [Qemu-devel] [PATCH RFC v2 2/2] block: add throttle block filter driver Manos Pitsidianakis
2017-06-11 1:28 ` [Qemu-devel] [PATCH RFC v2 0/2] IO throttling " no-reply
2017-06-11 1:37 ` Manos Pitsidianakis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).