]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mm/page_io: don't nest queue_lock under rcu in bio_associate_blkg_from_page()
authorYu Kuai <yukuai@fygo.io>
Mon, 8 Jun 2026 03:42:48 +0000 (11:42 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 24 Jun 2026 12:42:31 +0000 (06:42 -0600)
Take a css reference under RCU, drop RCU, and then associate the bio with
the blkg. This avoids nesting queue_lock under RCU and prepares to protect
blkcg with blkcg_mutex instead of queue_lock.

Use css_tryget() instead of css_tryget_online() so swap writeback for
pages charged to a dying memcg still passes the dying css to
bio_associate_blkg_from_css(). That preserves the existing closest-live
ancestor fallback instead of charging those bios to the root blkg.

Signed-off-by: Yu Kuai <yukuai@fygo.io>
Link: https://patch.msgid.link/c910d2c39d3ec97f67de68af636a52394342d55f.1780621988.git.yukuai@fygo.io
Signed-off-by: Jens Axboe <axboe@kernel.dk>
mm/page_io.c

index a59b73f8bdd9d1eb0730752d3261f2a122b1a52c..c96d3e4cf872d3de291ff81ca50f6867536efcaf 100644 (file)
@@ -317,8 +317,13 @@ static void bio_associate_blkg_from_page(struct bio *bio, struct folio *folio)
        rcu_read_lock();
        memcg = folio_memcg(folio);
        css = cgroup_e_css(memcg->css.cgroup, &io_cgrp_subsys);
-       bio_associate_blkg_from_css(bio, css);
+       if (!css || !css_tryget(css))
+               css = NULL;
        rcu_read_unlock();
+
+       bio_associate_blkg_from_css(bio, css);
+       if (css)
+               css_put(css);
 }
 #else
 #define bio_associate_blkg_from_page(bio, folio)               do { } while (0)