[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250722014030.297537-4-inwardvessel@gmail.com>
Date: Mon, 21 Jul 2025 18:40:28 -0700
From: JP Kobryn <inwardvessel@...il.com>
To: tj@...nel.org,
shakeel.butt@...ux.dev,
mkoutny@...e.com,
yosryahmed@...gle.com,
hannes@...xchg.org,
akpm@...ux-foundation.org
Cc: linux-kernel@...r.kernel.org,
cgroups@...r.kernel.org,
kernel-team@...a.com
Subject: [PATCH 3/5 cgroup/for-6.16-fixes] cgroup: split init_and_link_css()
Just as its name implies, init_and_link_css() has two responsibilities.
One is defining default values for some of the given css's fields. The
other is defining the cgroup, parent, and subsystem relationships (linking)
while incrementing the newly associated cgroup refcounts (including
parent). Once the refcounts are changed, cleanup of the css has to be
performed asynchronously in a series of workqueue functions.
The cleanup constraint impacts the error handling of the the css_create()
function. Code that follows init_and_link_css() must jump to the async
cleanup path in the case of an error. This leaves the call to
css_rstat_init() in a bad position. If it fails or if any other function
between it and init_and_link_css() fails, the async cleanup sequence will
ultimately reach a call to css_rstat_exit() on an uninitialized css.
Split init_and_link_css() into separate functions for each of its two
responsibilies. This allows for handling errors without having to resort to
the async cleanup sequence. More specifically, css_rstat_init() could be
called before async cleanup becomes necessary within css_create(). This
patch serves as preparation for the change in where css_rstat_init() will
be called.
Signed-off-by: JP Kobryn <inwardvessel@...il.com>
---
kernel/cgroup/cgroup.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index b034f47580f6..1990c6113c7f 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -5568,21 +5568,25 @@ static void css_release(struct percpu_ref *ref)
queue_work(cgroup_destroy_wq, &css->destroy_work);
}
-static void init_and_link_css(struct cgroup_subsys_state *css,
+static void init_css(struct cgroup_subsys_state *css)
+{
+ memset(css, 0, sizeof(*css));
+ css->id = -1;
+ INIT_LIST_HEAD(&css->sibling);
+ INIT_LIST_HEAD(&css->children);
+ css->serial_nr = css_serial_nr_next++;
+ atomic_set(&css->online_cnt, 0);
+}
+
+static void link_css(struct cgroup_subsys_state *css,
struct cgroup_subsys *ss, struct cgroup *cgrp)
{
lockdep_assert_held(&cgroup_mutex);
cgroup_get_live(cgrp);
- memset(css, 0, sizeof(*css));
css->cgroup = cgrp;
css->ss = ss;
- css->id = -1;
- INIT_LIST_HEAD(&css->sibling);
- INIT_LIST_HEAD(&css->children);
- css->serial_nr = css_serial_nr_next++;
- atomic_set(&css->online_cnt, 0);
if (cgroup_parent(cgrp)) {
css->parent = cgroup_css(cgroup_parent(cgrp), ss);
@@ -5670,7 +5674,8 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
if (IS_ERR(css))
return css;
- init_and_link_css(css, ss, cgrp);
+ init_css(css);
+ link_css(css, ss, cgrp);
err = percpu_ref_init(&css->refcnt, css_release, 0, GFP_KERNEL);
if (err)
@@ -6130,7 +6135,8 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
css = ss->css_alloc(NULL);
/* We don't handle early failures gracefully */
BUG_ON(IS_ERR(css));
- init_and_link_css(css, ss, &cgrp_dfl_root.cgrp);
+ init_css(css);
+ link_css(css, ss, &cgrp_dfl_root.cgrp);
/*
* Root csses are never destroyed and we can't initialize
--
2.47.1
Powered by blists - more mailing lists