From: Zizhi Wo <wozizhi@xxxxxxxxxx> Changes since V1-2: 1) Fixed minor comment issues in patch 4. 2) In patch 6, replaced the @queued parameter with @sq in both throtl_qnode_add_bio and throtl_pop_queued to facilitate internal changes. And the potential problem of null pointer dereference has been fixed. [BUG] The current blkthrotl code provides two types of throttling: BPS limit and IOPS limit. When both limits are enabled, an IO is only dispatched if it meets both the BPS and IOPS restrictions. However, when both BPS and IOPS are limited simultaneously, an IO delayed dispatch issue can occur due to IO splitting. For example, if two 1MB IOs are issued with a BPS limit of 1MB/s and a very high IOPS limit, the IO splitting will cause both IOs to complete almost "simultaneously" in 2 seconds. [CAUSE] The root cause of this issue is that blkthrotl mixes BPS and IOPS into a single queue. When issuing multiple IOs sequentially, the continuously split IOs will repeatedly enter the same queue. As they alternately go through the throtl process, IOs that have already been throttled will have to wait for IOs that have not yet been throttled. As a result, all IOs will eventually complete almost together. [FIX] Since IO requests that have already been split no longer need to go through BPS throttling but still require IOPS control, this patchset splits the existing blkthrotl queue into two separate queues: BPS and IOPS. 1) IO requests must first pass through the BPS queue. 2) Once they meet the BPS limit, they proceed to the IOPS queue before being dispatched. 3) Already split IO requests bypass the BPS queue and go directly to the IOPS queue. [OVERVIEW] This patchset consists of 7 patches: 1) Patch 1 is a simple clean_up. 2) Patch 2-4, to facilitate the subsequent splitting of queues. Patch 2-3 separate the -dispatch- and -charge- functions based on the BPS and IOPS. Patch 4 introduce a new flag to prevent double counting. 3) Patch 5-6 splits the original single queue into two separate queues(BPS and IOPS) without altering the existing code logic. 4) Patch 7 ensures that split IO requests bypass the BPS queue, preventing unnecessary throttling and eliminating the delay issue. Zizhi Wo (7): blk-throttle: Rename tg_may_dispatch() to tg_dispatch_time() blk-throttle: Refactor tg_dispatch_time by extracting tg_dispatch_bps/iops_time blk-throttle: Split throtl_charge_bio() into bps and iops functions blk-throttle: Introduce flag "BIO_TG_BPS_THROTTLED" blk-throttle: Split the blkthrotl queue blk-throttle: Split the service queue blk-throttle: Prevents the bps restricted io from entering the bps queue again block/blk-throttle.c | 302 ++++++++++++++++++++++++-------------- block/blk-throttle.h | 14 +- include/linux/blk_types.h | 5 + 3 files changed, 208 insertions(+), 113 deletions(-) -- 2.46.1