From: Fam Zheng <famz@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: stefanha@redhat.com, qemu-devel@nongnu.org, qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 03/16] block: introduce bdrv_no_throttling_begin/end
Date: Wed, 9 Mar 2016 09:45:46 +0800 [thread overview]
Message-ID: <20160309014546.GC17947@ad.usersys.redhat.com> (raw)
In-Reply-To: <1455645388-32401-4-git-send-email-pbonzini@redhat.com>
On Tue, 02/16 18:56, Paolo Bonzini wrote:
> Extract the handling of throttling from bdrv_flush_io_queue.
Looks good overall. Have two questions below.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> block.c | 1 -
> block/io.c | 56 +++++++++++++++++++++++++++++------------------
> block/throttle-groups.c | 4 ++++
> include/block/block_int.h | 6 ++---
> 4 files changed, 42 insertions(+), 25 deletions(-)
>
> diff --git a/block.c b/block.c
> index efc3c43..b4f328f 100644
> --- a/block.c
> +++ b/block.c
> @@ -2314,7 +2314,6 @@ static void swap_feature_fields(BlockDriverState *bs_top,
>
> assert(!bs_new->throttle_state);
> if (bs_top->throttle_state) {
> - assert(bs_top->io_limits_enabled);
> bdrv_io_limits_enable(bs_new, throttle_group_get_name(bs_top));
> bdrv_io_limits_disable(bs_top);
> }
> diff --git a/block/io.c b/block/io.c
> index 5ee5032..272caac 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -69,28 +69,43 @@ void bdrv_set_io_limits(BlockDriverState *bs,
> throttle_group_config(bs, cfg);
> }
>
> -static void bdrv_start_throttled_reqs(BlockDriverState *bs)
> +static void bdrv_no_throttling_begin(BlockDriverState *bs)
> {
> - bool enabled = bs->io_limits_enabled;
> + BdrvChild *child;
> +
> + QLIST_FOREACH(child, &bs->children, next) {
> + bdrv_no_throttling_begin(child->bs);
> + }
>
> - bs->io_limits_enabled = false;
> - throttle_group_restart_bs(bs);
> - bs->io_limits_enabled = enabled;
> + if (bs->io_limits_disabled++ == 0) {
> + throttle_group_restart_bs(bs);
> + }
> +}
> +
> +static void bdrv_no_throttling_end(BlockDriverState *bs)
> +{
> + BdrvChild *child;
> +
> + --bs->io_limits_disabled;
> +
> + QLIST_FOREACH(child, &bs->children, next) {
> + bdrv_no_throttling_end(child->bs);
> + }
> }
>
> void bdrv_io_limits_disable(BlockDriverState *bs)
> {
> - bs->io_limits_enabled = false;
> - bdrv_start_throttled_reqs(bs);
> + assert(bs->throttle_state);
> + bdrv_no_throttling_begin(bs);
> throttle_group_unregister_bs(bs);
> + bdrv_no_throttling_end(bs);
> }
>
> /* should be called before bdrv_set_io_limits if a limit is set */
> void bdrv_io_limits_enable(BlockDriverState *bs, const char *group)
> {
> - assert(!bs->io_limits_enabled);
> + assert(!bs->throttle_state);
> throttle_group_register_bs(bs, group);
> - bs->io_limits_enabled = true;
> }
>
> void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group)
> @@ -255,6 +270,7 @@ void bdrv_drain(BlockDriverState *bs)
> {
> bool busy = true;
>
> + bdrv_no_throttling_begin(bs);
> bdrv_drain_recurse(bs);
> while (busy) {
> /* Keep iterating */
> @@ -262,6 +278,7 @@ void bdrv_drain(BlockDriverState *bs)
> busy = bdrv_requests_pending(bs);
> busy |= aio_poll(bdrv_get_aio_context(bs), busy);
> }
> + bdrv_no_throttling_end(bs);
> }
>
> /*
> @@ -284,6 +301,7 @@ void bdrv_drain_all(void)
> if (bs->job) {
> block_job_pause(bs->job);
> }
> + bdrv_no_throttling_begin(bs);
> bdrv_drain_recurse(bs);
> aio_context_release(aio_context);
>
> @@ -325,6 +343,7 @@ void bdrv_drain_all(void)
> AioContext *aio_context = bdrv_get_aio_context(bs);
>
> aio_context_acquire(aio_context);
> + bdrv_no_throttling_end(bs);
> if (bs->job) {
> block_job_resume(bs->job);
> }
> @@ -555,11 +574,7 @@ static int bdrv_prwv_co(BlockDriverState *bs, int64_t offset,
> * will not fire; so the I/O throttling function has to be disabled here
> * if it has been enabled.
> */
> - if (bs->io_limits_enabled) {
> - fprintf(stderr, "Disabling I/O throttling on '%s' due "
> - "to synchronous I/O.\n", bdrv_get_device_name(bs));
> - bdrv_io_limits_disable(bs);
> - }
> + bdrv_no_throttling_begin(bs);
>
> if (qemu_in_coroutine()) {
> /* Fast-path if already in coroutine context */
> @@ -573,6 +588,8 @@ static int bdrv_prwv_co(BlockDriverState *bs, int64_t offset,
> aio_poll(aio_context, true);
> }
> }
> +
> + bdrv_no_throttling_end(bs);
Does this change the behavior? There wasn't a bdrv_io_limits_enable() here, and
the throttle doesn't come back automatically. Just want to make sure it's
intended.
> return rwco.ret;
> }
>
> @@ -608,13 +625,11 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num,
> int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
> uint8_t *buf, int nb_sectors)
> {
> - bool enabled;
> int ret;
>
> - enabled = bs->io_limits_enabled;
> - bs->io_limits_enabled = false;
> + bdrv_no_throttling_begin(bs);
> ret = bdrv_read(bs, sector_num, buf, nb_sectors);
> - bs->io_limits_enabled = enabled;
> + bdrv_no_throttling_end(bs);
> return ret;
> }
>
> @@ -952,7 +967,7 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
> }
>
> /* throttling disk I/O */
> - if (bs->io_limits_enabled) {
> + if (bs->throttle_state) {
> throttle_group_co_io_limits_intercept(bs, bytes, false);
> }
>
> @@ -1294,7 +1309,7 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
> }
>
> /* throttling disk I/O */
> - if (bs->io_limits_enabled) {
> + if (bs->throttle_state) {
> throttle_group_co_io_limits_intercept(bs, bytes, true);
> }
>
> @@ -2749,7 +2764,6 @@ void bdrv_flush_io_queue(BlockDriverState *bs)
> } else if (bs->file) {
> bdrv_flush_io_queue(bs->file->bs);
> }
> - bdrv_start_throttled_reqs(bs);
> }
>
> void bdrv_drained_begin(BlockDriverState *bs)
> diff --git a/block/throttle-groups.c b/block/throttle-groups.c
> index eccfc0d..8fe0a4f 100644
> --- a/block/throttle-groups.c
> +++ b/block/throttle-groups.c
> @@ -219,6 +219,10 @@ static bool throttle_group_schedule_timer(BlockDriverState *bs,
> ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
> bool must_wait;
>
> + if (bs->io_limits_disabled) {
> + return false;
> + }
> +
Before, this function and its direct caller
throttle_group_co_io_limits_intercept are not called if !bs->io_limits_enabled,
so the accounting is not done. It's better, but just different.
Thanks,
Fam
> /* Check if any of the timers in this group is already armed */
> if (tg->any_timer_armed[is_write]) {
> return true;
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index 9ef823a..ed2e034 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -412,10 +412,10 @@ struct BlockDriverState {
>
> /* I/O throttling.
> * throttle_state tells us if this BDS has I/O limits configured.
> - * io_limits_enabled tells us if they are currently being
> - * enforced, but it can be temporarily set to false */
> + * io_limits_disabled tells us if they are currently being enforced */
> CoQueue throttled_reqs[2];
> - bool io_limits_enabled;
> + unsigned int io_limits_disabled;
> +
> /* The following fields are protected by the ThrottleGroup lock.
> * See the ThrottleGroup documentation for details. */
> ThrottleState *throttle_state;
> --
> 2.5.0
>
>
>
next prev parent reply other threads:[~2016-03-09 1:46 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-16 17:56 [Qemu-devel] [PATCH 00/16] AioContext fine-grained locking, part 1 of 3, including bdrv_drain rewrite Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 01/16] block: make bdrv_start_throttled_reqs return void Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 02/16] block: move restarting of throttled reqs to block/throttle-groups.c Paolo Bonzini
2016-03-09 1:26 ` Fam Zheng
2016-03-09 7:37 ` Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 03/16] block: introduce bdrv_no_throttling_begin/end Paolo Bonzini
2016-03-09 1:45 ` Fam Zheng [this message]
2016-03-09 7:40 ` Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 04/16] block: plug whole tree at once, introduce bdrv_io_unplugged_begin/end Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 05/16] mirror: use bottom half to re-enter coroutine Paolo Bonzini
2016-03-09 3:19 ` Fam Zheng
2016-03-09 7:41 ` Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 06/16] block: add BDS field to count in-flight requests Paolo Bonzini
2016-03-09 3:35 ` Fam Zheng
2016-03-09 7:43 ` Paolo Bonzini
2016-03-09 8:00 ` Fam Zheng
2016-03-09 8:22 ` Paolo Bonzini
2016-03-09 8:33 ` Fam Zheng
2016-02-16 17:56 ` [Qemu-devel] [PATCH 07/16] block: change drain to look only at one child at a time Paolo Bonzini
2016-03-09 3:41 ` Fam Zheng
2016-03-09 7:49 ` Paolo Bonzini
2016-03-16 16:39 ` Stefan Hajnoczi
2016-03-16 17:41 ` Paolo Bonzini
2016-03-17 0:57 ` Fam Zheng
2016-02-16 17:56 ` [Qemu-devel] [PATCH 08/16] blockjob: introduce .drain callback for jobs Paolo Bonzini
2016-03-16 17:56 ` Stefan Hajnoczi
2016-02-16 17:56 ` [Qemu-devel] [PATCH 09/16] block: wait for all pending I/O when doing synchronous requests Paolo Bonzini
2016-03-09 8:13 ` Fam Zheng
2016-03-09 8:23 ` Paolo Bonzini
2016-03-16 18:04 ` Stefan Hajnoczi
2016-02-16 17:56 ` [Qemu-devel] [PATCH 10/16] nfs: replace aio_poll with bdrv_drain Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 11/16] sheepdog: disable dataplane Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 12/16] aio: introduce aio_context_in_iothread Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 13/16] block: only call aio_poll from iothread Paolo Bonzini
2016-03-09 8:30 ` Fam Zheng
2016-03-09 8:55 ` Paolo Bonzini
2016-03-09 9:10 ` Paolo Bonzini
2016-03-09 9:27 ` Fam Zheng
2016-02-16 17:56 ` [Qemu-devel] [PATCH 14/16] iothread: release AioContext around aio_poll Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 15/16] qemu-thread: introduce QemuRecMutex Paolo Bonzini
2016-02-16 17:56 ` [Qemu-devel] [PATCH 16/16] aio: convert from RFifoLock to QemuRecMutex Paolo Bonzini
2016-03-08 17:51 ` [Qemu-devel] [PATCH 00/16] AioContext fine-grained locking, part 1 of 3, including bdrv_drain rewrite Paolo Bonzini
2016-03-09 8:46 ` Fam Zheng
2016-03-16 18:18 ` Stefan Hajnoczi
2016-03-16 22:29 ` Paolo Bonzini
2016-03-17 13:44 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2016-03-17 13:48 ` Paolo Bonzini
2016-03-18 15:49 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160309014546.GC17947@ad.usersys.redhat.com \
--to=famz@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.