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