Skip to content

Commit bef8620

Browse files
rgushchintorvalds
authored andcommitted
mm: memcg: deprecate the non-hierarchical mode
Patch series "mm: memcg: deprecate cgroup v1 non-hierarchical mode", v1. The non-hierarchical cgroup v1 mode is a legacy of early days of the memory controller and doesn't bring any value today. However, it complicates the code and creates many edge cases all over the memory controller code. It's a good time to deprecate it completely. This patchset removes the internal logic, adjusts the user interface and updates the documentation. The alt patch removes some bits of the cgroup core code, which become obsolete. Michal Hocko said: "All that we know today is that we have a warning in place to complain loudly when somebody relies on use_hierarchy=0 with a deeper hierarchy. For all those years we have seen _zero_ reports that would describe a sensible usecase. Moreover we (SUSE) have backported this warning into old distribution kernels (since 3.0 based kernels) to extend the coverage and didn't hear even for users who adopt new kernels only very slowly. The only report we have seen so far was a LTP test suite which doesn't really reflect any real life usecase" This patch (of 3): The non-hierarchical cgroup v1 mode is a legacy of early days of the memory controller and doesn't bring any value today. However, it complicates the code and creates many edge cases all over the memory controller code. It's a good time to deprecate it completely. Functionally this patch enabled is by default for all cgroups and forbids switching it off. Nothing changes if cgroup v2 is used: hierarchical mode was enforced from scratch. To protect the ABI memory.use_hierarchy interface is preserved with a limited functionality: reading always returns "1", writing of "1" passes silently, writing of any other value fails with -EINVAL and a warning to dmesg (on the first occasion). Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Roman Gushchin <[email protected]> Acked-by: Michal Hocko <[email protected]> Reviewed-by: Shakeel Butt <[email protected]> Acked-by: David Rientjes <[email protected]> Acked-by: Johannes Weiner <[email protected]> Cc: Tejun Heo <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent a7cb874 commit bef8620

File tree

3 files changed

+13
-89
lines changed

3 files changed

+13
-89
lines changed

include/linux/memcontrol.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,6 @@ struct mem_cgroup {
234234
/* vmpressure notifications */
235235
struct vmpressure vmpressure;
236236

237-
/*
238-
* Should the accounting and control be hierarchical, per subtree?
239-
*/
240-
bool use_hierarchy;
241-
242237
/*
243238
* Should the OOM killer kill all belonging tasks, had it kill one?
244239
*/
@@ -588,8 +583,6 @@ static inline bool mem_cgroup_is_descendant(struct mem_cgroup *memcg,
588583
{
589584
if (root == memcg)
590585
return true;
591-
if (!root->use_hierarchy)
592-
return false;
593586
return cgroup_is_descendant(memcg->css.cgroup, root->css.cgroup);
594587
}
595588

kernel/cgroup/cgroup.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,6 @@ bool cgroup_ssid_enabled(int ssid)
281281
* - cpuset: a task can be moved into an empty cpuset, and again it takes
282282
* masks of ancestors.
283283
*
284-
* - memcg: use_hierarchy is on by default and the cgroup file for the flag
285-
* is not created.
286-
*
287284
* - blkcg: blk-throttle becomes properly hierarchical.
288285
*
289286
* - debug: disallowed on the default hierarchy.
@@ -5156,8 +5153,6 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
51565153
cgroup_parent(parent)) {
51575154
pr_warn("%s (%d) created nested cgroup for controller \"%s\" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.\n",
51585155
current->comm, current->pid, ss->name);
5159-
if (!strcmp(ss->name, "memory"))
5160-
pr_warn("\"memory\" requires setting use_hierarchy to 1 on the root\n");
51615156
ss->warned_broken_hierarchy = true;
51625157
}
51635158

mm/memcontrol.c

Lines changed: 13 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,12 +1141,6 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
11411141
if (prev && !reclaim)
11421142
pos = prev;
11431143

1144-
if (!root->use_hierarchy && root != root_mem_cgroup) {
1145-
if (prev)
1146-
goto out;
1147-
return root;
1148-
}
1149-
11501144
rcu_read_lock();
11511145

11521146
if (reclaim) {
@@ -1226,7 +1220,6 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
12261220

12271221
out_unlock:
12281222
rcu_read_unlock();
1229-
out:
12301223
if (prev && prev != root)
12311224
css_put(&prev->css);
12321225

@@ -3461,10 +3454,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
34613454
}
34623455

34633456
/*
3464-
* Test whether @memcg has children, dead or alive. Note that this
3465-
* function doesn't care whether @memcg has use_hierarchy enabled and
3466-
* returns %true if there are child csses according to the cgroup
3467-
* hierarchy. Testing use_hierarchy is the caller's responsibility.
3457+
* Test whether @memcg has children, dead or alive.
34683458
*/
34693459
static inline bool memcg_has_children(struct mem_cgroup *memcg)
34703460
{
@@ -3524,37 +3514,20 @@ static ssize_t mem_cgroup_force_empty_write(struct kernfs_open_file *of,
35243514
static u64 mem_cgroup_hierarchy_read(struct cgroup_subsys_state *css,
35253515
struct cftype *cft)
35263516
{
3527-
return mem_cgroup_from_css(css)->use_hierarchy;
3517+
return 1;
35283518
}
35293519

35303520
static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css,
35313521
struct cftype *cft, u64 val)
35323522
{
3533-
int retval = 0;
3534-
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
3535-
struct mem_cgroup *parent_memcg = mem_cgroup_from_css(memcg->css.parent);
3536-
3537-
if (memcg->use_hierarchy == val)
3523+
if (val == 1)
35383524
return 0;
35393525

3540-
/*
3541-
* If parent's use_hierarchy is set, we can't make any modifications
3542-
* in the child subtrees. If it is unset, then the change can
3543-
* occur, provided the current cgroup has no children.
3544-
*
3545-
* For the root cgroup, parent_mem is NULL, we allow value to be
3546-
* set if there are no children.
3547-
*/
3548-
if ((!parent_memcg || !parent_memcg->use_hierarchy) &&
3549-
(val == 1 || val == 0)) {
3550-
if (!memcg_has_children(memcg))
3551-
memcg->use_hierarchy = val;
3552-
else
3553-
retval = -EBUSY;
3554-
} else
3555-
retval = -EINVAL;
3526+
pr_warn_once("Non-hierarchical mode is deprecated. "
3527+
"Please report your usecase to [email protected] if you "
3528+
"depend on this functionality.\n");
35563529

3557-
return retval;
3530+
return -EINVAL;
35583531
}
35593532

35603533
static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
@@ -3742,8 +3715,6 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
37423715
child = mem_cgroup_from_css(css);
37433716
BUG_ON(child->kmemcg_id != kmemcg_id);
37443717
child->kmemcg_id = parent->kmemcg_id;
3745-
if (!memcg->use_hierarchy)
3746-
break;
37473718
}
37483719
rcu_read_unlock();
37493720

@@ -5334,38 +5305,22 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
53345305
if (parent) {
53355306
memcg->swappiness = mem_cgroup_swappiness(parent);
53365307
memcg->oom_kill_disable = parent->oom_kill_disable;
5337-
}
5338-
if (!parent) {
5339-
page_counter_init(&memcg->memory, NULL);
5340-
page_counter_init(&memcg->swap, NULL);
5341-
page_counter_init(&memcg->kmem, NULL);
5342-
page_counter_init(&memcg->tcpmem, NULL);
5343-
} else if (parent->use_hierarchy) {
5344-
memcg->use_hierarchy = true;
5308+
53455309
page_counter_init(&memcg->memory, &parent->memory);
53465310
page_counter_init(&memcg->swap, &parent->swap);
53475311
page_counter_init(&memcg->kmem, &parent->kmem);
53485312
page_counter_init(&memcg->tcpmem, &parent->tcpmem);
53495313
} else {
5350-
page_counter_init(&memcg->memory, &root_mem_cgroup->memory);
5351-
page_counter_init(&memcg->swap, &root_mem_cgroup->swap);
5352-
page_counter_init(&memcg->kmem, &root_mem_cgroup->kmem);
5353-
page_counter_init(&memcg->tcpmem, &root_mem_cgroup->tcpmem);
5354-
/*
5355-
* Deeper hierachy with use_hierarchy == false doesn't make
5356-
* much sense so let cgroup subsystem know about this
5357-
* unfortunate state in our controller.
5358-
*/
5359-
if (parent != root_mem_cgroup)
5360-
memory_cgrp_subsys.broken_hierarchy = true;
5361-
}
5314+
page_counter_init(&memcg->memory, NULL);
5315+
page_counter_init(&memcg->swap, NULL);
5316+
page_counter_init(&memcg->kmem, NULL);
5317+
page_counter_init(&memcg->tcpmem, NULL);
53625318

5363-
/* The following stuff does not apply to the root */
5364-
if (!parent) {
53655319
root_mem_cgroup = memcg;
53665320
return &memcg->css;
53675321
}
53685322

5323+
/* The following stuff does not apply to the root */
53695324
error = memcg_online_kmem(memcg);
53705325
if (error)
53715326
goto fail;
@@ -6202,24 +6157,6 @@ static void mem_cgroup_move_task(void)
62026157
}
62036158
#endif
62046159

6205-
/*
6206-
* Cgroup retains root cgroups across [un]mount cycles making it necessary
6207-
* to verify whether we're attached to the default hierarchy on each mount
6208-
* attempt.
6209-
*/
6210-
static void mem_cgroup_bind(struct cgroup_subsys_state *root_css)
6211-
{
6212-
/*
6213-
* use_hierarchy is forced on the default hierarchy. cgroup core
6214-
* guarantees that @root doesn't have any children, so turning it
6215-
* on for the root memcg is enough.
6216-
*/
6217-
if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
6218-
root_mem_cgroup->use_hierarchy = true;
6219-
else
6220-
root_mem_cgroup->use_hierarchy = false;
6221-
}
6222-
62236160
static int seq_puts_memcg_tunable(struct seq_file *m, unsigned long value)
62246161
{
62256162
if (value == PAGE_COUNTER_MAX)
@@ -6557,7 +6494,6 @@ struct cgroup_subsys memory_cgrp_subsys = {
65576494
.can_attach = mem_cgroup_can_attach,
65586495
.cancel_attach = mem_cgroup_cancel_attach,
65596496
.post_attach = mem_cgroup_move_task,
6560-
.bind = mem_cgroup_bind,
65616497
.dfl_cftypes = memory_files,
65626498
.legacy_cftypes = mem_cgroup_legacy_files,
65636499
.early_init = 0,

0 commit comments

Comments
 (0)