From: Ming Lei <ming.lei@redhat.com>
To: Yu Kuai <yukuai1@huaweicloud.com>
Cc: Jens Axboe <axboe@kernel.dk>,
linux-block@vger.kernel.org, Tejun Heo <tj@kernel.org>,
Josef Bacik <josef@toxicpanda.com>,
"yukuai (C)" <yukuai3@huawei.com>, WoZ1zh1 <wozizhi@huawei.com>
Subject: Re: [PATCH 3/3] blk-throttle: carry over directly
Date: Fri, 11 Apr 2025 23:01:56 +0800 [thread overview]
Message-ID: <Z_ku5L3sVZbHdbQ_@fedora> (raw)
In-Reply-To: <14e6c54f-d0d9-0122-1e47-c8a56adbd5db@huaweicloud.com>
On Fri, Apr 11, 2025 at 10:53:12AM +0800, Yu Kuai wrote:
> Hi, Ming
>
> 在 2025/03/05 12:31, Ming Lei 写道:
> > Now ->carryover_bytes[] and ->carryover_ios[] only covers limit/config
> > update.
> >
> > Actually the carryover bytes/ios can be carried to ->bytes_disp[] and
> > ->io_disp[] directly, since the carryover is one-shot thing and only valid
> > in current slice.
> >
> > Then we can remove the two fields and simplify code much.
> >
> > Type of ->bytes_disp[] and ->io_disp[] has to change as signed because the
> > two fields may become negative when updating limits or config, but both are
> > big enough for holding bytes/ios dispatched in single slice
> >
> > Cc: Tejun Heo <tj@kernel.org>
> > Cc: Josef Bacik <josef@toxicpanda.com>
> > Cc: Yu Kuai <yukuai3@huawei.com>
> > Signed-off-by: Ming Lei <ming.lei@redhat.com>
> > ---
> > block/blk-throttle.c | 49 +++++++++++++++++++-------------------------
> > block/blk-throttle.h | 4 ++--
> > 2 files changed, 23 insertions(+), 30 deletions(-)
> >
> > diff --git a/block/blk-throttle.c b/block/blk-throttle.c
> > index 7271aee94faf..91dab43c65ab 100644
> > --- a/block/blk-throttle.c
> > +++ b/block/blk-throttle.c
> > @@ -478,8 +478,6 @@ static inline void throtl_start_new_slice_with_credit(struct throtl_grp *tg,
> > {
> > tg->bytes_disp[rw] = 0;
> > tg->io_disp[rw] = 0;
> > - tg->carryover_bytes[rw] = 0;
> > - tg->carryover_ios[rw] = 0;
> > /*
> > * Previous slice has expired. We must have trimmed it after last
> > @@ -498,16 +496,14 @@ static inline void throtl_start_new_slice_with_credit(struct throtl_grp *tg,
> > }
> > static inline void throtl_start_new_slice(struct throtl_grp *tg, bool rw,
> > - bool clear_carryover)
> > + bool clear)
> > {
> > - tg->bytes_disp[rw] = 0;
> > - tg->io_disp[rw] = 0;
> > + if (clear) {
> > + tg->bytes_disp[rw] = 0;
> > + tg->io_disp[rw] = 0;
> > + }
> > tg->slice_start[rw] = jiffies;
> > tg->slice_end[rw] = jiffies + tg->td->throtl_slice;
> > - if (clear_carryover) {
> > - tg->carryover_bytes[rw] = 0;
> > - tg->carryover_ios[rw] = 0;
> > - }
> > throtl_log(&tg->service_queue,
> > "[%c] new slice start=%lu end=%lu jiffies=%lu",
> > @@ -617,20 +613,16 @@ static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw)
> > */
> > time_elapsed -= tg->td->throtl_slice;
> > bytes_trim = calculate_bytes_allowed(tg_bps_limit(tg, rw),
> > - time_elapsed) +
> > - tg->carryover_bytes[rw];
> > - io_trim = calculate_io_allowed(tg_iops_limit(tg, rw), time_elapsed) +
> > - tg->carryover_ios[rw];
> > + time_elapsed);
> > + io_trim = calculate_io_allowed(tg_iops_limit(tg, rw), time_elapsed);
> > if (bytes_trim <= 0 && io_trim <= 0)
> > return;
> > - tg->carryover_bytes[rw] = 0;
> > if ((long long)tg->bytes_disp[rw] >= bytes_trim)
> > tg->bytes_disp[rw] -= bytes_trim;
> > else
> > tg->bytes_disp[rw] = 0;
> > - tg->carryover_ios[rw] = 0;
> > if ((int)tg->io_disp[rw] >= io_trim)
> > tg->io_disp[rw] -= io_trim;
> > else
> > @@ -645,7 +637,8 @@ static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw)
> > jiffies);
> > }
> > -static void __tg_update_carryover(struct throtl_grp *tg, bool rw)
> > +static void __tg_update_carryover(struct throtl_grp *tg, bool rw,
> > + long long *bytes, int *ios)
> > {
> > unsigned long jiffy_elapsed = jiffies - tg->slice_start[rw];
> > u64 bps_limit = tg_bps_limit(tg, rw);
> > @@ -658,26 +651,28 @@ static void __tg_update_carryover(struct throtl_grp *tg, bool rw)
> > * configuration.
> > */
> > if (bps_limit != U64_MAX)
> > - tg->carryover_bytes[rw] +=
> > - calculate_bytes_allowed(bps_limit, jiffy_elapsed) -
> > + *bytes = calculate_bytes_allowed(bps_limit, jiffy_elapsed) -
> > tg->bytes_disp[rw];
> > if (iops_limit != UINT_MAX)
> > - tg->carryover_ios[rw] +=
> > - calculate_io_allowed(iops_limit, jiffy_elapsed) -
> > + *ios = calculate_io_allowed(iops_limit, jiffy_elapsed) -
> > tg->io_disp[rw];
> > + tg->bytes_disp[rw] -= *bytes;
> > + tg->io_disp[rw] -= *ios;
>
> This patch is applied before I get a chance to review. :( I think the
> above update should be:
oops, your review period takes too long(> 1 month), :-(
>
> tg->bytes_disp[rw] = -*bytes;
> tg->io_disp[rw] = -*ios;
I think the above is wrong since it simply override the existed dispatched
bytes/ios.
The calculation can be understood from two ways:
1) delta = calculate_bytes_allowed(bps_limit, jiffy_elapsed) - tg->bytes_disp[rw];
`delta` represents difference between theoretical and actual dispatch bytes.
If `delta` > 0, it means we dispatch too less in past, and we have to subtract
`delta` from ->bytes_disp, so that in future we can dispatch more.
Similar with 'delta < 0'.
2) from consumer viewpoint:
tg_within_bps_limit(): patched
...
bytes_allowed = calculate_bytes_allowed(bps_limit, jiffy_elapsed_rnd);
if (bytes_allowed > 0 && tg->bytes_disp[rw] + bio_size <= bytes_allowed)
...
tg_within_bps_limit(): before patched
...
bytes_allowed = calculate_bytes_allowed(bps_limit, jiffy_elapsed_rnd) +
tg->carryover_bytes[rw];
if (bytes_allowed > 0 && tg->bytes_disp[rw] + bio_size <= bytes_allowed)
...
So if `delta` is subtracted from `bytes_allowed` in patched code, we should
subtract same bytes from ->byte_disp[] side for maintaining the relation.
>
> Otherwise, the result is actually (2 * disp - allowed), which might be a
> huge value, causing long dealy for the next dispatch.
>
> This is what the old carryover fileds do, above change will work, but
> look wried.
As I explained, the patched code follows the original carryover calculation, and it
passes all throt blktests.
Or do you have test case broken by this patch?
Thanks.
Ming
next prev parent reply other threads:[~2025-04-11 15:02 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-05 4:31 [PATCH 0/3] blk-throttle: remove last_bytes/ios and carryover byte/ios Ming Lei
2025-03-05 4:31 ` [PATCH 1/3] blk-throttle: remove last_bytes_disp and last_ios_disp Ming Lei
2025-03-05 19:07 ` Tejun Heo
2025-03-05 4:31 ` [PATCH 2/3] blk-throttle: don't take carryover for prioritized processing of metadata Ming Lei
2025-03-05 19:11 ` Tejun Heo
2025-03-05 4:31 ` [PATCH 3/3] blk-throttle: carry over directly Ming Lei
2025-03-05 19:16 ` Tejun Heo
2025-04-11 2:53 ` Yu Kuai
2025-04-11 15:01 ` Ming Lei [this message]
2025-04-12 0:37 ` Yu Kuai
2025-04-14 2:32 ` Ming Lei
2025-04-14 11:47 ` Yu Kuai
2025-03-05 23:25 ` [PATCH 0/3] blk-throttle: remove last_bytes/ios and carryover byte/ios Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z_ku5L3sVZbHdbQ_@fedora \
--to=ming.lei@redhat.com \
--cc=axboe@kernel.dk \
--cc=josef@toxicpanda.com \
--cc=linux-block@vger.kernel.org \
--cc=tj@kernel.org \
--cc=wozizhi@huawei.com \
--cc=yukuai1@huaweicloud.com \
--cc=yukuai3@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox