summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2026-05-05 03:51:19 +0300
committerTejun Heo <tj@kernel.org>2026-05-15 20:24:26 +0300
commitc4799253a3ee74ebb27be72fb991c597a5902c01 (patch)
tree376bcbcc4292494708b8e5c03cea2cf8559ec810 /include/linux
parent44fabf05634ce9e90b3fb179ea962995b7bbaa09 (diff)
downloadlinux-c4799253a3ee74ebb27be72fb991c597a5902c01.tar.xz
cgroup: Move populated counters to cgroup_subsys_state
Later patches replace the cgroup-level finish_destroy_work deferral added by 93618edf7538 ("cgroup: Defer css percpu_ref kill on rmdir until cgroup is depopulated") with a per-subsys-css deferral. That needs each subsystem css to track its own populated count. Move the populated counters from cgroup onto cgroup_subsys_state. cgroup->self is itself a cgroup_subsys_state and self.parent walks the same chain as cgroup_parent(), so cgroup_update_populated() generalizes to a single css_update_populated() taking a css. The cgroup-side bookkeeping runs only when the walk started from a self css. Keep nr_populated_{domain,threaded}_children on cgroup. Both sum to self.nr_populated_children, but staying as dedicated fields to allow readers like cgroup_can_be_thread_root() unlocked access. css_set_update_populated() also walks the per-subsys-css chain so each subsystem css's hierarchical populated count is maintained. No reader consumes those counts yet. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/cgroup-defs.h24
-rw-r--r--include/linux/cgroup.h11
2 files changed, 21 insertions, 14 deletions
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index 50a784da7a81..c4929f7bbe5a 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -254,6 +254,15 @@ struct cgroup_subsys_state {
int nr_descendants;
/*
+ * Hierarchical populated state. For cgroup->self, nr_populated_csets
+ * counts populated csets linked via cgrp_cset_link.
+ * nr_populated_children counts immediate-child csses whose own
+ * populated state is nonzero. Protected by css_set_lock.
+ */
+ int nr_populated_csets;
+ int nr_populated_children;
+
+ /*
* A singly-linked list of css structures to be rstat flushed.
* This is a scratch field to be used exclusively by
* css_rstat_flush().
@@ -504,17 +513,12 @@ struct cgroup {
int max_descendants;
/*
- * Each non-empty css_set associated with this cgroup contributes
- * one to nr_populated_csets. The counter is zero iff this cgroup
- * doesn't have any tasks.
- *
- * All children which have non-zero nr_populated_csets and/or
- * nr_populated_children of their own contribute one to either
- * nr_populated_domain_children or nr_populated_threaded_children
- * depending on their type. Each counter is zero iff all cgroups
- * of the type in the subtree proper don't have any tasks.
+ * Domain/threaded split of self.nr_populated_children: each counts
+ * immediate-child cgroups whose subtree is populated and sums to
+ * self.nr_populated_children. Kept as separate fields to allow readers
+ * like cgroup_can_be_thread_root() unlocked access. Protected by
+ * css_set_lock; updated by css_update_populated().
*/
- int nr_populated_csets;
int nr_populated_domain_children;
int nr_populated_threaded_children;
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 9f8bef8f3a60..c2a8c38d8206 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -654,14 +654,17 @@ static inline bool task_under_cgroup_hierarchy(struct task_struct *task,
*/
static inline bool cgroup_has_tasks(struct cgroup *cgrp)
{
- return READ_ONCE(cgrp->nr_populated_csets);
+ return READ_ONCE(cgrp->self.nr_populated_csets);
+}
+
+static inline bool css_is_populated(struct cgroup_subsys_state *css)
+{
+ return READ_ONCE(css->nr_populated_csets) || READ_ONCE(css->nr_populated_children);
}
static inline bool cgroup_is_populated(struct cgroup *cgrp)
{
- return READ_ONCE(cgrp->nr_populated_csets) +
- READ_ONCE(cgrp->nr_populated_domain_children) +
- READ_ONCE(cgrp->nr_populated_threaded_children);
+ return css_is_populated(&cgrp->self);
}
/* returns ino associated with a cgroup */