From 66ebf6c0a1005f90099e25ece5630551ad97a3c3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 7 Aug 2016 09:45:39 -0400 Subject: core: add cgroup CPU controller support on the unified hierarchy Unfortunately, due to the disagreements in the kernel development community, CPU controller cgroup v2 support has not been merged and enabling it requires applying two small out-of-tree kernel patches. The situation is explained in the following documentation. https://git.kernel.org/cgit/linux/kernel/git/tj/cgroup.git/tree/Documentation/cgroup-v2-cpu.txt?h=cgroup-v2-cpu While it isn't clear what will happen with CPU controller cgroup v2 support, there are critical features which are possible only on cgroup v2 such as buffered write control making cgroup v2 essential for a lot of workloads. This commit implements systemd CPU controller support on the unified hierarchy so that users who choose to deploy CPU controller cgroup v2 support can easily take advantage of it. On the unified hierarchy, "cpu.weight" knob replaces "cpu.shares" and "cpu.max" replaces "cpu.cfs_period_us" and "cpu.cfs_quota_us". [Startup]CPUWeight config options are added with the usual compat translation. CPU quota settings remain unchanged and apply to both legacy and unified hierarchies. v2: - Error in man page corrected. - CPU config application in cgroup_context_apply() refactored. - CPU accounting now works on unified hierarchy. --- src/cgtop/cgtop.c | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'src/cgtop') diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index c67b328b38..6045ae0437 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -208,24 +208,47 @@ static int process( if (g->n_tasks > 0) g->n_tasks_valid = true; - } else if (streq(controller, "cpuacct") && cg_unified() <= 0) { + } else if (streq(controller, "cpu") || streq(controller, "cpuacct")) { _cleanup_free_ char *p = NULL, *v = NULL; uint64_t new_usage; nsec_t timestamp; - r = cg_get_path(controller, path, "cpuacct.usage", &p); - if (r < 0) - return r; + if (cg_unified() > 0) { + const char *keys[] = { "usage_usec", NULL }; + _cleanup_free_ char *val = NULL; - r = read_one_line_file(p, &v); - if (r == -ENOENT) - return 0; - if (r < 0) - return r; + if (!streq(controller, "cpu")) + return 0; - r = safe_atou64(v, &new_usage); - if (r < 0) - return r; + r = cg_get_keyed_attribute("cpu", path, "cpu.stat", keys, &val); + if (r == -ENOENT) + return 0; + if (r < 0) + return r; + + r = safe_atou64(val, &new_usage); + if (r < 0) + return r; + + new_usage *= NSEC_PER_USEC; + } else { + if (!streq(controller, "cpuacct")) + return 0; + + r = cg_get_path(controller, path, "cpuacct.usage", &p); + if (r < 0) + return r; + + r = read_one_line_file(p, &v); + if (r == -ENOENT) + return 0; + if (r < 0) + return r; + + r = safe_atou64(v, &new_usage); + if (r < 0) + return r; + } timestamp = now_nsec(CLOCK_MONOTONIC); @@ -447,6 +470,9 @@ static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration) assert(a); r = refresh_one(SYSTEMD_CGROUP_CONTROLLER, root, a, b, iteration, 0, NULL); + if (r < 0) + return r; + r = refresh_one("cpu", root, a, b, iteration, 0, NULL); if (r < 0) return r; r = refresh_one("cpuacct", root, a, b, iteration, 0, NULL); -- cgit v1.2.3-54-g00ecf