From 0e1daaf9b20df2125452846f768a68d8ea280adf Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 28 Oct 2026 10:41:04 -0600 Subject: [PATCH] blk-cgroup: keep the old blkg while reassociating a bio bio_associate_blkg_from_css() drops the bio's old blkg before it looks up the new one through the css. The css is pinned by the blkg, not by the bio, so if the cgroup is gone the bio may hold the last reference and the blkcg can be freed under blkg_tryget_closest(). The rcu_read_lock() around the whole thing used to cover that, until commit 457d3c4f0fdd dropped it. Put the old blkg after the new one has been looked up. Fixes: 457d3c4f0fdd ("blk-cgroup: don't nest queue_lock under rcu in bio_associate_blkg()") Cc: Tejun Heo Signed-off-by: Josef Bacik Acked-by: Tejun Heo Link: https://patch.msgid.link/20261028164415.1262013-2-axboe@kernel.dk Signed-off-by: Jens Axboe --- block/blk-cgroup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 82b66147d778..e79177ac2dc2 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -2139,8 +2139,7 @@ static inline struct blkcg_gq *blkg_tryget_closest(struct bio *bio, void bio_associate_blkg_from_css(struct bio *bio, struct cgroup_subsys_state *css) { - if (bio->bi_blkg) - blkg_put(bio->bi_blkg); + struct blkcg_gq *old_blkg = bio->bi_blkg; if (css && css->parent) { bio->bi_blkg = blkg_tryget_closest(bio, css); @@ -2148,6 +2147,10 @@ void bio_associate_blkg_from_css(struct bio *bio, blkg_get(bdev_get_queue(bio->bi_bdev)->root_blkg); bio->bi_blkg = bdev_get_queue(bio->bi_bdev)->root_blkg; } + + /* @old_blkg may be the only thing which pins @css */ + if (old_blkg) + blkg_put(old_blkg); } EXPORT_SYMBOL_GPL(bio_associate_blkg_from_css);