Skip to content

Commit 8821f36

Browse files
pixelclusterMaarten Lankhorst
authored andcommitted
cgroup/dmem: Don't open-code css_for_each_descendant_pre
The current implementation has a bug: If the current css doesn't contain any pool that is a descendant of the "pool" (i.e. when found_descendant == false), then "pool" will point to some unrelated pool. If the current css has a child, we'll overwrite parent_pool with this unrelated pool on the next iteration. Since we can just check whether a pool refers to the same region to determine whether or not it's related, all the additional pool tracking is unnecessary, so just switch to using css_for_each_descendant_pre for traversal. Fixes: b168ed4 ("kernel/cgroup: Add "dmem" memory accounting cgroup") Signed-off-by: Friedrich Vock <friedrich.vock@gmx.de> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250127152754.21325-1-friedrich.vock@gmx.de Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
1 parent b3fefbb commit 8821f36

File tree

1 file changed

+11
-39
lines changed

1 file changed

+11
-39
lines changed

kernel/cgroup/dmem.c

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -220,60 +220,32 @@ dmem_cgroup_calculate_protection(struct dmem_cgroup_pool_state *limit_pool,
220220
struct dmem_cgroup_pool_state *test_pool)
221221
{
222222
struct page_counter *climit;
223-
struct cgroup_subsys_state *css, *next_css;
223+
struct cgroup_subsys_state *css;
224224
struct dmemcg_state *dmemcg_iter;
225-
struct dmem_cgroup_pool_state *pool, *parent_pool;
226-
bool found_descendant;
225+
struct dmem_cgroup_pool_state *pool, *found_pool;
227226

228227
climit = &limit_pool->cnt;
229228

230229
rcu_read_lock();
231-
parent_pool = pool = limit_pool;
232-
css = &limit_pool->cs->css;
233230

234-
/*
235-
* This logic is roughly equivalent to css_foreach_descendant_pre,
236-
* except we also track the parent pool to find out which pool we need
237-
* to calculate protection values for.
238-
*
239-
* We can stop the traversal once we find test_pool among the
240-
* descendants since we don't really care about any others.
241-
*/
242-
while (pool != test_pool) {
243-
next_css = css_next_child(NULL, css);
244-
if (next_css) {
245-
parent_pool = pool;
246-
} else {
247-
while (css != &limit_pool->cs->css) {
248-
next_css = css_next_child(css, css->parent);
249-
if (next_css)
250-
break;
251-
css = css->parent;
252-
parent_pool = pool_parent(parent_pool);
253-
}
254-
/*
255-
* We can only hit this when test_pool is not a
256-
* descendant of limit_pool.
257-
*/
258-
if (WARN_ON_ONCE(css == &limit_pool->cs->css))
259-
break;
260-
}
261-
css = next_css;
262-
263-
found_descendant = false;
231+
css_for_each_descendant_pre(css, &limit_pool->cs->css) {
264232
dmemcg_iter = container_of(css, struct dmemcg_state, css);
233+
found_pool = NULL;
265234

266235
list_for_each_entry_rcu(pool, &dmemcg_iter->pools, css_node) {
267-
if (pool_parent(pool) == parent_pool) {
268-
found_descendant = true;
236+
if (pool->region == limit_pool->region) {
237+
found_pool = pool;
269238
break;
270239
}
271240
}
272-
if (!found_descendant)
241+
if (!found_pool)
273242
continue;
274243

275244
page_counter_calculate_protection(
276-
climit, &pool->cnt, true);
245+
climit, &found_pool->cnt, true);
246+
247+
if (found_pool == test_pool)
248+
break;
277249
}
278250
rcu_read_unlock();
279251
}

0 commit comments

Comments
 (0)