From: Tao Cui <cui.tao@linux.dev>
To: tj@kernel.org, axboe@kernel.dk
Cc: linux-block@vger.kernel.org, josef@toxicpanda.com,
yu kuai <yukuai@fygo.io>,
cgroups@vger.kernel.org, linux-kernel@vger.kernel.org,
david.laight.linux@gmail.com, haris.iqbal@linux.dev,
cui.tao@linux.dev, Tao Cui <cuitao@kylinos.cn>
Subject: [PATCH v4] blk-throttle: fix divide-by-zero on legacy iops limit of 0
Date: Wed, 22 Jul 2026 18:24:59 +0800 [thread overview]
Message-ID: <20260722102459.253189-1-cui.tao@linux.dev> (raw)
From: Tao Cui <cuitao@kylinos.cn>
Writing a multiple of 2^32 (e.g. 4294967296) to a legacy cgroup v1
throttle iops file (blkio.throttle.{read,write}_iops_device) silently
truncates to 0: tg_set_conf() stores the sscanf-parsed u64 value into
an unsigned int field with no clamping. The cgroup v2 path,
tg_set_limit(), already clamps the same kind of value with
min_t(u64, val, UINT_MAX), but the legacy path never did. Note that
the "!v -> U64_MAX" mapping only catches an explicit zero and does not
catch a value that truncates to zero.
With iops stored as 0, tg_update_has_rules() sets has_rules_iops[] and
the next IO reaches tg_within_iops_limit(), which computes
jiffy_wait = max(jiffy_wait, HZ / iops_limit + 1);
triggering a divide-by-zero oops.
Fix it in tg_set_conf() by clamping the value to UINT_MAX, consistent
with tg_set_limit(). This closes the truncation root cause: with 0 no
longer reachable as a stored limit, the HZ / iops_limit divide is never
hit.
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
Changes in v4:
- Drop the defensive "iops_limit == 0" check in tg_dispatch_iops_time():
with the tg_set_conf() clamp in place, 0 can never be stored as a limit,
so the runtime check only guards an unreachable state. (Yu Kuai)
- Drop the Fixes: tag: the unclamped write -- and the iops=0 behavior it
can produce (calculate_io_allowed() returns 0, so no IO is issued) --
long predates the commit that added the HZ / iops_limit divide, so
attributing it there was incorrect. (Yu Kuai)
Changes in v3:
- Drop the (u64) cast on UINT_MAX: the kernel's type-checked min() accepts
two unsigned types of different width (both >= 4 bytes), so
min(v, UINT_MAX) compiles clean. (David Laight)
Changes in v2:
- Use a "void *field" local for the config write so the assignment reads
*(u64 *)field / *(unsigned int *)field instead of the
(type *)((void *)tg + of_cft(of)->private) casts.
- Use min(v, UINT_MAX) instead of min_t(u64, v, UINT_MAX).
---
block/blk-throttle.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index ffc3b70065d4..97ad7959d006 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -1383,10 +1383,12 @@ static ssize_t tg_set_conf(struct kernfs_open_file *of,
tg = blkg_to_tg(ctx.blkg);
tg_update_carryover(tg);
+ void *field = (void *)tg + of_cft(of)->private;
+
if (is_u64)
- *(u64 *)((void *)tg + of_cft(of)->private) = v;
+ *(u64 *)field = v;
else
- *(unsigned int *)((void *)tg + of_cft(of)->private) = v;
+ *(unsigned int *)field = min(v, UINT_MAX);
tg_conf_updated(tg, false);
ret = 0;
--
2.43.0
reply other threads:[~2026-07-22 10:25 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20260722102459.253189-1-cui.tao@linux.dev \
--to=cui.tao@linux.dev \
--cc=axboe@kernel.dk \
--cc=cgroups@vger.kernel.org \
--cc=cuitao@kylinos.cn \
--cc=david.laight.linux@gmail.com \
--cc=haris.iqbal@linux.dev \
--cc=josef@toxicpanda.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
--cc=yukuai@fygo.io \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.