]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
blk-cgroup: protect iterating blkgs with blkcg->lock in blkcg_print_stat()
authorYu Kuai <yukuai@fygo.io>
Mon, 8 Jun 2026 03:42:42 +0000 (11:42 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 24 Jun 2026 12:37:54 +0000 (06:37 -0600)
blkcg_print_one_stat() will be called for each blkg:
- access blkg->iostat, which is freed from rcu callback
  blkg_free_workfn();
- access policy data from pd_stat_fn(), which is freed from
  pd_free_fn(), while pd_free_fn() can be called by removing blkcg or
  deactivating policy;

Take blkcg->lock while iterating so the blkgs stay online and both
blkg->iostat and policy data for activated policies stay valid.  Use
irq-safe locking because blkcg->lock can be nested under q->queue_lock,
which is used from IRQ completion paths.

Prepare to convert protecting blkgs from request_queue with mutex.

Signed-off-by: Yu Kuai <yukuai@fygo.io>
Link: https://patch.msgid.link/05799877e720dcd300e2ddd4625e8e162959d7cc.1780621988.git.yukuai@fygo.io
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-cgroup.c

index ee076ab795d33276af385f07af48194be1abed57..c991c263cb5ab9981f464fb19edc81ce21c4028e 100644 (file)
@@ -1191,13 +1191,10 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
        else
                css_rstat_flush(&blkcg->css);
 
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(blkg, &blkcg->blkg_list, blkcg_node) {
-               spin_lock_irq(&blkg->q->queue_lock);
+       guard(spinlock_irq)(&blkcg->lock);
+       hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node)
                blkcg_print_one_stat(blkg, sf);
-               spin_unlock_irq(&blkg->q->queue_lock);
-       }
-       rcu_read_unlock();
+
        return 0;
 }