From: sashiko-bot@kernel.org
To: "Yu Kuai" <yukuai@kernel.org>
Cc: hannes@cmpxchg.org, mkoutny@suse.com, linux-raid@vger.kernel.org,
yukuai@fygo.io, nvdimm@lists.linux.dev, tj@kernel.org
Subject: Re: [RFC PATCH v1 2/3] blk-cgroup: store blkcg in bio instead of blkg
Date: Tue, 04 Aug 2026 07:09:30 +0000 [thread overview]
Message-ID: <20260804070931.487701F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260804065313.2092022-3-yukuai@kernel.org>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] Dropping a bio's pinned `blkg` reference fails if the cgroup is offlined while IO is in flight, leaking the originally pinned `blkg` and causing a reference underflow on the root `blkg`.
- [High] `bio_blkg()` returns NULL when blkg creation fails and it falls back to an ancestor, leading to an immediate kernel panic in blk-throttle.
- [Medium] Standard IO statistics (io.stat) are silently dropped because the block cgroup association no longer creates missing blkgs by default.
--
--- Patch [2]: [RFC PATCH v1 2/3] blk-cgroup: store blkcg in bio instead of blkg ---
commit be98a58b9b6c0f35f61427866bf52e9085c5a028
Author: Yu Kuai <yukuai@fygo.io>
Subject: blk-cgroup: store blkcg in bio instead of blkg
A bio currently stores a queue-local blkg reference. This forces bio
association and remap paths to look up or create a blkg even when the bio
will never enter a blkcg policy. Store the blkcg css association in the
bio instead, and derive the blkg from the bio's blkcg and current bdev
when a policy needs it.
> diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
> index 52e7faaff0e5b..68a1d93e6584e 100644
> --- a/block/blk-cgroup.c
> +++ b/block/blk-cgroup.c
[ ... ]
> +static struct blkcg_gq *bio_pinned_blkg(struct bio *bio)
> +{
> + struct request_queue *q = bdev_get_queue(bio->bi_bdev);
> + struct blkcg_gq *blkg;
> +
> + rcu_read_lock();
> + blkg = blkg_lookup(bio_blkcg(bio), q);
> + rcu_read_unlock();
> +
> + if (WARN_ON_ONCE(!blkg))
> + return q->root_blkg;
> + return blkg;
> +}
[Severity: Critical]
How does this handle a cgroup being offlined while IO is in flight?
If an unprivileged user issues async IO and then immediately removes the
cgroup via rmdir, blkg_destroy() will remove the blkg from the radix tree.
When the bio completes, blkg_lookup() here will fail to find the child blkg
and fall back to returning q->root_blkg.
[ ... ]
> +void bio_put_blkg_ref(struct bio *bio)
> +{
> + if (bio_flagged(bio, BIO_BLKG_REF)) {
> + struct blkcg_gq *blkg = bio_pinned_blkg(bio);
> +
> + blkg_put(blkg);
> + bio_clear_flag(bio, BIO_BLKG_REF);
> + }
> +}
[Severity: Critical]
Because bio_pinned_blkg() falls back to q->root_blkg when the child blkg is
no longer in the radix tree, blkg_put() here will drop the reference on the
root blkg instead of the actually pinned child blkg. Will this leak the
child blkg and eventually cause a use-after-free panic on the root blkg
due to the reference underflow?
[ ... ]
> +struct blkcg_gq *bio_blkg(struct bio *bio)
> +{
> + struct blkcg *blkcg = bio_blkcg(bio);
> + struct gendisk *disk;
> + struct request_queue *q;
> + struct blkcg_gq *blkg;
> +
> + if (!blkcg || !bio->bi_bdev)
> + return NULL;
> +
> + if (bio_flagged(bio, BIO_BLKG_REF))
> + return bio_pinned_blkg(bio);
> +
> + disk = bio->bi_bdev->bd_disk;
> + q = disk->queue;
>
> spin_lock_irq(&q->queue_lock);
> - blkg = blkg_lookup_create(blkcg, bio->bi_bdev->bd_disk);
> - if (blkg)
> - blkg = blkg_lookup_tryget(blkg);
> + blkg = blkg_lookup_create(blkcg, disk);
> + if (blkg && blkg->blkcg == blkcg && blkg_tryget(blkg))
> + bio_set_flag(bio, BIO_BLKG_REF);
> + else
> + blkg = NULL;
> spin_unlock_irq(&q->queue_lock);
>
> return blkg;
> }
[Severity: High]
Is it intentional to return NULL when blkg_lookup_create() falls back
to an ancestor? If blkg creation fails due to ENOMEM, it correctly
returns the closest alive ancestor. But this strict blkg->blkcg == blkcg
check fails, explicitly returning NULL. Since blk-throttle unconditionally
dereferences the returned blkg (for example in __blk_throtl_bio() via
blkg_to_tg(blkg)->td), won't this cause a kernel panic under memory pressure
instead of gracefully falling back?
[ ... ]
> void blk_cgroup_bio_start(struct bio *bio)
> {
> - struct blkcg_gq *blkg = bio_blkg(bio);
> struct blkcg *blkcg = bio_blkcg(bio);
> + struct blkcg_gq *blkg;
> int rwd = blk_cgroup_io_type(bio), cpu;
> struct blkg_iostat_set *bis;
> unsigned long flags;
>
> if (!cgroup_subsys_on_dfl(io_cgrp_subsys))
> return;
> + if (!blkcg)
> + return;
>
> /* Root-level stats are sourced from system-wide IO stats */
> if (!cgroup_parent(blkcg->css.cgroup))
> return;
>
> + blkg = bio_blkg_lookup(bio);
> + if (!blkg)
> + return;
[Severity: Medium]
Can this silently drop standard IO statistics (io.stat)? Before this
patch, bio_associate_blkg() proactively created the blkg. Now, missing
blkgs are not created by default. If no other active IO policy like
throttle or BFQ processes the bio and explicitly calls bio_blkg() to
create the hierarchy, bio_blkg_lookup() returns NULL and
blk_cgroup_bio_start() aborts. Does this completely lose cgroup IO accounting
on disks without active block IO policies?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260804065313.2092022-1-yukuai@kernel.org?part=2
next prev parent reply other threads:[~2026-08-04 7:09 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 6:53 [RFC PATCH v1 0/3] blk-cgroup: store blkcg in bio before blkcg_mutex conversion Yu Kuai
2026-08-04 6:53 ` [RFC PATCH v1 1/3] blk-cgroup: add helpers for bio cgroup state Yu Kuai
2026-08-04 7:08 ` sashiko-bot
2026-08-04 10:52 ` Jan Kara
2026-08-04 13:25 ` Christoph Hellwig
2026-08-04 15:07 ` yu kuai
2026-08-04 6:53 ` [RFC PATCH v1 2/3] blk-cgroup: store blkcg in bio instead of blkg Yu Kuai
2026-08-04 7:09 ` sashiko-bot [this message]
2026-08-04 9:19 ` Tao Cui
2026-08-04 13:32 ` Christoph Hellwig
2026-08-04 15:30 ` yu kuai
2026-08-04 15:47 ` Christoph Hellwig
2026-08-05 0:58 ` Tao Cui
2026-08-06 9:22 ` Michal Koutný
2026-08-04 6:53 ` [RFC PATCH v1 3/3] blk-cgroup: move async bio punt state to blkcg Yu Kuai
2026-08-04 7:10 ` sashiko-bot
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=20260804070931.487701F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=linux-raid@vger.kernel.org \
--cc=mkoutny@suse.com \
--cc=nvdimm@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tj@kernel.org \
--cc=yukuai@fygo.io \
--cc=yukuai@kernel.org \
/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