Expose memory.cma..{current,max} files under each non-root cgroup when cgroupfs memory_cma_accounting option is enabled. memory.cma..current reports the cgroup's CMA usage for that area. memory.cma..max is a read-write limit (default: max). Each CMA area gets a cftype template with its name set from the CMA area's name. Signed-off-by: Eric Chanudet --- Documentation/admin-guide/cgroup-v2.rst | 15 ++++++ mm/memcontrol.c | 89 +++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 3dfc13f31a0c..39871a7a08a8 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1928,6 +1928,21 @@ The following nested keys are defined. This setting has no effect if zswap is disabled, and swapping is allowed unless memory.swap.max is set to 0. + memory.cma..current + A read-only single value file which exists on non-root cgroups. + is the CMA area name (e.g. "reserved" for the default DMA CMA area). + + The total amount of CMA memory currently charged to the cgroup for the + given CMA area. Only accounted when memory_cma_accounting is enabled. + + memory.cma..max + A read-write single value file which exists on non-root cgroups. The + default is "max". + + CMA usage hard limit for the given area. If a cgroup's CMA usage for + this area exceeds this limit, the allocation will fail. Only enforced + when memory_cma_accounting is enabled. + memory.pressure A read-only nested-keyed file. diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 8eca00d30fc5..f28d610a59ce 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -6182,3 +6182,92 @@ void mem_cgroup_show_protected_memory(struct mem_cgroup *memcg) K(atomic_long_read(&memcg->memory.children_min_usage)), K(atomic_long_read(&memcg->memory.children_low_usage))); } + +#ifdef CONFIG_CMA +static int memory_cma_current_show(struct seq_file *m, void *v) +{ + struct mem_cgroup *memcg = mem_cgroup_from_seq(m); + int idx = seq_cft(m)->private; + unsigned long cur = page_counter_read(&memcg->cma_counters[idx]); + + seq_printf(m, "%lu\n", cur * PAGE_SIZE); + + return 0; +} + +static int memory_cma_max_show(struct seq_file *m, void *v) +{ + struct mem_cgroup *memcg = mem_cgroup_from_seq(m); + int idx = seq_cft(m)->private; + unsigned long max = READ_ONCE(memcg->cma_counters[idx].max); + + return seq_puts_memcg_tunable(m, max); +} + +static ssize_t memory_cma_max_write(struct kernfs_open_file *of, char *buf, + size_t nbytes, loff_t off) +{ + struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of)); + int idx = of_cft(of)->private; + unsigned long max; + int rc; + + buf = strstrip(buf); + rc = page_counter_memparse(buf, "max", &max); + if (rc) + return rc; + + xchg(&memcg->cma_counters[idx].max, max); + + return nbytes; +} + +static struct cftype cma_dfl_tmpl[] = { + { + .name = "current", + .seq_show = memory_cma_current_show, + .flags = CFTYPE_NOT_ON_ROOT, + }, + { + .name = "max", + .seq_show = memory_cma_max_show, + .write = memory_cma_max_write, + .flags = CFTYPE_NOT_ON_ROOT, + }, + { } +}; +#define CMA_DFL_TMPL_SIZE (ARRAY_SIZE(cma_dfl_tmpl) - 1) + +static struct cftype *cma_dfl_files; + +static int __init mem_cgroup_cma_init(void) +{ + struct cftype *cft; + unsigned int i, j; + int count; + + if (mem_cgroup_disabled() || !cma_area_count) + return 0; + + count = cma_area_count * CMA_DFL_TMPL_SIZE; + cma_dfl_files = kcalloc(count + 1, sizeof(*cma_dfl_tmpl), GFP_KERNEL); + if (!cma_dfl_files) + return -ENOMEM; + + for (i = 0; i < cma_area_count; ++i) + for (j = 0; j < CMA_DFL_TMPL_SIZE; ++j) { + cft = &cma_dfl_files[i * CMA_DFL_TMPL_SIZE + j]; + *cft = cma_dfl_tmpl[j]; + snprintf(cft->name, MAX_CFTYPE_NAME, "cma.%s.%s", + cma_get_name(&cma_areas[i]), + cma_dfl_tmpl[j].name); + cft->private = i; /* cma area index for counters in callbacks. */ + lockdep_register_key(&cft->lockdep_key); + } + + WARN_ON(cgroup_add_dfl_cftypes(&memory_cgrp_subsys, cma_dfl_files)); + + return 0; +} +subsys_initcall(mem_cgroup_cma_init); +#endif /* CONFIG_CMA */ -- 2.53.0