[PATCH] loop: fix memcg css leak on read-only I/O path
Genjian <[email protected]> Mon, 10 Aug 2026 21:49:05 +0800
| Newsgroups | org.kernel.vger.linux-block,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Genjian Zhang <[email protected]> loop_queue_rq() takes a reference on the effective memcg css via cgroup_get_e_css() and stores it in cmd->memcg_css. loop_handle_cmd() is supposed to drop that reference after use, but the early exit for writes to a read-only loop device jumps past css_put(). When testing on cgroup v2, stack a dm-linear device on a read-only loop and issue writes to it from a child cgroup, then remove that cgroup: nr_dying_subsys_memory in cgroup.stat increases and never goes back down until reboot. The same test no longer shows the leak with this patch. Fix by moving css_put() onto the shared exit path so the read-only failure case drops the reference as well. Fixes: c74d40e8b5e2 ("loop: charge i/o to mem and blk cg") Signed-off-by: Genjian Zhang <[email protected]> --- drivers/block/loop.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 1faecef33009..66eaf912c013 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1895,7 +1895,7 @@ static void loop_handle_cmd(struct loop_cmd *cmd) if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) { ret = -EIO; - goto failed; + goto out; } /* We can block in this context, so ignore REQ_NOWAIT. */ @@ -1919,11 +1919,12 @@ static void loop_handle_cmd(struct loop_cmd *cmd) if (cmd_blkcg_css) kthread_associate_blkcg(NULL); - if (cmd_memcg_css) { + if (cmd_memcg_css) set_active_memcg(old_memcg); +out: + if (cmd_memcg_css) css_put(cmd_memcg_css); - } - failed: + /* complete non-aio request */ if (ret != -EIOCBQUEUED) { if (ret == -EOPNOTSUPP) -- 2.25.1