From patchwork Tue Mar 22 15:33:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 8643841 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B3EC29F44D for ; Tue, 22 Mar 2016 15:41:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D96762014A for ; Tue, 22 Mar 2016 15:41:24 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4F15E20340 for ; Tue, 22 Mar 2016 15:41:23 +0000 (UTC) Received: from localhost ([::1]:37894 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aiOQs-0002wg-OR for patchwork-qemu-devel@patchwork.kernel.org; Tue, 22 Mar 2016 11:41:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54176) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aiOJb-0006ls-E4 for qemu-devel@nongnu.org; Tue, 22 Mar 2016 11:33:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aiOJW-0003m2-GP for qemu-devel@nongnu.org; Tue, 22 Mar 2016 11:33:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60930) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aiOJQ-0003ii-FO; Tue, 22 Mar 2016 11:33:40 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 1F59D6447F; Tue, 22 Mar 2016 15:33:40 +0000 (UTC) Received: from noname.redhat.com (ovpn-116-53.ams2.redhat.com [10.36.116.53]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u2MFXNXs020137; Tue, 22 Mar 2016 11:33:38 -0400 From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 22 Mar 2016 16:33:10 +0100 Message-Id: <1458660792-3035-11-git-send-email-kwolf@redhat.com> In-Reply-To: <1458660792-3035-1-git-send-email-kwolf@redhat.com> References: <1458660792-3035-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 22 Mar 2016 15:33:40 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, berto@igalia.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 10/12] block: Drain throttling queue with BdrvChild callback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This removes the last part of I/O throttling from block/io.c and moves it to the BlockBackend. When draining the queue of a BlockDriverState, we must make sure that no new requests can come in for it. Request sources from outside the block layer are disabled with aio_disable_external(), but the throttling queue must be handled separately. The two obvious options we have are either to implement a similar mechanism in BlockBackend that queues requests and avoids to pass them to the BDS, or to flush the whole queue. The first option seems nicer and could prevent bypassing the I/O limit, but the second is closer to what we're already doing on the BDS level, so this patch keeps it this way for now. Signed-off-by: Kevin Wolf --- block/block-backend.c | 29 +++++++++++++++++++++++++++-- block/io.c | 35 ++++++++--------------------------- include/block/block_int.h | 4 ++-- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index d2bd268..c71ce4d 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -90,9 +90,12 @@ static void blk_root_inherit_options(int *child_flags, QDict *child_options, /* We're not supposed to call this function for root nodes */ abort(); } +static bool blk_drain_throttling_queue(BdrvChild *child); static const BdrvChildRole child_root = { - .inherit_options = blk_root_inherit_options, + .inherit_options = blk_root_inherit_options, + + .drain_queue = blk_drain_throttling_queue, }; /* @@ -1677,7 +1680,7 @@ void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg) void blk_io_limits_disable(BlockBackend *blk) { blk->public.io_limits_enabled = false; - bdrv_start_throttled_reqs(blk_bs(blk)); + blk_drain_throttling_queue(blk->root); throttle_group_unregister_blk(blk); } @@ -1705,3 +1708,25 @@ void blk_io_limits_update_group(BlockBackend *blk, const char *group) blk_io_limits_disable(blk); blk_io_limits_enable(blk, group); } + +/* this function drain all the throttled IOs */ +static bool blk_drain_throttling_queue(BdrvChild *child) +{ + BlockBackend *blk = child->opaque; + BlockBackendPublic *blkp = &blk->public; + bool drained = false; + bool enabled = blkp->io_limits_enabled; + int i; + + blkp->io_limits_enabled = false; + + for (i = 0; i < 2; i++) { + while (qemu_co_enter_next(&blkp->throttled_reqs[i])) { + drained = true; + } + } + + blkp->io_limits_enabled = enabled; + + return drained; +} diff --git a/block/io.c b/block/io.c index 22dbb43..f6edab8 100644 --- a/block/io.c +++ b/block/io.c @@ -27,7 +27,6 @@ #include "sysemu/block-backend.h" #include "block/blockjob.h" #include "block/block_int.h" -#include "block/throttle-groups.h" #include "qemu/error-report.h" #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ @@ -56,31 +55,6 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque); static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BdrvRequestFlags flags); -/* this function drain all the throttled IOs */ -bool bdrv_start_throttled_reqs(BlockDriverState *bs) -{ - if (!bs->blk) { - return false; - } - - BlockBackendPublic *blkp = blk_get_public(bs->blk); - bool drained = false; - bool enabled = blk_get_public(bs->blk)->io_limits_enabled; - int i; - - blkp->io_limits_enabled = false; - - for (i = 0; i < 2; i++) { - while (qemu_co_enter_next(&blkp->throttled_reqs[i])) { - drained = true; - } - } - - blkp->io_limits_enabled = enabled; - - return drained; -} - void bdrv_setup_io_funcs(BlockDriver *bdrv) { /* Block drivers without coroutine functions need emulation */ @@ -2668,12 +2642,19 @@ void bdrv_io_unplug(BlockDriverState *bs) void bdrv_flush_io_queue(BlockDriverState *bs) { BlockDriver *drv = bs->drv; + BdrvChild *c; + if (drv && drv->bdrv_flush_io_queue) { drv->bdrv_flush_io_queue(bs); } else if (bs->file) { bdrv_flush_io_queue(bs->file->bs); } - bdrv_start_throttled_reqs(bs); + + QLIST_FOREACH(c, &bs->parents, next_parent) { + if (c->role->drain_queue) { + c->role->drain_queue(c); + } + } } void bdrv_drained_begin(BlockDriverState *bs) diff --git a/include/block/block_int.h b/include/block/block_int.h index 1b3c310..e064d9d 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -355,6 +355,8 @@ typedef struct BdrvAioNotifier { struct BdrvChildRole { void (*inherit_options)(int *child_flags, QDict *child_options, int parent_flags, QDict *parent_options); + + bool (*drain_queue)(BdrvChild *child); }; extern const BdrvChildRole child_file; @@ -508,8 +510,6 @@ int get_tmp_filename(char *filename, int size); BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size, const char *filename); -bool bdrv_start_throttled_reqs(BlockDriverState *bs); - /** * bdrv_add_before_write_notifier: