Skip to content

Commit 8f9e7b6

Browse files
YuKuai-huaweiaxboe
authored andcommitted
block: cancel all throttled bios in del_gendisk()
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 <yukuai3@huawei.com> Signed-off-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20220318130144.1066064-4-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 0a9a25c commit 8f9e7b6

3 files changed

Lines changed: 41 additions & 1 deletion

File tree

block/blk-throttle.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,8 @@ static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio,
874874
bio != throtl_peek_queued(&tg->service_queue.queued[rw]));
875875

876876
/* If tg->bps = -1, then BW is unlimited */
877-
if (bps_limit == U64_MAX && iops_limit == UINT_MAX) {
877+
if ((bps_limit == U64_MAX && iops_limit == UINT_MAX) ||
878+
tg->flags & THROTL_TG_CANCELING) {
878879
if (wait)
879880
*wait = 0;
880881
return true;
@@ -1776,6 +1777,39 @@ static bool throtl_hierarchy_can_upgrade(struct throtl_grp *tg)
17761777
return false;
17771778
}
17781779

1780+
void blk_throtl_cancel_bios(struct request_queue *q)
1781+
{
1782+
struct cgroup_subsys_state *pos_css;
1783+
struct blkcg_gq *blkg;
1784+
1785+
spin_lock_irq(&q->queue_lock);
1786+
/*
1787+
* queue_lock is held, rcu lock is not needed here technically.
1788+
* However, rcu lock is still held to emphasize that following
1789+
* path need RCU protection and to prevent warning from lockdep.
1790+
*/
1791+
rcu_read_lock();
1792+
blkg_for_each_descendant_post(blkg, pos_css, q->root_blkg) {
1793+
struct throtl_grp *tg = blkg_to_tg(blkg);
1794+
struct throtl_service_queue *sq = &tg->service_queue;
1795+
1796+
/*
1797+
* Set the flag to make sure throtl_pending_timer_fn() won't
1798+
* stop until all throttled bios are dispatched.
1799+
*/
1800+
blkg_to_tg(blkg)->flags |= THROTL_TG_CANCELING;
1801+
/*
1802+
* Update disptime after setting the above flag to make sure
1803+
* throtl_select_dispatch() won't exit without dispatching.
1804+
*/
1805+
tg_update_disptime(tg);
1806+
1807+
throtl_schedule_pending_timer(sq, jiffies + 1);
1808+
}
1809+
rcu_read_unlock();
1810+
spin_unlock_irq(&q->queue_lock);
1811+
}
1812+
17791813
static bool throtl_can_upgrade(struct throtl_data *td,
17801814
struct throtl_grp *this_tg)
17811815
{

block/blk-throttle.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum tg_state_flags {
5656
THROTL_TG_PENDING = 1 << 0, /* on parent's pending tree */
5757
THROTL_TG_WAS_EMPTY = 1 << 1, /* bio_lists[] became non-empty */
5858
THROTL_TG_HAS_IOPS_LIMIT = 1 << 2, /* tg has iops limit */
59+
THROTL_TG_CANCELING = 1 << 3, /* starts to cancel bio */
5960
};
6061

6162
enum {
@@ -162,11 +163,13 @@ static inline int blk_throtl_init(struct request_queue *q) { return 0; }
162163
static inline void blk_throtl_exit(struct request_queue *q) { }
163164
static inline void blk_throtl_register_queue(struct request_queue *q) { }
164165
static inline bool blk_throtl_bio(struct bio *bio) { return false; }
166+
static inline void blk_throtl_cancel_bios(struct request_queue *q) { }
165167
#else /* CONFIG_BLK_DEV_THROTTLING */
166168
int blk_throtl_init(struct request_queue *q);
167169
void blk_throtl_exit(struct request_queue *q);
168170
void blk_throtl_register_queue(struct request_queue *q);
169171
bool __blk_throtl_bio(struct bio *bio);
172+
void blk_throtl_cancel_bios(struct request_queue *q);
170173
static inline bool blk_throtl_bio(struct bio *bio)
171174
{
172175
struct throtl_grp *tg = blkg_to_tg(bio->bi_blkg);

block/genhd.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/pm_runtime.h>
2626
#include <linux/badblocks.h>
2727
#include <linux/part_stat.h>
28+
#include "blk-throttle.h"
2829

2930
#include "blk.h"
3031
#include "blk-mq-sched.h"
@@ -627,6 +628,8 @@ void del_gendisk(struct gendisk *disk)
627628

628629
blk_mq_freeze_queue_wait(q);
629630

631+
blk_throtl_cancel_bios(disk->queue);
632+
630633
blk_sync_queue(q);
631634
blk_flush_integrity();
632635
/*

0 commit comments

Comments
 (0)