summaryrefslogtreecommitdiff
path: root/src/cgtop
diff options
context:
space:
mode:
authorTejun Heo <htejun@fb.com>2016-08-07 09:45:39 -0400
committerTejun Heo <tj@kernel.org>2016-08-07 09:45:39 -0400
commit66ebf6c0a1005f90099e25ece5630551ad97a3c3 (patch)
treed66af9b366845249937bf6b16025552e97ff25be /src/cgtop
parentceab9e2deee29dfda213a30c533c7dcd59c6bcad (diff)
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.
Diffstat (limited to 'src/cgtop')
-rw-r--r--src/cgtop/cgtop.c50
1 files changed, 38 insertions, 12 deletions
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);
@@ -449,6 +472,9 @@ static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration)
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);
if (r < 0)
return r;