[PATCH 03/11] cgroup: add memory_cma_accounting mount option
Eric Chanudet <[email protected]>
| Newsgroups | org.kernel.vger.linux-kselftest,org.kernel.vger.cgroups,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
Add a cgroup v2 mount option that will be used later in this series to enable CMA memory accounting under memcg. The option is made opt-in as it will charge allocations to the cgroup's overall memory usage, which changes existing expectations. Signed-off-by: Eric Chanudet <[email protected]> --- Documentation/admin-guide/cgroup-v2.rst | 20 ++++++++++++++++++++ include/linux/cgroup-defs.h | 5 +++++ kernel/cgroup/cgroup.c | 15 ++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index aed195a71cbf..3dfc13f31a0c 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -246,6 +246,26 @@ cgroup v2 currently supports the following mount options. will not be tracked by the memory controller (even if cgroup v2 is remounted later on). + memory_cma_accounting + Count CMA memory usage towards the cgroup's overall memory usage for + the memory controller, and expose per-CMA-area usage counters. This + behavior is opt-in, so as to not cause regression on existing setups. + + A few caveats to keep in mind: + + * CMA areas are reserved at boot time, memory is only charged to a + cgroup when a CMA allocation is performed on its behalf. + * CMA pages allocated while this option is not enabled will not be + tracked by the memory controller, even if cgroup v2 is remounted + later on with this option. Charges happen at allocation. + * CMA allocations are charged both to the cgroup's memory counter + (limited by memory.max) and the per-area CMA counter (limited by + memory.cma.<area>.max). Hitting either limit can cause an allocation + to fail. If CMA usage pushes the cgroup over memory.high or + memory.max, the memory controller will attempt to reclaim other + memory only. CMA memory charged to the cgroup is not reclaimable. + Limits should be sized to accommodate the expected CMA pressure. + pids_localevents The option restores v1-like behavior of pids.events:max, that is only local (inside cgroup proper) fork failures are counted. Without this diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index de2cd6238c2a..15f3f7110c5b 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -129,6 +129,11 @@ enum { * Enable legacy local pids.events. */ CGRP_ROOT_PIDS_LOCAL_EVENTS = (1 << 20), + + /* + * Enable cma accounting for the memory controller. + */ + CGRP_ROOT_MEMORY_CMA_ACCOUNTING = (1 << 21), }; /* cftype->flags */ diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index b5b461d4418b..12184f85ad10 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1985,6 +1985,7 @@ enum cgroup2_param { Opt_memory_recursiveprot, Opt_memory_hugetlb_accounting, Opt_pids_localevents, + Opt_memory_cma_accounting, nr__cgroup2_params }; @@ -1995,6 +1996,7 @@ static const struct fs_parameter_spec cgroup2_fs_parameters[] = { fsparam_flag("memory_recursiveprot", Opt_memory_recursiveprot), fsparam_flag("memory_hugetlb_accounting", Opt_memory_hugetlb_accounting), fsparam_flag("pids_localevents", Opt_pids_localevents), + fsparam_flag("memory_cma_accounting", Opt_memory_cma_accounting), {} }; @@ -2027,6 +2029,9 @@ static int cgroup2_parse_param(struct fs_context *fc, struct fs_parameter *param case Opt_pids_localevents: ctx->flags |= CGRP_ROOT_PIDS_LOCAL_EVENTS; return 0; + case Opt_memory_cma_accounting: + ctx->flags |= CGRP_ROOT_MEMORY_CMA_ACCOUNTING; + return 0; } return -EINVAL; } @@ -2068,6 +2073,11 @@ static void apply_cgroup_root_flags(unsigned int root_flags) cgrp_dfl_root.flags |= CGRP_ROOT_PIDS_LOCAL_EVENTS; else cgrp_dfl_root.flags &= ~CGRP_ROOT_PIDS_LOCAL_EVENTS; + + if (root_flags & CGRP_ROOT_MEMORY_CMA_ACCOUNTING) + cgrp_dfl_root.flags |= CGRP_ROOT_MEMORY_CMA_ACCOUNTING; + else + cgrp_dfl_root.flags &= ~CGRP_ROOT_MEMORY_CMA_ACCOUNTING; } } @@ -2085,6 +2095,8 @@ static int cgroup_show_options(struct seq_file *seq, struct kernfs_root *kf_root seq_puts(seq, ",memory_hugetlb_accounting"); if (cgrp_dfl_root.flags & CGRP_ROOT_PIDS_LOCAL_EVENTS) seq_puts(seq, ",pids_localevents"); + if (cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_CMA_ACCOUNTING) + seq_puts(seq, ",memory_cma_accounting"); return 0; } @@ -7520,7 +7532,8 @@ static ssize_t features_show(struct kobject *kobj, struct kobj_attribute *attr, "memory_localevents\n" "memory_recursiveprot\n" "memory_hugetlb_accounting\n" - "pids_localevents\n"); + "pids_localevents\n" + "memory_cma_accounting\n"); } static struct kobj_attribute cgroup_features_attr = __ATTR_RO(features); -- 2.53.0