From patchwork Fri Jan 28 08:45:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yu Kuai X-Patchwork-Id: 12728113 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BEC7C433F5 for ; Fri, 28 Jan 2022 08:34:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347339AbiA1Iej (ORCPT ); Fri, 28 Jan 2022 03:34:39 -0500 Received: from szxga02-in.huawei.com ([45.249.212.188]:30318 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347313AbiA1Iej (ORCPT ); Fri, 28 Jan 2022 03:34:39 -0500 Received: from kwepemi500024.china.huawei.com (unknown [172.30.72.54]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4JlW2J6CM8zbkCQ; Fri, 28 Jan 2022 16:33:44 +0800 (CST) Received: from kwepemm600009.china.huawei.com (7.193.23.164) by kwepemi500024.china.huawei.com (7.221.188.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.21; Fri, 28 Jan 2022 16:34:36 +0800 Received: from huawei.com (10.175.127.227) by kwepemm600009.china.huawei.com (7.193.23.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.21; Fri, 28 Jan 2022 16:34:35 +0800 From: Yu Kuai To: , , CC: , , , , Subject: [PATCH v7 1/2] blk-throtl: introduce a new flag THROTL_TG_CANCELING Date: Fri, 28 Jan 2022 16:45:21 +0800 Message-ID: <20220128084522.3169961-2-yukuai3@huawei.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220128084522.3169961-1-yukuai3@huawei.com> References: <20220128084522.3169961-1-yukuai3@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600009.china.huawei.com (7.193.23.164) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org If the new flag is set, then the throtl_grp will stop throttling bios. Prepare to canceling all throttled bios if the disk is gone. Signed-off-by: Yu Kuai --- block/blk-throttle.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 7c462c006b26..abc5e506c72d 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -43,8 +43,12 @@ static struct workqueue_struct *kthrotld_workqueue; enum tg_state_flags { - THROTL_TG_PENDING = 1 << 0, /* on parent's pending tree */ - THROTL_TG_WAS_EMPTY = 1 << 1, /* bio_lists[] became non-empty */ + /* on parent's pending tree */ + THROTL_TG_PENDING = 1 << 0, + /* bio_lists[] became non-empty */ + THROTL_TG_WAS_EMPTY = 1 << 1, + /* starts to cancel all bios, will be set if the disk is deleted */ + THROTL_TG_CANCELING = 1 << 2, }; #define rb_entry_tg(node) rb_entry((node), struct throtl_grp, rb_node) @@ -871,7 +875,8 @@ static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio, bio != throtl_peek_queued(&tg->service_queue.queued[rw])); /* If tg->bps = -1, then BW is unlimited */ - if (bps_limit == U64_MAX && iops_limit == UINT_MAX) { + if ((bps_limit == U64_MAX && iops_limit == UINT_MAX) || + tg->flags & THROTL_TG_CANCELING) { if (wait) *wait = 0; return true; @@ -974,6 +979,9 @@ static void tg_update_disptime(struct throtl_grp *tg) unsigned long read_wait = -1, write_wait = -1, min_wait = -1, disptime; struct bio *bio; + if (tg->flags & THROTL_TG_CANCELING) + goto update; + bio = throtl_peek_queued(&sq->queued[READ]); if (bio) tg_may_dispatch(tg, bio, &read_wait); @@ -983,9 +991,10 @@ static void tg_update_disptime(struct throtl_grp *tg) tg_may_dispatch(tg, bio, &write_wait); min_wait = min(read_wait, write_wait); - disptime = jiffies + min_wait; +update: /* Update dispatch time */ + disptime = jiffies + min_wait; throtl_dequeue_tg(tg); tg->disptime = disptime; throtl_enqueue_tg(tg); From patchwork Fri Jan 28 08:45:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yu Kuai X-Patchwork-Id: 12728114 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3761C43217 for ; Fri, 28 Jan 2022 08:34:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347344AbiA1Iek (ORCPT ); Fri, 28 Jan 2022 03:34:40 -0500 Received: from szxga02-in.huawei.com ([45.249.212.188]:30319 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347329AbiA1Iej (ORCPT ); Fri, 28 Jan 2022 03:34:39 -0500 Received: from kwepemi500023.china.huawei.com (unknown [172.30.72.57]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4JlW2K48rdzbkJ7; Fri, 28 Jan 2022 16:33:45 +0800 (CST) Received: from kwepemm600009.china.huawei.com (7.193.23.164) by kwepemi500023.china.huawei.com (7.221.188.76) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.21; Fri, 28 Jan 2022 16:34:37 +0800 Received: from huawei.com (10.175.127.227) by kwepemm600009.china.huawei.com (7.193.23.164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.21; Fri, 28 Jan 2022 16:34:36 +0800 From: Yu Kuai To: , , CC: , , , , Subject: [PATCH v7 2/2] block: cancel all throttled bios in del_gendisk() Date: Fri, 28 Jan 2022 16:45:22 +0800 Message-ID: <20220128084522.3169961-3-yukuai3@huawei.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220128084522.3169961-1-yukuai3@huawei.com> References: <20220128084522.3169961-1-yukuai3@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600009.china.huawei.com (7.193.23.164) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Throttled bios can't be issued after del_gendisk() is done, thus it's better to cancel them immediately rather than waiting for throttle is done. For example, if user thread is throttled with low bps while it's issuing large io, and the device is deleted. The user thread will wait for a long time for io to return. Signed-off-by: Yu Kuai --- block/blk-throttle.c | 32 ++++++++++++++++++++++++++++++++ block/blk-throttle.h | 2 ++ block/genhd.c | 2 ++ 3 files changed, 36 insertions(+) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index abc5e506c72d..3280b8559ea7 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -1772,6 +1772,38 @@ static bool throtl_hierarchy_can_upgrade(struct throtl_grp *tg) return false; } +void blk_throtl_cancel_bios(struct request_queue *q) +{ + struct cgroup_subsys_state *pos_css; + struct blkcg_gq *blkg; + + spin_lock_irq(&q->queue_lock); + /* + * queue_lock is held, rcu lock is not needed here technically. + * However, rcu lock is still held to emphasize that following + * path need RCU protection and to prevent warning from lockdep. + */ + rcu_read_lock(); + blkg_for_each_descendant_post(blkg, pos_css, q->root_blkg) { + struct throtl_grp *tg = blkg_to_tg(blkg); + struct throtl_service_queue *sq = &tg->service_queue; + + /* + * Set disptime in the past to make sure + * throtl_select_dispatch() won't exit without dispatching. + */ + tg->disptime = jiffies - 1; + /* + * Set the flag to make sure throtl_pending_timer_fn() won't + * stop until all throttled bios are dispatched. + */ + blkg_to_tg(blkg)->flags |= THROTL_TG_CANCELING; + throtl_schedule_pending_timer(sq, jiffies + 1); + } + rcu_read_unlock(); + spin_unlock_irq(&q->queue_lock); +} + static bool throtl_can_upgrade(struct throtl_data *td, struct throtl_grp *this_tg) { diff --git a/block/blk-throttle.h b/block/blk-throttle.h index 175f03abd9e4..2ae467ac17ea 100644 --- a/block/blk-throttle.h +++ b/block/blk-throttle.h @@ -160,12 +160,14 @@ static inline void blk_throtl_exit(struct request_queue *q) { } static inline void blk_throtl_register_queue(struct request_queue *q) { } static inline void blk_throtl_charge_bio_split(struct bio *bio) { } static inline bool blk_throtl_bio(struct bio *bio) { return false; } +static inline void blk_throtl_cancel_bios(struct request_queue *q) { } #else /* CONFIG_BLK_DEV_THROTTLING */ int blk_throtl_init(struct request_queue *q); void blk_throtl_exit(struct request_queue *q); void blk_throtl_register_queue(struct request_queue *q); void blk_throtl_charge_bio_split(struct bio *bio); bool __blk_throtl_bio(struct bio *bio); +void blk_throtl_cancel_bios(struct request_queue *q); static inline bool blk_throtl_bio(struct bio *bio) { struct throtl_grp *tg = blkg_to_tg(bio->bi_blkg); diff --git a/block/genhd.c b/block/genhd.c index 9589d1d59afa..6acc98cd0365 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -29,6 +29,7 @@ #include "blk.h" #include "blk-mq-sched.h" #include "blk-rq-qos.h" +#include "blk-throttle.h" static struct kobject *block_depr; @@ -625,6 +626,7 @@ void del_gendisk(struct gendisk *disk) blk_mq_freeze_queue_wait(q); + blk_throtl_cancel_bios(disk->queue); rq_qos_exit(q); blk_sync_queue(q); blk_flush_integrity();