Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-reques…
Browse files Browse the repository at this point in the history
…t' into staging

# gpg: Signature made Fri Jun 12 15:57:47 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request:
  qemu-iotests: expand test 093 to support group throttling
  throttle: Update throttle infrastructure copyright
  throttle: add the name of the ThrottleGroup to BlockDeviceInfo
  throttle: acquire the ThrottleGroup lock in bdrv_swap()
  throttle: Add throttle group support
  throttle: Add throttle group infrastructure tests
  throttle: Add throttle group infrastructure
  throttle: Extract timers from ThrottleState into a separate structure
  raw-posix: Fix .bdrv_co_get_block_status() for unaligned image size
  Revert "iothread: release iothread around aio_poll"

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jun 12, 2015
2 parents 0a2df85 + 2db33f8 commit 8aeaa05
Show file tree
Hide file tree
Showing 21 changed files with 956 additions and 221 deletions.
8 changes: 7 additions & 1 deletion async.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ static void aio_timerlist_notify(void *opaque)
aio_notify(opaque);
}

static void aio_rfifolock_cb(void *opaque)
{
/* Kick owner thread in case they are blocked in aio_poll() */
aio_notify(opaque);
}

AioContext *aio_context_new(Error **errp)
{
int ret;
Expand All @@ -297,7 +303,7 @@ AioContext *aio_context_new(Error **errp)
event_notifier_test_and_clear);
ctx->thread_pool = NULL;
qemu_mutex_init(&ctx->bh_lock);
rfifolock_init(&ctx->lock, NULL, NULL);
rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);

return ctx;
Expand Down
38 changes: 30 additions & 8 deletions block.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "qmp-commands.h"
#include "qemu/timer.h"
#include "qapi-event.h"
#include "block/throttle-groups.h"

#ifdef CONFIG_BSD
#include <sys/types.h>
Expand Down Expand Up @@ -1822,12 +1823,18 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
bs_dest->enable_write_cache = bs_src->enable_write_cache;

/* i/o throttled req */
memcpy(&bs_dest->throttle_state,
&bs_src->throttle_state,
sizeof(ThrottleState));
bs_dest->throttle_state = bs_src->throttle_state,
bs_dest->io_limits_enabled = bs_src->io_limits_enabled;
bs_dest->pending_reqs[0] = bs_src->pending_reqs[0];
bs_dest->pending_reqs[1] = bs_src->pending_reqs[1];
bs_dest->throttled_reqs[0] = bs_src->throttled_reqs[0];
bs_dest->throttled_reqs[1] = bs_src->throttled_reqs[1];
bs_dest->io_limits_enabled = bs_src->io_limits_enabled;
memcpy(&bs_dest->round_robin,
&bs_src->round_robin,
sizeof(bs_dest->round_robin));
memcpy(&bs_dest->throttle_timers,
&bs_src->throttle_timers,
sizeof(ThrottleTimers));

/* r/w error */
bs_dest->on_read_error = bs_src->on_read_error;
Expand Down Expand Up @@ -1881,12 +1888,21 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
QTAILQ_REMOVE(&graph_bdrv_states, bs_old, node_list);
}

/* If the BlockDriverState is part of a throttling group acquire
* its lock since we're going to mess with the protected fields.
* Otherwise there's no need to worry since no one else can touch
* them. */
if (bs_old->throttle_state) {
throttle_group_lock(bs_old);
}

/* bs_new must be unattached and shouldn't have anything fancy enabled */
assert(!bs_new->blk);
assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
assert(bs_new->job == NULL);
assert(bs_new->io_limits_enabled == false);
assert(!throttle_have_timer(&bs_new->throttle_state));
assert(bs_new->throttle_state == NULL);
assert(!throttle_timers_are_initialized(&bs_new->throttle_timers));

tmp = *bs_new;
*bs_new = *bs_old;
Expand All @@ -1903,7 +1919,13 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
/* Check a few fields that should remain attached to the device */
assert(bs_new->job == NULL);
assert(bs_new->io_limits_enabled == false);
assert(!throttle_have_timer(&bs_new->throttle_state));
assert(bs_new->throttle_state == NULL);
assert(!throttle_timers_are_initialized(&bs_new->throttle_timers));

/* Release the ThrottleGroup lock */
if (bs_old->throttle_state) {
throttle_group_unlock(bs_old);
}

/* insert the nodes back into the graph node list if needed */
if (bs_new->node_name[0] != '\0') {
Expand Down Expand Up @@ -3691,7 +3713,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
}

if (bs->io_limits_enabled) {
throttle_detach_aio_context(&bs->throttle_state);
throttle_timers_detach_aio_context(&bs->throttle_timers);
}
if (bs->drv->bdrv_detach_aio_context) {
bs->drv->bdrv_detach_aio_context(bs);
Expand Down Expand Up @@ -3727,7 +3749,7 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
bs->drv->bdrv_attach_aio_context(bs, new_context);
}
if (bs->io_limits_enabled) {
throttle_attach_aio_context(&bs->throttle_state, new_context);
throttle_timers_attach_aio_context(&bs->throttle_timers, new_context);
}

QLIST_FOREACH(ban, &bs->aio_notifiers, list) {
Expand Down
1 change: 1 addition & 0 deletions block/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
block-obj-$(CONFIG_POSIX) += raw-posix.o
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
block-obj-y += null.o mirror.o io.o
block-obj-y += throttle-groups.o

block-obj-y += nbd.o nbd-client.o sheepdog.o
block-obj-$(CONFIG_LIBISCSI) += iscsi.o
Expand Down
71 changes: 16 additions & 55 deletions block/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
*/

#include "trace.h"
#include "sysemu/qtest.h"
#include "block/blockjob.h"
#include "block/block_int.h"
#include "block/throttle-groups.h"

#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */

Expand Down Expand Up @@ -65,7 +65,7 @@ void bdrv_set_io_limits(BlockDriverState *bs,
{
int i;

throttle_config(&bs->throttle_state, cfg);
throttle_group_config(bs, cfg);

for (i = 0; i < 2; i++) {
qemu_co_enter_next(&bs->throttled_reqs[i]);
Expand Down Expand Up @@ -95,72 +95,33 @@ static bool bdrv_start_throttled_reqs(BlockDriverState *bs)
void bdrv_io_limits_disable(BlockDriverState *bs)
{
bs->io_limits_enabled = false;

bdrv_start_throttled_reqs(bs);

throttle_destroy(&bs->throttle_state);
}

static void bdrv_throttle_read_timer_cb(void *opaque)
{
BlockDriverState *bs = opaque;
qemu_co_enter_next(&bs->throttled_reqs[0]);
}

static void bdrv_throttle_write_timer_cb(void *opaque)
{
BlockDriverState *bs = opaque;
qemu_co_enter_next(&bs->throttled_reqs[1]);
throttle_group_unregister_bs(bs);
}

/* should be called before bdrv_set_io_limits if a limit is set */
void bdrv_io_limits_enable(BlockDriverState *bs)
void bdrv_io_limits_enable(BlockDriverState *bs, const char *group)
{
int clock_type = QEMU_CLOCK_REALTIME;

if (qtest_enabled()) {
/* For testing block IO throttling only */
clock_type = QEMU_CLOCK_VIRTUAL;
}
assert(!bs->io_limits_enabled);
throttle_init(&bs->throttle_state,
bdrv_get_aio_context(bs),
clock_type,
bdrv_throttle_read_timer_cb,
bdrv_throttle_write_timer_cb,
bs);
throttle_group_register_bs(bs, group);
bs->io_limits_enabled = true;
}

/* This function makes an IO wait if needed
*
* @nb_sectors: the number of sectors of the IO
* @is_write: is the IO a write
*/
static void bdrv_io_limits_intercept(BlockDriverState *bs,
unsigned int bytes,
bool is_write)
void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group)
{
/* does this io must wait */
bool must_wait = throttle_schedule_timer(&bs->throttle_state, is_write);

/* if must wait or any request of this type throttled queue the IO */
if (must_wait ||
!qemu_co_queue_empty(&bs->throttled_reqs[is_write])) {
qemu_co_queue_wait(&bs->throttled_reqs[is_write]);
/* this bs is not part of any group */
if (!bs->throttle_state) {
return;
}

/* the IO will be executed, do the accounting */
throttle_account(&bs->throttle_state, is_write, bytes);


/* if the next request must wait -> do nothing */
if (throttle_schedule_timer(&bs->throttle_state, is_write)) {
/* this bs is a part of the same group than the one we want */
if (!g_strcmp0(throttle_group_get_name(bs), group)) {
return;
}

/* else queue next request for execution */
qemu_co_queue_next(&bs->throttled_reqs[is_write]);
/* need to change the group this bs belong to */
bdrv_io_limits_disable(bs);
bdrv_io_limits_enable(bs, group);
}

void bdrv_setup_io_funcs(BlockDriver *bdrv)
Expand Down Expand Up @@ -967,7 +928,7 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,

/* throttling disk I/O */
if (bs->io_limits_enabled) {
bdrv_io_limits_intercept(bs, bytes, false);
throttle_group_co_io_limits_intercept(bs, bytes, false);
}

/* Align read if necessary by padding qiov */
Expand Down Expand Up @@ -1297,7 +1258,7 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,

/* throttling disk I/O */
if (bs->io_limits_enabled) {
bdrv_io_limits_intercept(bs, bytes, true);
throttle_group_co_io_limits_intercept(bs, bytes, true);
}

/*
Expand Down
8 changes: 7 additions & 1 deletion block/qapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "block/qapi.h"
#include "block/block_int.h"
#include "block/throttle-groups.h"
#include "block/write-threshold.h"
#include "qmp-commands.h"
#include "qapi-visit.h"
Expand Down Expand Up @@ -65,7 +66,9 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs, Error **errp)

if (bs->io_limits_enabled) {
ThrottleConfig cfg;
throttle_get_config(&bs->throttle_state, &cfg);

throttle_group_get_config(bs, &cfg);

info->bps = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
info->bps_rd = cfg.buckets[THROTTLE_BPS_READ].avg;
info->bps_wr = cfg.buckets[THROTTLE_BPS_WRITE].avg;
Expand All @@ -90,6 +93,9 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs, Error **errp)

info->has_iops_size = cfg.op_size;
info->iops_size = cfg.op_size;

info->has_group = true;
info->group = g_strdup(throttle_group_get_name(bs));
}

info->write_threshold = bdrv_write_threshold_get(bs);
Expand Down
5 changes: 3 additions & 2 deletions block/raw-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1848,8 +1848,9 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
*pnum = nb_sectors;
ret = BDRV_BLOCK_DATA;
} else if (data == start) {
/* On a data extent, compute sectors to the end of the extent. */
*pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
/* On a data extent, compute sectors to the end of the extent,
* possibly including a partial sector at EOF. */
*pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE));
ret = BDRV_BLOCK_DATA;
} else {
/* On a hole, compute sectors to the beginning of the next extent. */
Expand Down
Loading

0 comments on commit 8aeaa05

Please sign in to comment.