]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
blk-throttle: schedule parent dispatch in tg_flush_bios()
authorTao Cui <cuitao@kylinos.cn>
Fri, 22 May 2026 09:15:30 +0000 (17:15 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 27 May 2026 14:37:47 +0000 (08:37 -0600)
commit6235ea3f8b8ffca0333ade0863992f3cd69592ea
tree8f3b13515a1e575e576b050feac7717aaf2a552e
parent6b2f3e4970e48e70c10111366f59f908f2ea6f96
blk-throttle: schedule parent dispatch in tg_flush_bios()

tg_flush_bios() schedules pending_timer on the child tg's own
service_queue, which causes throtl_pending_timer_fn() to dispatch from
the child's pending_tree.  For leaf cgroups this tree is empty, so the
timer fires and exits without dispatching the throttled bio.

The throttled bio sits in the parent's pending_tree with disptime set
to jiffies (THROTL_TG_CANCELING zeroes all dispatch times), but the
parent's timer is never explicitly rescheduled.  The bio only gets
dispatched when the parent timer eventually fires at its previously
scheduled expiry.

Fix by calling throtl_schedule_next_dispatch(sq->parent_sq, true)
instead, matching what tg_set_limit() already does.  This forces the
parent's dispatch cycle to run immediately and flush all canceling
bios without waiting for a stale timer.

For the device deletion path (blk_throtl_cancel_bios), directly
complete throttled bios with EIO via bio_io_error() instead of
dispatching them through the timer -> work -> submission chain.
This avoids a race with the SCSI state machine where bios can reach
the SCSI layer while the device is in SDEV_CANCEL state, causing
ENODEV instead of the expected EIO.

Reported-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Link: https://lore.kernel.org/all/ag2owaQQoigp_fSV@shinmob/
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
Link: https://patch.msgid.link/20260522091530.1901437-1-cuitao@kylinos.cn
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-throttle.c