diff mbox series

[4/7] blk-throttle: Introduce flag "BIO_TG_BPS_THROTTLED"

Message ID 20250414132731.167620-5-wozizhi@huawei.com (mailing list archive)
State New
Headers show
Series blk-throttle: Split the blkthrotl queue to solve the IO delay issue | expand

Commit Message

Zizhi Wo April 14, 2025, 1:27 p.m. UTC
Subsequent patches will split the single queue into separate bps and iops
queues. To prevent IO that has already passed through the bps queue at a
single tg level from being counted toward bps wait time again, we introduce
"BIO_TG_BPS_THROTTLED" flag. Since throttle and QoS operate at different
levels, we reuse the value as "BIO_QOS_THROTTLED".

We set this flag when charge bps and clear it when charge iops, as the bio
will move to the upper-level tg or be dispatched.

This patch does not involve functional changes.

Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
---
 block/blk-throttle.c      | 9 +++++++--
 include/linux/blk_types.h | 5 +++++
 2 files changed, 12 insertions(+), 2 deletions(-)

Comments

Yu Kuai April 15, 2025, 2:24 a.m. UTC | #1
Hi,

在 2025/04/14 21:27, Zizhi Wo 写道:
> Subsequent patches will split the single queue into separate bps and iops
> queues. To prevent IO that has already passed through the bps queue at a
> single tg level from being counted toward bps wait time again, we introduce
> "BIO_TG_BPS_THROTTLED" flag. Since throttle and QoS operate at different
> levels, we reuse the value as "BIO_QOS_THROTTLED".
> 
> We set this flag when charge bps and clear it when charge iops, as the bio
> will move to the upper-level tg or be dispatched.
> 
> This patch does not involve functional changes.
> 
> Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
> ---
>   block/blk-throttle.c      | 9 +++++++--
>   include/linux/blk_types.h | 5 +++++
>   2 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/block/blk-throttle.c b/block/blk-throttle.c
> index 91ee1c502b41..caae2e3b7534 100644
> --- a/block/blk-throttle.c
> +++ b/block/blk-throttle.c
> @@ -741,12 +741,16 @@ static void throtl_charge_bps_bio(struct throtl_grp *tg, struct bio *bio)
>   	unsigned int bio_size = throtl_bio_data_size(bio);
>   
>   	/* Charge the bio to the group */
> -	if (!bio_flagged(bio, BIO_BPS_THROTTLED))
> +	if (!bio_flagged(bio, BIO_BPS_THROTTLED) &&
> +	    !bio_flagged(bio, BIO_TG_BPS_THROTTLED)) {
> +		bio_set_flag(bio, BIO_TG_BPS_THROTTLED);
>   		tg->bytes_disp[bio_data_dir(bio)] += bio_size;
> +	}
>   }
>   
>   static void throtl_charge_iops_bio(struct throtl_grp *tg, struct bio *bio)
>   {
> +	bio_clear_flag(bio, BIO_TG_BPS_THROTTLED);
>   	tg->io_disp[bio_data_dir(bio)]++;
>   }
>   
> @@ -772,7 +776,8 @@ static unsigned long tg_dispatch_bps_time(struct throtl_grp *tg, struct bio *bio
>   
>   	/* no need to throttle if this bio's bytes have been accounted */
>   	if (bps_limit == U64_MAX || tg->flags & THROTL_TG_CANCELING ||
> -	    bio_flagged(bio, BIO_BPS_THROTTLED))
> +	    bio_flagged(bio, BIO_BPS_THROTTLED) ||
> +	    bio_flagged(bio, BIO_TG_BPS_THROTTLED))
>   		return 0;
>   
>   	tg_update_slice(tg, rw);
> diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
> index dce7615c35e7..f9d1230e27a7 100644
> --- a/include/linux/blk_types.h
> +++ b/include/linux/blk_types.h
> @@ -296,6 +296,11 @@ enum {
>   				 * of this bio. */
>   	BIO_CGROUP_ACCT,	/* has been accounted to a cgroup */
>   	BIO_QOS_THROTTLED,	/* bio went through rq_qos throttle path */
> +	/*
> +	 * This bio has undergone rate limiting at the single throtl_grp level bps
> +	 * queue. Since throttle and QoS are not at the same level, reused the value.
resued -> resue

Other than the typo, LGTM
Reviewed-by: Yu Kuai <yukuai3@huawei.com>

> +	 */
> +	BIO_TG_BPS_THROTTLED = BIO_QOS_THROTTLED,
>   	BIO_QOS_MERGED,		/* but went through rq_qos merge path */
>   	BIO_REMAPPED,
>   	BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */
>
Zizhi Wo April 15, 2025, 6:15 a.m. UTC | #2
在 2025/4/15 10:24, Yu Kuai 写道:
> Hi,
> 
> 在 2025/04/14 21:27, Zizhi Wo 写道:
>> Subsequent patches will split the single queue into separate bps and iops
>> queues. To prevent IO that has already passed through the bps queue at a
>> single tg level from being counted toward bps wait time again, we 
>> introduce
>> "BIO_TG_BPS_THROTTLED" flag. Since throttle and QoS operate at different
>> levels, we reuse the value as "BIO_QOS_THROTTLED".
>>
>> We set this flag when charge bps and clear it when charge iops, as the 
>> bio
>> will move to the upper-level tg or be dispatched.
>>
>> This patch does not involve functional changes.
>>
>> Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
>> ---
>>   block/blk-throttle.c      | 9 +++++++--
>>   include/linux/blk_types.h | 5 +++++
>>   2 files changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/block/blk-throttle.c b/block/blk-throttle.c
>> index 91ee1c502b41..caae2e3b7534 100644
>> --- a/block/blk-throttle.c
>> +++ b/block/blk-throttle.c
>> @@ -741,12 +741,16 @@ static void throtl_charge_bps_bio(struct 
>> throtl_grp *tg, struct bio *bio)
>>       unsigned int bio_size = throtl_bio_data_size(bio);
>>       /* Charge the bio to the group */
>> -    if (!bio_flagged(bio, BIO_BPS_THROTTLED))
>> +    if (!bio_flagged(bio, BIO_BPS_THROTTLED) &&
>> +        !bio_flagged(bio, BIO_TG_BPS_THROTTLED)) {
>> +        bio_set_flag(bio, BIO_TG_BPS_THROTTLED);
>>           tg->bytes_disp[bio_data_dir(bio)] += bio_size;
>> +    }
>>   }
>>   static void throtl_charge_iops_bio(struct throtl_grp *tg, struct bio 
>> *bio)
>>   {
>> +    bio_clear_flag(bio, BIO_TG_BPS_THROTTLED);
>>       tg->io_disp[bio_data_dir(bio)]++;
>>   }
>> @@ -772,7 +776,8 @@ static unsigned long tg_dispatch_bps_time(struct 
>> throtl_grp *tg, struct bio *bio
>>       /* no need to throttle if this bio's bytes have been accounted */
>>       if (bps_limit == U64_MAX || tg->flags & THROTL_TG_CANCELING ||
>> -        bio_flagged(bio, BIO_BPS_THROTTLED))
>> +        bio_flagged(bio, BIO_BPS_THROTTLED) ||
>> +        bio_flagged(bio, BIO_TG_BPS_THROTTLED))
>>           return 0;
>>       tg_update_slice(tg, rw);
>> diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
>> index dce7615c35e7..f9d1230e27a7 100644
>> --- a/include/linux/blk_types.h
>> +++ b/include/linux/blk_types.h
>> @@ -296,6 +296,11 @@ enum {
>>                    * of this bio. */
>>       BIO_CGROUP_ACCT,    /* has been accounted to a cgroup */
>>       BIO_QOS_THROTTLED,    /* bio went through rq_qos throttle path */
>> +    /*
>> +     * This bio has undergone rate limiting at the single throtl_grp 
>> level bps
>> +     * queue. Since throttle and QoS are not at the same level, 
>> reused the value.
> resued -> resue

Sorry about that, I missed it. Appreciate the correction.

Thanks,
Zizhi Wo

> 
> Other than the typo, LGTM
> Reviewed-by: Yu Kuai <yukuai3@huawei.com>
> 
>> +     */
>> +    BIO_TG_BPS_THROTTLED = BIO_QOS_THROTTLED,
>>       BIO_QOS_MERGED,        /* but went through rq_qos merge path */
>>       BIO_REMAPPED,
>>       BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write 
>> plugging */
>>
>
diff mbox series

Patch

diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 91ee1c502b41..caae2e3b7534 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -741,12 +741,16 @@  static void throtl_charge_bps_bio(struct throtl_grp *tg, struct bio *bio)
 	unsigned int bio_size = throtl_bio_data_size(bio);
 
 	/* Charge the bio to the group */
-	if (!bio_flagged(bio, BIO_BPS_THROTTLED))
+	if (!bio_flagged(bio, BIO_BPS_THROTTLED) &&
+	    !bio_flagged(bio, BIO_TG_BPS_THROTTLED)) {
+		bio_set_flag(bio, BIO_TG_BPS_THROTTLED);
 		tg->bytes_disp[bio_data_dir(bio)] += bio_size;
+	}
 }
 
 static void throtl_charge_iops_bio(struct throtl_grp *tg, struct bio *bio)
 {
+	bio_clear_flag(bio, BIO_TG_BPS_THROTTLED);
 	tg->io_disp[bio_data_dir(bio)]++;
 }
 
@@ -772,7 +776,8 @@  static unsigned long tg_dispatch_bps_time(struct throtl_grp *tg, struct bio *bio
 
 	/* no need to throttle if this bio's bytes have been accounted */
 	if (bps_limit == U64_MAX || tg->flags & THROTL_TG_CANCELING ||
-	    bio_flagged(bio, BIO_BPS_THROTTLED))
+	    bio_flagged(bio, BIO_BPS_THROTTLED) ||
+	    bio_flagged(bio, BIO_TG_BPS_THROTTLED))
 		return 0;
 
 	tg_update_slice(tg, rw);
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index dce7615c35e7..f9d1230e27a7 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -296,6 +296,11 @@  enum {
 				 * of this bio. */
 	BIO_CGROUP_ACCT,	/* has been accounted to a cgroup */
 	BIO_QOS_THROTTLED,	/* bio went through rq_qos throttle path */
+	/*
+	 * This bio has undergone rate limiting at the single throtl_grp level bps
+	 * queue. Since throttle and QoS are not at the same level, reused the value.
+	 */
+	BIO_TG_BPS_THROTTLED = BIO_QOS_THROTTLED,
 	BIO_QOS_MERGED,		/* but went through rq_qos merge path */
 	BIO_REMAPPED,
 	BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */