summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNatalie Vock <natalie.vock@gmx.de>2026-08-04 10:25:17 +0200
committerNatalie Vock <nat@pixelcluster.dev>2026-08-05 10:34:42 +0200
commit34f3e259925382cd87187dd426d3918379c6144e (patch)
treea0dbd3deda4bfba08b8096a41053dcc596278644 /include
parentdd517e49a3123f868151ff1a193add8e10ae69ba (diff)
cgroup,cgroup/dmem: Add (dmem_)cgroup_common_ancestor helper
This helps to find a common subtree of two resources, which is important when determining whether it's helpful to evict one resource in favor of another. To facilitate this, add a common helper to find the ancestor of two cgroups using each cgroup's ancestor array. Tested-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com> Reviewed-by: Maarten Lankhorst <dev@lankhorst.se> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Signed-off-by: Natalie Vock <natalie.vock@gmx.de> Link: https://patch.msgid.link/20260804-dmemcg-aggressive-protect-v8-2-07af96681bf8@gmx.de
Diffstat (limited to 'include')
-rw-r--r--include/linux/cgroup.h21
-rw-r--r--include/linux/cgroup_dmem.h9
2 files changed, 30 insertions, 0 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index f2aa46a4f871..83a17ded1c51 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -624,6 +624,27 @@ static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp,
}
/**
+ * cgroup_common_ancestor - find common ancestor of two cgroups
+ * @a: first cgroup to find common ancestor of
+ * @b: second cgroup to find common ancestor of
+ *
+ * Find the first cgroup that is an ancestor of both @a and @b, if it exists
+ * and return a pointer to it. If such a cgroup doesn't exist, return NULL.
+ *
+ * This function is safe to call as long as both @a and @b are accessible.
+ */
+static inline struct cgroup *cgroup_common_ancestor(struct cgroup *a,
+ struct cgroup *b)
+{
+ int level;
+
+ for (level = min(a->level, b->level); level >= 0; level--)
+ if (a->ancestors[level] == b->ancestors[level])
+ return a->ancestors[level];
+ return NULL;
+}
+
+/**
* task_under_cgroup_hierarchy - test task's membership of cgroup ancestry
* @task: the task to be tested
* @ancestor: possible ancestor of @task's cgroup
diff --git a/include/linux/cgroup_dmem.h b/include/linux/cgroup_dmem.h
index 1a88cd0c9eb0..9d72457c4cb9 100644
--- a/include/linux/cgroup_dmem.h
+++ b/include/linux/cgroup_dmem.h
@@ -28,6 +28,8 @@ bool dmem_cgroup_below_min(struct dmem_cgroup_pool_state *root,
struct dmem_cgroup_pool_state *test);
bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root,
struct dmem_cgroup_pool_state *test);
+struct dmem_cgroup_pool_state *dmem_cgroup_get_common_ancestor(struct dmem_cgroup_pool_state *a,
+ struct dmem_cgroup_pool_state *b);
void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool);
#else
@@ -75,6 +77,13 @@ static inline bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root,
return false;
}
+static inline
+struct dmem_cgroup_pool_state *dmem_cgroup_get_common_ancestor(struct dmem_cgroup_pool_state *a,
+ struct dmem_cgroup_pool_state *b)
+{
+ return NULL;
+}
+
static inline void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool)
{ }